1
0
mirror of https://github.com/systemd/systemd synced 2025-09-22 05:14:44 +02:00

Compare commits

...

42 Commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek
a06df2a4bd
Merge pull request #15727 from poettering/systemctl-list-sockets-tweak
systemctl: some table output tweaks
2020-05-06 22:38:25 +02:00
Balint Reczey
e48471b948 test: Skip test-boot-timestamps on permission denied
In containers even root can be denied to access the needed files.
2020-05-06 22:01:50 +02:00
Bastien Nocera
259f0dfbec hwdb: Force "mouse" type on Logitech Ultrathin Touch Mouse
Closes: #15657
2020-05-06 21:09:29 +02:00
Lennart Poettering
1fab579743 systemctl: underline whole rows, gapless
Just some tweaking of the output.
2020-05-06 15:40:15 +02:00
Lennart Poettering
b0395c1176 format-table: support coloring the gap right of each cell individually
This is useful for underlining a whole row of cells: previously we
couldn't underline the gap. Now we can.
2020-05-06 15:40:15 +02:00
Lennart Poettering
45d82c3f1c systemctl: ensure underline for "list-unit-files" empty cells 2020-05-06 15:40:15 +02:00
Lennart Poettering
50098d87fb systemctl: let's tweak how we synthesize a cell for activating unit
Let's create a string cell for the unit if possible (since there can
only be one unit right now, and the JSON alternative output then
generates a string instead of an array for us), an empty cell if empty.
2020-05-06 15:40:15 +02:00
Lennart Poettering
bc04bb0d29 systemctl: change column name in "list-sockets" out from "units" to "unit"
All our other tables call the field in singular, hence let's do so here,
too.
2020-05-06 15:40:15 +02:00
Lennart Poettering
0773357ad1 systemctl: show empty cells as '-'
This is mostly relevant for "systemct list-sockets" which can have empty
cells for the activating unit.
2020-05-06 15:40:15 +02:00
Lennart Poettering
557b0841b7 format-table: display an empty strv cell the same way as an empty cell
An empty list conceptually is very close to null, hence let's show it
the same way, i.e. using the defined "empty" string, and greyed out.
2020-05-06 15:40:15 +02:00
Zbigniew Jędrzejewski-Szmek
0894f08bf1 resolve: fix type of parameter and update man page
The "a" got dropped in eff7c2d3c905dec9ea4e1d5e53a0efd6af7d3d26.
2020-05-06 15:02:38 +02:00
Zbigniew Jędrzejewski-Szmek
ba5a389d24 Merge pull request #15473 from keszybz/bus-introspection 2020-05-06 15:00:07 +02:00
Zbigniew Jędrzejewski-Szmek
b61cc5fdad man: update login1(5) for SetType()
Added in db72aea4a952cdfdef51eda03408d7c4a11e7359.
2020-05-06 09:13:42 +02:00
Zbigniew Jędrzejewski-Szmek
b856b346c1 man: add stub for home1(5) 2020-05-06 09:13:42 +02:00
Zbigniew Jędrzejewski-Szmek
cfd508a9d6 homed: convert to the new scheme and add --bus-introspect 2020-05-06 09:13:42 +02:00
Zbigniew Jędrzejewski-Szmek
1a0e562a5b man: add description of org.freedesktop.LogControl1
I'm not sure if the LogTarget property is sufficiently general to be made into
a property that can be generally implemented. It is very closely tied to the internal
systemd logic. The other two seem fine thoough.
2020-05-05 22:41:23 +02:00
Zbigniew Jędrzejewski-Szmek
81e06775be meson: add man/update-dbus-docs target 2020-05-05 22:41:23 +02:00
Zbigniew Jędrzejewski-Szmek
7cb4f4145f man: drop LogLevel from resolve1(5)
Removed in 4c4520789d2bfa3fa51b38b826cac2efb5a4d252.
2020-05-05 22:41:23 +02:00
Zbigniew Jędrzejewski-Szmek
38b52b6918 man: drop CanMultiSession from documention
Removed in 8f8cc84ba4612e74cd1e26898c6816e6e60fc4e9.
2020-05-05 22:41:23 +02:00
Zbigniew Jędrzejewski-Szmek
48f99d7c06 man: use --bus-introspect to autogenerate dbus api docs
This has the advantage that the executables are always in place and we don't
need any units to exist on the bus, so we can eventually hook this up into
a normal build system. (Probably as a build time check.)
2020-05-05 22:41:23 +02:00
Zbigniew Jędrzejewski-Szmek
c351d568c3 update-dbus-docs: use executables in build/ 2020-05-05 22:41:23 +02:00
Zbigniew Jędrzejewski-Szmek
5c08257b70 pid1: add --bus-introspect 2020-05-05 22:40:44 +02:00
Zbigniew Jędrzejewski-Szmek
f6e9aa9e45 pid1: convert to the new scheme
In all the other cases, I think the code was clearer with the static table.
Here, not so much. And because of the existing dump code, the vtables cannot
be made static and need to remain exported. I still think it's worth to do the
change to have the cmdline introspection, but I'm disappointed with how this
came out.
2020-05-05 22:40:37 +02:00
Zbigniew Jędrzejewski-Szmek
4faa530cf6 machined: convert to the new scheme and add --bus-introspect 2020-05-05 22:38:31 +02:00
Zbigniew Jędrzejewski-Szmek
5ceceff170 localed: convert to the new scheme and add --bus-introspect 2020-05-05 22:37:08 +02:00
Zbigniew Jędrzejewski-Szmek
670139db40 hostnamed: convert to the new scheme and add --bus-introspect 2020-05-05 22:36:54 +02:00
Zbigniew Jędrzejewski-Szmek
8b4933973e bus-introspect: list the interfaces with "list"
The output is not very well formatted, but it is still useful when
testing this.
2020-05-05 22:36:38 +02:00
Zbigniew Jędrzejewski-Szmek
8d1280897b resolved: convert to the new scheme 2020-05-05 22:36:37 +02:00
Zbigniew Jędrzejewski-Szmek
c4b7d95c46 timedated: convert to the new scheme and add --bus-introspect 2020-05-05 22:34:37 +02:00
Zbigniew Jędrzejewski-Szmek
cd7e1e1a7f units: change description of systemd-logind.service
"Login Service" doesn''t explain much, esp. considering that logind is actually is
for logins. I think "User Login Management" is better, but not that great either.
Suggestions welcome.
2020-05-05 22:34:17 +02:00
Zbigniew Jędrzejewski-Szmek
d4cc0edfce importd,logind: add --bus-introspect= option 2020-05-05 22:34:17 +02:00
Zbigniew Jędrzejewski-Szmek
1e9bc92dba bus-util: add wrapper for interface introspection 2020-05-05 22:33:53 +02:00
Zbigniew Jędrzejewski-Szmek
c2b178d3ca logind: convert to the new scheme 2020-05-05 22:33:52 +02:00
Zbigniew Jędrzejewski-Szmek
a3b7cf5013 importd: convert to the new scheme 2020-05-05 22:31:50 +02:00
Zbigniew Jędrzejewski-Szmek
6a7e98aaca sd-bus: add helper struct for interface definitions
The idea is to have a static table that defines the dbus API. The vtable is
defined right next to the interface name and path because they are logically
connected.
2020-05-05 22:27:03 +02:00
Zbigniew Jędrzejewski-Szmek
fc021a5bbf logind,importd,hostnamed,localed,timedated,machined,resolved: add option parsing stubs
--help and --version are implemented in the usual style.
help() prints full path, since the program is not expected to
be in $PATH.
2020-05-03 10:55:51 +02:00
Zbigniew Jędrzejewski-Szmek
7ae473268c manager: add highlighting to --help
Also change the summary line to a bit more concise.
2020-05-03 10:55:51 +02:00
Zbigniew Jędrzejewski-Szmek
53f7f7fcf2 util-lib: add stub parser for --help, --version 2020-05-03 10:55:51 +02:00
Zbigniew Jędrzejewski-Szmek
ab09bf9007 importd: wrap long lines 2020-05-03 10:55:51 +02:00
Zbigniew Jędrzejewski-Szmek
b49ca3bc37 sd-bus: use STR_IN_SET() in one more place 2020-05-03 10:55:51 +02:00
Zbigniew Jędrzejewski-Szmek
2b6a1d155d bus-introspect: move xml string defines into the .c file 2020-05-03 10:55:51 +02:00
Zbigniew Jędrzejewski-Szmek
61d0df3919 bus-introspect: write <interface> from within introspect_write_interface() 2020-05-03 10:55:51 +02:00
93 changed files with 2691 additions and 1161 deletions

View File

@ -70,3 +70,7 @@ id-input:modalias:input:b0003v28bdp0078*
# Lite-On Tech IBM USB Travel Keyboard with Ultra Nav Mouse
id-input:modalias:input:b0003v04B3p301Ee0100-e0,1,2,4*
ID_INPUT_POINTINGSTICK=1
# Logitech Ultrathin Touch Mouse
id-input:modalias:input:b0005v046DpB00De0700*
ID_INPUT_MOUSE=1

View File

@ -34,6 +34,7 @@ custom_entities_ent = configure_file(
man_pages = []
html_pages = []
source_xml_files = []
dbus_docs = []
foreach tuple : xsltproc.found() ? manpages : []
stem = tuple[0]
section = tuple[1]
@ -90,7 +91,11 @@ foreach tuple : xsltproc.found() ? manpages : []
install_dir : join_paths(docdir, 'html'))
html_pages += p3
source_xml_files += files(tuple[0] + '.xml')
file = files(tuple[0] + '.xml')
source_xml_files += file
if tuple[0].startswith('org.freedesktop.')
dbus_docs += file
endif
else
message('Skipping @0@.@1@ because @2@ is false'.format(stem, section, condition))
endif
@ -193,6 +198,19 @@ run_target(
############################################################
if dbus_docs.length() > 0
custom_target(
'update-dbus-docs',
output : 'update-dbus-docs',
command : ['python3',
'@0@/tools/update-dbus-docs.py'.format(project_source_root),
'--build-dir=@0@'.format(project_build_root),
'@INPUT@'],
input : dbus_docs)
endif
############################################################
if git.found()
custom_target(
'update-man-rules',

View File

@ -0,0 +1,106 @@
<?xml version='1.0'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" >
<!-- SPDX-License-Identifier: LGPL-2.1+ -->
<refentry id="org.freedesktop.LogControl1"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>org.freedesktop.LogControl1</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>org.freedesktop.LogControl1</refentrytitle>
<manvolnum>5</manvolnum>
</refmeta>
<refnamediv>
<refname>org.freedesktop.LogControl1</refname>
<refpurpose>D-Bus interface to query and set logging configuration</refpurpose>
</refnamediv>
<refsect1>
<title>Introduction</title>
<para><interfacename>org.freedesktop.LogControl1</interfacename> is a generic interface that is intended
to be used by any daemon which should allow setting the log level and target over D-Bus. It is implemented
by various daemons that are part of the
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> suite.</para>
<para>It is assumed that those settings are global for the whole program, so a fixed object path is
used. The interface should always be available under the path
<filename>/org/freedesktop/LogControl1</filename>.</para>
</refsect1>
<refsect1>
<title>Description</title>
<para>The following interface is exposed:</para>
<programlisting executable="systemd" node="/org/freedesktop/LogControl1" interface="org.freedesktop.LogControl1">
node /org/freedesktop/LogControl1 {
interface org.freedesktop.LogControl1 {
properties:
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@org.freedesktop.systemd1.Privileged("true")
readwrite s LogLevel = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@org.freedesktop.systemd1.Privileged("true")
readwrite s LogTarget = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s SyslogIdentifier = '...';
};
interface org.freedesktop.DBus.Peer { ... };
interface org.freedesktop.DBus.Introspectable { ... };
interface org.freedesktop.DBus.Properties { ... };
};
</programlisting>
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.LogControl1"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.LogControl1"/>
<variablelist class="dbus-property" generated="True" extra-ref="LogLevel"/>
<variablelist class="dbus-property" generated="True" extra-ref="LogTarget"/>
<variablelist class="dbus-property" generated="True" extra-ref="SyslogIdentifier"/>
<!--End of Autogenerated section-->
<refsect2>
<title>Properties</title>
<para><varname>LogLevel</varname> describes the
<citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>-style
log-level, and should be one of <literal>emerg</literal>, <literal>alert</literal>,
<literal>crit</literal>, <literal>err</literal>, <literal>warning</literal>, <literal>notice</literal>,
<literal>info</literal>, <literal>debug</literal>, in order of increasing verbosity.</para>
<para><varname>LogTarget</varname> describes the log target (mechanism). It should be one of
<literal>console</literal> (log to the console or standard output),
<literal>kmsg</literal> (log to the kernel ring buffer),
<literal>journal</literal> (log the the journal natively, see
<citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>),
<literal>syslog</literal> (log using the
<citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> call).
</para>
<para>Those two properties are writable, so they may be set by sufficiently privileged users.</para>
<para><varname>SyslogIdentifier</varname> is a read-only property that shows the "syslog identifier".
It is a short string that identifies the program that is the source of log messages that is passed to
the <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> call.
</para>
<para>Note: <command>journalctl</command> option <option>-p</option>/<option>--priority=</option> may
be used to filter log messages by log level, option <option>-t</option>/<option>--identifier=</option>
may be used to by the syslog identifier, and filters like <literal>_TRANSPORT=syslog</literal>,
<literal>_TRANSPORT=journal</literal>, and <literal>_TRANSPORT=kernel</literal> may be used to filter
messages by the mechanism through which they reached <command>systemd-journald</command>.</para>
</refsect2>
</refsect1>
</refentry>

View File

@ -0,0 +1,369 @@
<?xml version='1.0'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" >
<!-- SPDX-License-Identifier: LGPL-2.1+ -->
<refentry id="org.freedesktop.home1" conditional='ENABLE_HOMED'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>org.freedesktop.home1</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>org.freedesktop.home1</refentrytitle>
<manvolnum>5</manvolnum>
</refmeta>
<refnamediv>
<refname>org.freedesktop.home1</refname>
<refpurpose>The D-Bus interface of systemd-homed</refpurpose>
</refnamediv>
<refsect1>
<title>Introduction</title>
<para>
<citerefentry><refentrytitle>systemd-homed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
is a system service which may be used to to create, remove, change or inspect home areas. This page
describes the D-Bus interface.
</para>
</refsect1>
<refsect1>
<title>The Manager Object</title>
<para>The service exposes the following interfaces on the Manager object on the bus:</para>
<programlisting executable="systemd-homed" node="/org/freedesktop/home1" interface="org.freedesktop.home1.Manager">
node /org/freedesktop/home1 {
interface org.freedesktop.home1.Manager {
methods:
GetHomeByName(in s user_name,
out u uid,
out s home_state,
out u gid,
out s real_name,
out s home_directory,
out s shell,
out o bus_path);
GetHomeByUID(in u uid,
out s user_name,
out s home_state,
out u gid,
out s real_name,
out s home_directory,
out s shell,
out o bus_path);
GetUserRecordByName(in s user_name,
out s user_record,
out b incomplete,
out o bus_path);
GetUserRecordByUID(in u uid,
out s user_record,
out b incomplete,
out o bus_path);
ListHomes(out a(susussso) home_areas);
ActivateHome(in s user_name,
in s user_record);
DeactivateHome(in s user_name);
RegisterHome(in s home_record);
UnregisterHome(in s user_name);
CreateHome(in s home_record);
RealizeHome(in s user_name,
in s user_record);
RemoveHome(in s user_name);
FixateHome(in s user_name,
in s user_record);
AuthenticateHome(in s user_name,
in s user_record);
UpdateHome(in s user_record);
ResizeHome(in s user_name,
in t size,
in s user_record);
ChangePasswordHome(in s user_name,
in s new_user_record,
in s old_user_record);
LockHome(in s user_name);
UnlockHome(in s user_name,
in s user_record);
AcquireHome(in s user_name,
in s user_record,
in b please_suspend,
out h send_fd);
RefHome(in s user_name,
in b please_suspend,
out h send_fd);
ReleaseHome(in s user_name);
LockAllHomes();
properties:
readonly a(sso) AutoLogin = [...];
};
interface org.freedesktop.DBus.Peer { ... };
interface org.freedesktop.DBus.Introspectable { ... };
interface org.freedesktop.DBus.Properties { ... };
};
</programlisting>
<!--method GetHomeByName is not documented!-->
<!--method GetHomeByUID is not documented!-->
<!--method GetUserRecordByName is not documented!-->
<!--method GetUserRecordByUID is not documented!-->
<!--method ListHomes is not documented!-->
<!--method ActivateHome is not documented!-->
<!--method DeactivateHome is not documented!-->
<!--method RegisterHome is not documented!-->
<!--method UnregisterHome is not documented!-->
<!--method CreateHome is not documented!-->
<!--method RealizeHome is not documented!-->
<!--method RemoveHome is not documented!-->
<!--method FixateHome is not documented!-->
<!--method AuthenticateHome is not documented!-->
<!--method UpdateHome is not documented!-->
<!--method ResizeHome is not documented!-->
<!--method ChangePasswordHome is not documented!-->
<!--method LockHome is not documented!-->
<!--method UnlockHome is not documented!-->
<!--method AcquireHome is not documented!-->
<!--method RefHome is not documented!-->
<!--method ReleaseHome is not documented!-->
<!--method LockAllHomes is not documented!-->
<!--property AutoLogin is not documented!-->
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.home1.Manager"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.home1.Manager"/>
<variablelist class="dbus-method" generated="True" extra-ref="GetHomeByName()"/>
<variablelist class="dbus-method" generated="True" extra-ref="GetHomeByUID()"/>
<variablelist class="dbus-method" generated="True" extra-ref="GetUserRecordByName()"/>
<variablelist class="dbus-method" generated="True" extra-ref="GetUserRecordByUID()"/>
<variablelist class="dbus-method" generated="True" extra-ref="ListHomes()"/>
<variablelist class="dbus-method" generated="True" extra-ref="ActivateHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="DeactivateHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="RegisterHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="UnregisterHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="CreateHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="RealizeHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="RemoveHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="FixateHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AuthenticateHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="UpdateHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="ResizeHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="ChangePasswordHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="LockHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="UnlockHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AcquireHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="RefHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="ReleaseHome()"/>
<variablelist class="dbus-method" generated="True" extra-ref="LockAllHomes()"/>
<variablelist class="dbus-property" generated="True" extra-ref="AutoLogin"/>
<!--End of Autogenerated section-->
<refsect2>
<title>Methods</title>
<para>...</para>
</refsect2>
<refsect2>
<title>Signals</title>
<para>...</para>
</refsect2>
</refsect1>
<refsect1>
<title>The Home Object</title>
<programlisting executable="systemd-homed" node="/org/freedesktop/home1/home" interface="org.freedesktop.home1.Home">
node /org/freedesktop/home1/home {
interface org.freedesktop.home1.Home {
methods:
Activate(in s user_record);
Deactivate();
Unregister();
Realize(in s user_record);
Remove();
Fixate(in s user_record);
Authenticate(in s user_record);
Update(in s user_record);
Resize(in t size,
in s user_record);
ChangePassword(in s new_user_record,
in s old_user_record);
Lock();
Unlock(in s user_record);
Acquire(in s user_record,
in b please_suspend,
out h send_fd);
Ref(in b please_suspend,
out h send_fd);
Release();
properties:
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s UserName = '...';
readonly u UID = ...;
readonly (suusss) UnixRecord = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s State = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
readonly (sb) UserRecord = ...;
};
interface org.freedesktop.DBus.Peer { ... };
interface org.freedesktop.DBus.Introspectable { ... };
interface org.freedesktop.DBus.Properties { ... };
interface org.freedesktop.DBus.ObjectManager { ... };
};
</programlisting>
<!--method Activate is not documented!-->
<!--method Deactivate is not documented!-->
<!--method Unregister is not documented!-->
<!--method Realize is not documented!-->
<!--method Remove is not documented!-->
<!--method Fixate is not documented!-->
<!--method Authenticate is not documented!-->
<!--method Update is not documented!-->
<!--method Resize is not documented!-->
<!--method ChangePassword is not documented!-->
<!--method Lock is not documented!-->
<!--method Unlock is not documented!-->
<!--method Acquire is not documented!-->
<!--method Ref is not documented!-->
<!--method Release is not documented!-->
<!--property UserName is not documented!-->
<!--property UID is not documented!-->
<!--property UnixRecord is not documented!-->
<!--property State is not documented!-->
<!--property UserRecord is not documented!-->
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.DBus.ObjectManager"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.home1.Home"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.DBus.ObjectManager"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.home1.Home"/>
<variablelist class="dbus-method" generated="True" extra-ref="Activate()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Deactivate()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Unregister()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Realize()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Remove()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Fixate()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Authenticate()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Update()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Resize()"/>
<variablelist class="dbus-method" generated="True" extra-ref="ChangePassword()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Lock()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Unlock()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Acquire()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Ref()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Release()"/>
<variablelist class="dbus-property" generated="True" extra-ref="UserName"/>
<variablelist class="dbus-property" generated="True" extra-ref="UID"/>
<variablelist class="dbus-property" generated="True" extra-ref="UnixRecord"/>
<variablelist class="dbus-property" generated="True" extra-ref="State"/>
<variablelist class="dbus-property" generated="True" extra-ref="UserRecord"/>
<!--End of Autogenerated section-->
</refsect1>
<refsect1>
<title>Versioning</title>
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
</refentry>

View File

@ -38,11 +38,7 @@
<para>The service exposes the following interfaces on the bus:</para>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.hostname1 \
--object-path /org/freedesktop/hostname1
<programlisting executable="systemd-hostnamed" node="/org/freedesktop/hostname1" interface="org.freedesktop.hostname1">
node /org/freedesktop/hostname1 {
interface org.freedesktop.hostname1 {
methods:
@ -349,6 +345,19 @@ node /org/freedesktop/hostname1 {
the usual interface versioning guidelines</ulink>.</para>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>Introspect <interfacename>org.freedesktop.hostname1</interfacename> on the bus</title>
<programlisting>$ gdbus introspect --system \
--dest org.freedesktop.hostname1 \
--object-path /org/freedesktop/hostname1
</programlisting>
</example>
</refsect1>
<refsect1>
<title>See also</title>

View File

@ -46,11 +46,7 @@
<para>The service exposes the following interfaces on the Manager object on the bus:</para>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.import1 \
--object-path /org/freedesktop/import1
<programlisting executable="systemd-importd" node="/org/freedesktop/import1" interface="org.freedesktop.import1.Manager">
node /org/freedesktop/import1 {
interface org.freedesktop.import1.Manager {
methods:
@ -238,11 +234,7 @@ node /org/freedesktop/import1 {
<refsect1>
<title>The Transfer Object</title>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.import1 \
--object-path /org/freedesktop/import1/transfer/_1
<programlisting executable="systemd-importd" node="/org/freedesktop/import1/transfer/_1" interface="org.freedesktop.import1.Transfer">
node /org/freedesktop/import1/transfer/_1 {
interface org.freedesktop.import1.Transfer {
methods:
@ -325,6 +317,28 @@ node /org/freedesktop/import1/transfer/_1 {
</refsect2>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>Introspect <interfacename>org.freedesktop.import1.Manager</interfacename> on the bus</title>
<programlisting>$ gdbus introspect --system \
--dest org.freedesktop.import1 \
--object-path /org/freedesktop/import1
</programlisting>
</example>
<example>
<title>Introspect <interfacename>org.freedesktop.import1.Transfer</interfacename> on the bus</title>
<programlisting>$ gdbus introspect --system \
--dest org.freedesktop.import1 \
--object-path /org/freedesktop/import1/transfer/_1
</programlisting>
</example>
</refsect1>
<refsect1>
<title>Versioning</title>

View File

@ -34,11 +34,7 @@
<para>The service exposes the following interfaces on the bus:</para>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.locale1 \
--object-path /org/freedesktop/locale1
<programlisting executable="systemd-localed" node="/org/freedesktop/locale1" interface="org.freedesktop.locale1">
node /org/freedesktop/locale1 {
interface org.freedesktop.locale1 {
methods:
@ -169,6 +165,20 @@ node /org/freedesktop/locale1 {
</refsect2>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>Introspect <interfacename>org.freedesktop.locale1</interfacename> on the bus</title>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.locale1 \
--object-path /org/freedesktop/locale1
</programlisting>
</example>
</refsect1>
<refsect1>
<title>Versioning</title>

View File

@ -38,11 +38,7 @@
<para>The service exposes the following interfaces on the Manager object on the bus:</para>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1
<programlisting executable="systemd-logind" node="/org/freedesktop/login1" interface="org.freedesktop.login1.Manager">
node /org/freedesktop/login1 {
interface org.freedesktop.login1.Manager {
methods:
@ -741,10 +737,7 @@ node /org/freedesktop/login1 {
<refsect1>
<title>Seat Objects</title>
<programlisting>
$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1/seat/seat0
<programlisting executable="systemd-logind" node="/org/freedesktop/login1/seat/seat0" interface="org.freedesktop.login1.Seat">
node /org/freedesktop/login1/seat/seat0 {
interface org.freedesktop.login1.Seat {
methods:
@ -758,8 +751,6 @@ node /org/freedesktop/login1/seat/seat0 {
readonly s Id = '...';
readonly (so) ActiveSession = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b CanMultiSession = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b CanTTY = ...;
readonly b CanGraphical = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@ -794,8 +785,6 @@ node /org/freedesktop/login1/seat/seat0 {
<variablelist class="dbus-property" generated="True" extra-ref="ActiveSession"/>
<variablelist class="dbus-property" generated="True" extra-ref="CanMultiSession"/>
<variablelist class="dbus-property" generated="True" extra-ref="CanTTY"/>
<variablelist class="dbus-property" generated="True" extra-ref="CanGraphical"/>
@ -827,7 +816,7 @@ node /org/freedesktop/login1/seat/seat0 {
<title>Signals</title>
<para>Whenever <function>ActiveSession</function>, <function>Sessions</function>,
<function>CanGraphical</function>, <function>CanMultiSession</function> and <function>CanTTY</function>
<function>CanGraphical</function>, <function>CanTTY</function>,
or the idle state changes, <function>PropertyChanged</function> signals are sent out to which clients
can subscribe.</para>
</refsect2>
@ -840,9 +829,8 @@ node /org/freedesktop/login1/seat/seat0 {
<para><varname>ActiveSession</varname> encodes the currently active session if there is one. It is a
structure consisting of the session id and the object path.</para>
<para><varname>CanMultiSession</varname> encodes whether the session is multi-session capable,
<varname>CanTTY</varname> whether it is suitable for text logins, <varname>CanGraphical</varname>
whether it is suitable for graphical sessions.</para>
<para><varname>CanTTY</varname> encodes whether the session is suitable for text logins, and
<varname>CanGraphical</varname> whether it is suitable for graphical sessions.</para>
<para>The <varname>Sessions</varname> property is an array of all current sessions of this seat, each
encoded in a structure consisting of the ID and the object path.</para>
@ -856,10 +844,7 @@ node /org/freedesktop/login1/seat/seat0 {
<refsect1>
<title>User Objects</title>
<programlisting>
$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1/user/_1000
<programlisting executable="systemd-logind" node="/org/freedesktop/login1/user/_1000" interface="org.freedesktop.login1.User">
node /org/freedesktop/login1/user/_1000 {
interface org.freedesktop.login1.User {
methods:
@ -1004,11 +989,8 @@ node /org/freedesktop/login1/user/_1000 {
<refsect1>
<title>Session Objects</title>
<programlisting>
$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1/session/45
node /org/freedesktop/login1/session/45 {
<programlisting executable="systemd-logind" node="/org/freedesktop/login1/session/1" interface="org.freedesktop.login1.Session">
node /org/freedesktop/login1/session/1 {
interface org.freedesktop.login1.Session {
methods:
Terminate();
@ -1021,6 +1003,7 @@ node /org/freedesktop/login1/session/45 {
in i signal_number);
TakeControl(in b force);
ReleaseControl();
SetType(in s type);
TakeDevice(in u major,
in u minor,
out h fd,
@ -1076,7 +1059,6 @@ node /org/freedesktop/login1/session/45 {
readonly u Leader = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly u Audit = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Type = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Class = '...';
@ -1093,6 +1075,100 @@ node /org/freedesktop/login1/session/45 {
};
</programlisting>
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.login1.Session"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.login1.Session"/>
<variablelist class="dbus-method" generated="True" extra-ref="Terminate()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Activate()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Lock()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Unlock()"/>
<variablelist class="dbus-method" generated="True" extra-ref="SetIdleHint()"/>
<variablelist class="dbus-method" generated="True" extra-ref="SetLockedHint()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Kill()"/>
<variablelist class="dbus-method" generated="True" extra-ref="TakeControl()"/>
<variablelist class="dbus-method" generated="True" extra-ref="ReleaseControl()"/>
<variablelist class="dbus-method" generated="True" extra-ref="SetType()"/>
<variablelist class="dbus-method" generated="True" extra-ref="TakeDevice()"/>
<variablelist class="dbus-method" generated="True" extra-ref="ReleaseDevice()"/>
<variablelist class="dbus-method" generated="True" extra-ref="PauseDeviceComplete()"/>
<variablelist class="dbus-method" generated="True" extra-ref="SetBrightness()"/>
<variablelist class="dbus-signal" generated="True" extra-ref="PauseDevice"/>
<variablelist class="dbus-signal" generated="True" extra-ref="ResumeDevice"/>
<variablelist class="dbus-signal" generated="True" extra-ref="Lock"/>
<variablelist class="dbus-signal" generated="True" extra-ref="Unlock"/>
<variablelist class="dbus-property" generated="True" extra-ref="Id"/>
<variablelist class="dbus-property" generated="True" extra-ref="User"/>
<variablelist class="dbus-property" generated="True" extra-ref="Name"/>
<variablelist class="dbus-property" generated="True" extra-ref="Timestamp"/>
<variablelist class="dbus-property" generated="True" extra-ref="TimestampMonotonic"/>
<variablelist class="dbus-property" generated="True" extra-ref="VTNr"/>
<variablelist class="dbus-property" generated="True" extra-ref="Seat"/>
<variablelist class="dbus-property" generated="True" extra-ref="TTY"/>
<variablelist class="dbus-property" generated="True" extra-ref="Display"/>
<variablelist class="dbus-property" generated="True" extra-ref="Remote"/>
<variablelist class="dbus-property" generated="True" extra-ref="RemoteHost"/>
<variablelist class="dbus-property" generated="True" extra-ref="RemoteUser"/>
<variablelist class="dbus-property" generated="True" extra-ref="Service"/>
<variablelist class="dbus-property" generated="True" extra-ref="Desktop"/>
<variablelist class="dbus-property" generated="True" extra-ref="Scope"/>
<variablelist class="dbus-property" generated="True" extra-ref="Leader"/>
<variablelist class="dbus-property" generated="True" extra-ref="Audit"/>
<variablelist class="dbus-property" generated="True" extra-ref="Type"/>
<variablelist class="dbus-property" generated="True" extra-ref="Class"/>
<variablelist class="dbus-property" generated="True" extra-ref="Active"/>
<variablelist class="dbus-property" generated="True" extra-ref="State"/>
<variablelist class="dbus-property" generated="True" extra-ref="IdleHint"/>
<variablelist class="dbus-property" generated="True" extra-ref="IdleSinceHint"/>
<variablelist class="dbus-property" generated="True" extra-ref="IdleSinceHintMonotonic"/>
<variablelist class="dbus-property" generated="True" extra-ref="LockedHint"/>
<!--End of Autogenerated section-->
<refsect2>
<title>Methods</title>
@ -1109,10 +1185,17 @@ node /org/freedesktop/login1/session/45 {
out and replaced. Otherwise, this method fails if there is already a controller. Note that this method is
limited to D-Bus users with the effective UID set to the user of the session or root.</para>
<para><function>ReleaseControl()</function> drops control of a given session. Closing the
D-Bus connection implicitly releases control as well. See <function>TakeControl()</function> for more information. This
method also releases all devices for which the controller requested ownership via <function>TakeDevice()</function>.
</para>
<para><function>ReleaseControl()</function> drops control of a given session. Closing the D-Bus
connection implicitly releases control as well. See <function>TakeControl()</function> for more
information. This method also releases all devices for which the controller requested ownership via
<function>TakeDevice()</function>.</para>
<para><function>SetType()</function> allows the type of the session to be changed dynamically. It can
only be called by session's current controller. If <function>TakeControl()</function> has not been
called, this method will fail. In addition, the session type will be reset to its original value once
control is released, either by calling <function>ReleaseControl()</function> or closing the D-Bus
connection. This should help prevent a session from entering an inconsistent state, for example if the
controller crashes. The only argument <varname>type</varname> is the new session type.</para>
<para><function>TakeDevice()</function> allows a session controller to get a file descriptor for a
specific device. Pass in the major and minor numbers of the character device and
@ -1257,6 +1340,42 @@ node /org/freedesktop/login1/session/45 {
</refsect2>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>Introspect <interfacename>org.freedesktop.login1.Manager</interfacename> on the bus</title>
<programlisting>$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1
</programlisting>
</example>
<example>
<title>Introspect <interfacename>org.freedesktop.login1.Seat</interfacename> on the bus</title>
<programlisting>$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1/seat/seat0
</programlisting>
</example>
<example>
<title>Introspect <interfacename>org.freedesktop.login1.User</interfacename> on the bus</title>
<programlisting>$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1/user/_1000
</programlisting>
</example>
<example>
<title>Introspect <interfacename>org.freedesktop.login1.Session</interfacename> on the bus</title>
<programlisting>$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1/session/45
</programlisting>
</example>
</refsect1>
<refsect1>
<title>Versioning</title>

View File

@ -34,11 +34,7 @@
<para>The service exposes the following interfaces on the Manager object on the bus:</para>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.machine1 \
--object-path /org/freedesktop/machine1
<programlisting executable="systemd-machined" node="/org/freedesktop/machine1" interface="org.freedesktop.machine1.Manager">
node /org/freedesktop/machine1 {
interface org.freedesktop.machine1.Manager {
methods:
@ -435,11 +431,7 @@ node /org/freedesktop/machine1 {
<refsect1>
<title>Machine Objects</title>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.machine1 \
--object-path /org/freedesktop/machine1/machine/rawhide
<programlisting executable="systemd-machined" node="/org/freedesktop/machine1/machine/rawhide" interface="org.freedesktop.machine1.Machine">
node /org/freedesktop/machine1/machine/rawhide {
interface org.freedesktop.machine1.Machine {
methods:
@ -617,6 +609,30 @@ node /org/freedesktop/machine1/machine/rawhide {
</refsect2>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>Introspect <interfacename>org.freedesktop.machine1.Manager</interfacename> on the bus</title>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.machine1 \
--object-path /org/freedesktop/machine1
</programlisting>
</example>
<example>
<title>Introspect <interfacename>org.freedesktop.machine1.Machine</interfacename> on the bus</title>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.machine1 \
--object-path /org/freedesktop/machine1/machine/rawhide
</programlisting>
</example>
</refsect1>
<refsect1>
<title>Versioning</title>

View File

@ -46,11 +46,7 @@
<para>The service exposes the following interfaces on the Manager object on the bus:</para>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.resolve1 \
--object-path /org/freedesktop/resolve1
<programlisting executable="systemd-resolved" node="/org/freedesktop/resolve1" interface="org.freedesktop.resolve1.Manager">
node /org/freedesktop/resolve1 {
interface org.freedesktop.resolve1.Manager {
methods:
@ -110,7 +106,7 @@ node /org/freedesktop/resolve1 {
in s type,
in q service_port,
in q service_priority,
in q serwise_weight,
in q service_weight,
in aa{say} txt_datas,
out o service_path);
UnregisterService(in o service_path);
@ -145,9 +141,6 @@ node /org/freedesktop/resolve1 {
readonly as DNSSECNegativeTrustAnchors = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s DNSStubListener = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@org.freedesktop.systemd1.Privileged("true")
readwrite s LogLevel = '...';
};
interface org.freedesktop.DBus.Peer { ... };
interface org.freedesktop.DBus.Introspectable { ... };
@ -257,8 +250,6 @@ node /org/freedesktop/resolve1 {
<variablelist class="dbus-property" generated="True" extra-ref="DNSStubListener"/>
<variablelist class="dbus-property" generated="True" extra-ref="LogLevel"/>
<!--End of Autogenerated section-->
<refsect2>
@ -551,12 +542,8 @@ node /org/freedesktop/resolve1 {
<refsect1>
<title>Link Object</title>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.resolve1 \
--object-path /org/freedesktop/resolve1/link/_34
node /org/freedesktop/resolve1/link/_34 {
<programlisting executable="systemd-resolved" node="/org/freedesktop/resolve1/link/_1" interface="org.freedesktop.resolve1.Link">
node /org/freedesktop/resolve1/link/_1 {
interface org.freedesktop.resolve1.Link {
methods:
SetDNS(in a(iay) addresses);
@ -790,6 +777,30 @@ node /org/freedesktop/resolve1/link/_34 {
</variablelist>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>Introspect <interfacename>org.freedesktop.resolve1.Manager</interfacename> on the bus</title>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.resolve1 \
--object-path /org/freedesktop/resolve1
</programlisting>
</example>
<example>
<title>Introspect <interfacename>org.freedesktop.resolve1.Link</interfacename> on the bus</title>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.resolve1 \
--object-path /org/freedesktop/resolve1/link/_11
</programlisting>
</example>
</refsect1>
<refsect1>
<title>Versioning</title>

View File

@ -57,11 +57,7 @@
<para>The main entry point object is available on the fixed
<constant>/org/freedesktop/systemd1</constant> object path:</para>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1
<programlisting executable="systemd" node="/org/freedesktop/systemd1" interface="org.freedesktop.systemd1.Manager">
node /org/freedesktop/systemd1 {
interface org.freedesktop.systemd1.Manager {
methods:
@ -1484,10 +1480,7 @@ node /org/freedesktop/systemd1 {
<refsect1>
<title>Unit Objects</title>
<programlisting interface="org.freedesktop.systemd1.Unit">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice
<programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice" interface="org.freedesktop.systemd1.Unit">
node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
interface org.freedesktop.systemd1.Unit {
methods:
@ -1674,7 +1667,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
interface org.freedesktop.DBus.Peer { ... };
interface org.freedesktop.DBus.Introspectable { ... };
interface org.freedesktop.DBus.Properties { ... };
interface org.freedesktop.systemd1.Service { ... };
};
</programlisting>
@ -1746,12 +1738,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Service"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Service"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-method" generated="True" extra-ref="Start()"/>
@ -2139,10 +2127,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<interfacename>org.freedesktop.systemd1.Service</interfacename> interface (described here) in addition to
the generic <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Service">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice
<programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice" interface="org.freedesktop.systemd1.Service">
node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
interface org.freedesktop.systemd1.Service {
methods:
@ -3135,14 +3120,14 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Service"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Service"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Service"/>
<variablelist class="dbus-method" generated="True" extra-ref="GetProcesses()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/>
@ -3746,10 +3731,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<refsect1>
<title>Socket Unit Objects</title>
<programlisting interface="org.freedesktop.systemd1.Socket">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket
<programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket" interface="org.freedesktop.systemd1.Socket">
node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
interface org.freedesktop.systemd1.Socket {
methods:
@ -4777,14 +4759,14 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Socket"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Socket"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Socket"/>
<variablelist class="dbus-method" generated="True" extra-ref="GetProcesses()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/>
@ -5340,10 +5322,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
<refsect1>
<title>Target Unit Objects</title>
<programlisting interface="org.freedesktop.systemd1.Target">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/basic_2etarget
<programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/basic_2etarget" interface="org.freedesktop.systemd1.Target">
node /org/freedesktop/systemd1/unit/basic_2etarget {
interface org.freedesktop.systemd1.Target {
};
@ -5364,11 +5343,8 @@ node /org/freedesktop/systemd1/unit/basic_2etarget {
<para>All device unit objects implement the <interfacename>org.freedesktop.systemd1.Device</interfacename> interface (described here)
in addition to the generic <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Device">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/dev_2dfoo_2edevice
node /org/freedesktop/systemd1/unit/dev_2dfoo_2edevice {
<programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/dev_2dttyS0_2edevice" interface="org.freedesktop.systemd1.Device">
node /org/freedesktop/systemd1/unit/dev_2dttyS0_2edevice {
interface org.freedesktop.systemd1.Device {
properties:
readonly s SysFSPath = '...';
@ -5382,14 +5358,14 @@ node /org/freedesktop/systemd1/unit/dev_2dfoo_2edevice {
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Device"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Device"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Device"/>
<variablelist class="dbus-property" generated="True" extra-ref="SysFSPath"/>
<!--End of Autogenerated section-->
@ -5411,10 +5387,7 @@ node /org/freedesktop/systemd1/unit/dev_2dfoo_2edevice {
interface (described here) in addition to the generic
<interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Mount">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/home_2emount
<programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/home_2emount" interface="org.freedesktop.systemd1.Mount">
node /org/freedesktop/systemd1/unit/home_2emount {
interface org.freedesktop.systemd1.Mount {
methods:
@ -6291,14 +6264,14 @@ node /org/freedesktop/systemd1/unit/home_2emount {
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Mount"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Mount"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Mount"/>
<variablelist class="dbus-method" generated="True" extra-ref="GetProcesses()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/>
@ -6773,10 +6746,7 @@ node /org/freedesktop/systemd1/unit/home_2emount {
<interfacename>org.freedesktop.systemd1.Automount</interfacename> interface (described here) in addition
to the generic <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Automount">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount
<programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount" interface="org.freedesktop.systemd1.Automount">
node /org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount {
interface org.freedesktop.systemd1.Automount {
properties:
@ -6803,14 +6773,14 @@ node /org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Automount"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Automount"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Automount"/>
<variablelist class="dbus-property" generated="True" extra-ref="Where"/>
<variablelist class="dbus-property" generated="True" extra-ref="DirectoryMode"/>
@ -6841,10 +6811,7 @@ node /org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount
interface (described here) in addition to the generic
<interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Timer">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer
<programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer" interface="org.freedesktop.systemd1.Timer">
node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer {
interface org.freedesktop.systemd1.Timer {
properties:
@ -6901,14 +6868,14 @@ node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer {
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Timer"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Timer"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Timer"/>
<variablelist class="dbus-property" generated="True" extra-ref="Unit"/>
<variablelist class="dbus-property" generated="True" extra-ref="TimersMonotonic"/>
@ -6980,10 +6947,7 @@ node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer {
interface (described here) in addition to the generic
<interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Swap">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap
<programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/dev_2dsda3_2eswap" interface="org.freedesktop.systemd1.Swap">
node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
interface org.freedesktop.systemd1.Swap {
methods:
@ -7836,14 +7800,14 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Swap"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Swap"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Swap"/>
<variablelist class="dbus-method" generated="True" extra-ref="GetProcesses()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/>
@ -8306,10 +8270,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
<refsect1>
<title>Path Unit Objects</title>
<programlisting interface="org.freedesktop.systemd1.Path">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/cups_2epath
<programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/cups_2epath" interface="org.freedesktop.systemd1.Path">
node /org/freedesktop/systemd1/unit/cups_2epath {
interface org.freedesktop.systemd1.Path {
properties:
@ -8336,14 +8297,14 @@ node /org/freedesktop/systemd1/unit/cups_2epath {
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Path"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Path"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Path"/>
<variablelist class="dbus-property" generated="True" extra-ref="Unit"/>
<variablelist class="dbus-property" generated="True" extra-ref="Paths"/>
@ -8382,10 +8343,7 @@ node /org/freedesktop/systemd1/unit/cups_2epath {
interface (described here) in addition to the generic
<interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Slice">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/system_2eslice
<programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/system_2eslice" interface="org.freedesktop.systemd1.Slice">
node /org/freedesktop/systemd1/unit/system_2eslice {
interface org.freedesktop.systemd1.Slice {
methods:
@ -8645,14 +8603,14 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Slice"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Slice"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Slice"/>
<variablelist class="dbus-method" generated="True" extra-ref="GetProcesses()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/>
@ -8793,10 +8751,7 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
interface (described here) in addition to the generic
<interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Scope">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/session_2d1_2escope
<programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/session_2d1_2escope" interface="org.freedesktop.systemd1.Scope">
node /org/freedesktop/systemd1/unit/session_2d1_2escope {
interface org.freedesktop.systemd1.Scope {
methods:
@ -9097,14 +9052,14 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Scope"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Scope"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Scope"/>
<variablelist class="dbus-method" generated="True" extra-ref="Abandon()"/>
<variablelist class="dbus-method" generated="True" extra-ref="GetProcesses()"/>
@ -9293,11 +9248,8 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
<para>Job objects encapsulate scheduled or running jobs. Each unit can have none or one jobs in the
execution queue. Each job is attached to exactly one unit.</para>
<programlisting>
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/job/1292
node /org/freedesktop/systemd1/job/1292 {
<programlisting executable="systemd" node="/org/freedesktop/systemd1/job/666" interface="org.freedesktop.systemd1.Job">
node /org/freedesktop/systemd1/job/666 {
interface org.freedesktop.systemd1.Job {
methods:
Cancel();
@ -9373,6 +9325,41 @@ node /org/freedesktop/systemd1/job/1292 {
</refsect2>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>Introspect <interfacename>org.freedesktop.systemd1.Manager</interfacename> on the bus</title>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1
</programlisting>
</example>
<example>
<title>Introspect a unit on the bus</title>
<programlisting>
$ busctl introspect org.freedesktop.systemd1 \
$(busctl call org.freedesktop.systemd1 \
/org/freedesktop/systemd1 \
org.freedesktop.systemd1.Manager \
GetUnit s systemd-resolved.service | cut -d'"' -f2)
</programlisting>
</example>
<example>
<title>Introspect <interfacename>org.freedesktop.systemd1.Job</interfacename> on the bus</title>
<programlisting>
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/job/1292
</programlisting>
</example>
</refsect1>
<refsect1>
<title>Versioning</title>

View File

@ -34,11 +34,7 @@
<para>The service exposes the following interfaces on the bus:</para>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.timedate1 \
--object-path /org/freedesktop/timedate1
<programlisting executable="systemd-timedated" node="/org/freedesktop/timedate1" interface="org.freedesktop.timedate1">
node /org/freedesktop/timedate1 {
interface org.freedesktop.timedate1 {
methods:
@ -180,6 +176,20 @@ node /org/freedesktop/timedate1 {
</refsect2>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>Introspect <interfacename>org.freedesktop.timedate1</interfacename> on the bus</title>
<programlisting>
$ gdbus introspect --system \
--dest org.freedesktop.timedate1 \
--object-path /org/freedesktop/timedate1
</programlisting>
</example>
</refsect1>
<refsect1>
<title>Versioning</title>

View File

@ -44,6 +44,8 @@ manpages = [
['nss-mymachines', '8', ['libnss_mymachines.so.2'], 'ENABLE_NSS_MYMACHINES'],
['nss-resolve', '8', ['libnss_resolve.so.2'], 'ENABLE_NSS_RESOLVE'],
['nss-systemd', '8', ['libnss_systemd.so.2'], 'ENABLE_NSS_SYSTEMD'],
['org.freedesktop.LogControl1', '5', [], ''],
['org.freedesktop.home1', '5', [], 'ENABLE_HOMED'],
['org.freedesktop.hostname1', '5', [], 'ENABLE_HOSTNAMED'],
['org.freedesktop.import1', '5', [], 'ENABLE_IMPORTD'],
['org.freedesktop.locale1', '5', [], 'ENABLE_LOCALED'],

View File

@ -56,7 +56,9 @@
is a command line client to this service.</para>
<para>See
<citerefentry><refentrytitle>org.freedesktop.hostname1</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<citerefentry><refentrytitle>org.freedesktop.hostname1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for a description of the D-Bus API.</para>
</refsect1>

View File

@ -36,10 +36,11 @@
<command>pull-raw</command>, <command>pull-tar</command>, <command>import-raw</command>,
<command>import-tar</command>, <command>export-raw</command>, and <command>export-tar</command> commands.</para>
<para>See the
<ulink url="https://www.freedesktop.org/wiki/Software/systemd/importd">
importd D-Bus API Documentation</ulink> for information about the
APIs <filename>systemd-importd</filename> provides.</para>
<para>See
<citerefentry><refentrytitle>org.freedesktop.import1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for a description of the D-Bus API.</para>
</refsect1>
<refsect1>

View File

@ -41,7 +41,9 @@
is a command line client to this service.</para>
<para>See
<citerefentry><refentrytitle>org.freedesktop.locale1</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<citerefentry><refentrytitle>org.freedesktop.locale1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for a description of the D-Bus API.</para>
</refsect1>

View File

@ -79,7 +79,9 @@
such as users, sessions and seats.</para>
<para>See
<citerefentry><refentrytitle>org.freedesktop.login1</refentrytitle><manvolnum>3</manvolnum></citerefentry>
<citerefentry><refentrytitle>org.freedesktop.login1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for information about the D-Bus APIs <filename>systemd-logind</filename> provides.</para>
<para>For more information on the inhibition logic see the <ulink

View File

@ -107,7 +107,9 @@
For more information please consult
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>org.freedesktop.machine1</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
<citerefentry><refentrytitle>org.freedesktop.machine1</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
and
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
</para>
<para>A small companion daemon

View File

@ -38,6 +38,8 @@
<listitem><para>The native, fully-featured API <command>systemd-resolved</command> exposes on the bus,
see
<citerefentry><refentrytitle>org.freedesktop.resolve1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. Usage of this API is generally recommended to clients as it is asynchronous and fully
featured (for example, properly returns DNSSEC validation status and interface scope for addresses as
necessary for supporting link-local networking).</para></listitem>

View File

@ -55,6 +55,8 @@
<para>See
<citerefentry><refentrytitle>org.freedesktop.timedate1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for information about the D-Bus API.</para>
</refsect1>

View File

@ -281,7 +281,10 @@
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
<para>The D-Bus API of <command>systemd</command> is described in
<citerefentry><refentrytitle>org.freedesktop.systemd1</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
<citerefentry><refentrytitle>org.freedesktop.systemd1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>org.freedesktop.LogControl1</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para>
<para>Systems which invoke systemd in a container or initrd environment should implement the <ulink
url="https://systemd.io/CONTAINER_INTERFACE">Container Interface</ulink> or <ulink

View File

@ -32,8 +32,9 @@ substs.set('PROJECT_VERSION', meson.project_version(),
# This is to be used instead of meson.source_root(), as the latter will return
# the wrong result when systemd is being built as a meson subproject
project_source_root = meson.current_source_dir()
project_build_root = meson.current_build_dir()
relative_source_path = run_command('realpath',
'--relative-to=@0@'.format(meson.current_build_dir()),
'--relative-to=@0@'.format(project_build_root),
project_source_root).stdout().strip()
conf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path)
@ -292,7 +293,7 @@ substs.set('RC_LOCAL_SCRIPT_PATH_START', get_option('rc-loc
substs.set('MEMORY_ACCOUNTING_DEFAULT', memory_accounting_default ? 'yes' : 'no')
substs.set('STATUS_UNIT_FORMAT_DEFAULT', status_unit_format_default)
substs.set('HIGH_RLIMIT_NOFILE', conf.get('HIGH_RLIMIT_NOFILE'))
substs.set('BUILD_ROOT', meson.current_build_dir())
substs.set('BUILD_ROOT', project_build_root)
#####################################################################
@ -3103,7 +3104,7 @@ custom_target(
output : 'systemd-runtest.env',
command : ['sh', '-c', '{ ' +
'echo SYSTEMD_TEST_DATA=@0@; '.format(join_paths(project_source_root, 'test')) +
'echo SYSTEMD_CATALOG_DIR=@0@; '.format(join_paths(meson.current_build_dir(), 'catalog')) +
'echo SYSTEMD_CATALOG_DIR=@0@; '.format(join_paths(project_build_root, 'catalog')) +
'} >@OUTPUT@'],
build_by_default : true)

View File

@ -28,6 +28,7 @@
#define ANSI_HIGHLIGHT_YELLOW4 "\x1B[0;1;38;5;100m"
/* Underlined */
#define ANSI_GREY_UNDERLINE "\x1B[0;4;38;5;245m"
#define ANSI_HIGHLIGHT_RED_UNDERLINE "\x1B[0;1;4;31m"
#define ANSI_HIGHLIGHT_GREEN_UNDERLINE "\x1B[0;1;4;32m"
#define ANSI_HIGHLIGHT_YELLOW_UNDERLINE "\x1B[0;1;4;38;5;185m"
@ -138,6 +139,7 @@ DEFINE_ANSI_FUNC(highlight_grey, HIGHLIGHT_GREY);
DEFINE_ANSI_FUNC_UNDERLINE(underline, UNDERLINE, NORMAL);
DEFINE_ANSI_FUNC_UNDERLINE(highlight_underline, HIGHLIGHT_UNDERLINE, HIGHLIGHT);
DEFINE_ANSI_FUNC_UNDERLINE(grey_underline, GREY_UNDERLINE, GREY);
DEFINE_ANSI_FUNC_UNDERLINE(highlight_red_underline, HIGHLIGHT_RED_UNDERLINE, HIGHLIGHT_RED);
DEFINE_ANSI_FUNC_UNDERLINE(highlight_green_underline, HIGHLIGHT_GREEN_UNDERLINE, HIGHLIGHT_GREEN);
DEFINE_ANSI_FUNC_UNDERLINE(highlight_yellow_underline, HIGHLIGHT_YELLOW_UNDERLINE, HIGHLIGHT_YELLOW);

View File

@ -1133,7 +1133,6 @@ const UnitVTable automount_vtable = {
.reset_failed = automount_reset_failed,
.bus_vtable = bus_automount_vtable,
.bus_set_property = bus_automount_set_property,
.shutdown = automount_shutdown,

View File

@ -140,6 +140,58 @@ const sd_bus_vtable bus_job_vtable[] = {
SD_BUS_VTABLE_END
};
static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
Manager *m = userdata;
Job *j;
int r;
assert(bus);
assert(path);
assert(interface);
assert(found);
assert(m);
r = manager_get_job_from_dbus_path(m, path, &j);
if (r < 0)
return 0;
*found = j;
return 1;
}
static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
Manager *m = userdata;
unsigned k = 0;
Iterator i;
Job *j;
l = new0(char*, hashmap_size(m->jobs)+1);
if (!l)
return -ENOMEM;
HASHMAP_FOREACH(j, m->jobs, i) {
l[k] = job_dbus_path(j);
if (!l[k])
return -ENOMEM;
k++;
}
assert(hashmap_size(m->jobs) == k);
*nodes = TAKE_PTR(l);
return k;
}
const BusObjectImplementation job_object = {
"/org/freedesktop/systemd1/job",
"org.freedesktop.systemd1.Job",
.fallback_vtables = BUS_FALLBACK_VTABLES({bus_job_vtable, bus_job_find}),
.node_enumerator = bus_job_enumerate,
};
static int send_new_signal(sd_bus *bus, void *userdata) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
_cleanup_free_ char *p = NULL;

View File

@ -2,11 +2,12 @@
#pragma once
#include "sd-bus.h"
#include "sd-bus-vtable.h"
#include "unit.h"
#include "bus-util.h"
extern const sd_bus_vtable bus_job_vtable[];
extern const BusObjectImplementation job_object;
int bus_job_method_cancel(sd_bus_message *message, void *job, sd_bus_error *error);
int bus_job_method_get_waiting_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error);

View File

@ -2,7 +2,6 @@
#pragma once
#include "sd-bus.h"
#include "sd-bus-vtable.h"
#include "unit.h"

View File

@ -274,25 +274,6 @@ static int mac_selinux_filter(sd_bus_message *message, void *userdata, sd_bus_er
}
#endif
static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
Manager *m = userdata;
Job *j;
int r;
assert(bus);
assert(path);
assert(interface);
assert(found);
assert(m);
r = manager_get_job_from_dbus_path(m, path, &j);
if (r < 0)
return 0;
*found = j;
return 1;
}
static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
Unit *u = NULL; /* just to appease gcc, initialization is not really necessary */
int r;
@ -472,32 +453,6 @@ static int bus_kill_context_find(sd_bus *bus, const char *path, const char *inte
return 1;
}
static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
Manager *m = userdata;
unsigned k = 0;
Iterator i;
Job *j;
l = new0(char*, hashmap_size(m->jobs)+1);
if (!l)
return -ENOMEM;
HASHMAP_FOREACH(j, m->jobs, i) {
l[k] = job_dbus_path(j);
if (!l[k])
return -ENOMEM;
k++;
}
assert(hashmap_size(m->jobs) == k);
*nodes = TAKE_PTR(l);
return k;
}
static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
Manager *m = userdata;
@ -522,8 +477,147 @@ static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, cha
return k;
}
static const BusObjectImplementation unit_object = {
"/org/freedesktop/systemd1/unit",
"org.freedesktop.systemd1.Unit",
.fallback_vtables = BUS_FALLBACK_VTABLES(
{ bus_unit_vtable, bus_unit_find }),
.node_enumerator = bus_unit_enumerate,
};
static const BusObjectImplementation bus_automount_object = {
"/org/freedesktop/systemd1/unit",
"org.freedesktop.systemd1.Automount",
.fallback_vtables = BUS_FALLBACK_VTABLES(
{ bus_automount_vtable, bus_unit_interface_find }),
};
static const BusObjectImplementation bus_device_object = {
"/org/freedesktop/systemd1/unit",
"org.freedesktop.systemd1.Device",
.fallback_vtables = BUS_FALLBACK_VTABLES(
{ bus_device_vtable, bus_unit_interface_find }),
};
static const BusObjectImplementation bus_mount_object = {
"/org/freedesktop/systemd1/unit",
"org.freedesktop.systemd1.Mount",
.fallback_vtables = BUS_FALLBACK_VTABLES(
{ bus_mount_vtable, bus_unit_interface_find },
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
{ bus_cgroup_vtable, bus_cgroup_context_find },
{ bus_exec_vtable, bus_exec_context_find },
{ bus_kill_vtable, bus_kill_context_find }),
};
static const BusObjectImplementation bus_path_object = {
"/org/freedesktop/systemd1/unit",
"org.freedesktop.systemd1.Path",
.fallback_vtables = BUS_FALLBACK_VTABLES(
{ bus_path_vtable, bus_unit_interface_find }),
};
static const BusObjectImplementation bus_scope_object = {
"/org/freedesktop/systemd1/unit",
"org.freedesktop.systemd1.Scope",
.fallback_vtables = BUS_FALLBACK_VTABLES(
{ bus_scope_vtable, bus_unit_interface_find },
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
{ bus_cgroup_vtable, bus_cgroup_context_find },
{ bus_kill_vtable, bus_kill_context_find }),
};
static const BusObjectImplementation bus_service_object = {
"/org/freedesktop/systemd1/unit",
"org.freedesktop.systemd1.Service",
.fallback_vtables = BUS_FALLBACK_VTABLES(
{ bus_service_vtable, bus_unit_interface_find },
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
{ bus_cgroup_vtable, bus_cgroup_context_find },
{ bus_exec_vtable, bus_exec_context_find },
{ bus_kill_vtable, bus_kill_context_find }),
};
static const BusObjectImplementation bus_slice_object = {
"/org/freedesktop/systemd1/unit",
"org.freedesktop.systemd1.Slice",
.fallback_vtables = BUS_FALLBACK_VTABLES(
{ bus_slice_vtable, bus_unit_interface_find },
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
{ bus_cgroup_vtable, bus_cgroup_context_find }),
};
static const BusObjectImplementation bus_socket_object = {
"/org/freedesktop/systemd1/unit",
"org.freedesktop.systemd1.Socket",
.fallback_vtables = BUS_FALLBACK_VTABLES(
{ bus_socket_vtable, bus_unit_interface_find },
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
{ bus_cgroup_vtable, bus_cgroup_context_find },
{ bus_exec_vtable, bus_exec_context_find },
{ bus_kill_vtable, bus_kill_context_find }),
};
static const BusObjectImplementation bus_swap_object = {
"/org/freedesktop/systemd1/unit",
"org.freedesktop.systemd1.Swap",
.fallback_vtables = BUS_FALLBACK_VTABLES(
{ bus_swap_vtable, bus_unit_interface_find },
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
{ bus_cgroup_vtable, bus_cgroup_context_find },
{ bus_exec_vtable, bus_exec_context_find },
{ bus_kill_vtable, bus_kill_context_find }),
};
static const BusObjectImplementation bus_target_object = {
"/org/freedesktop/systemd1/unit",
"org.freedesktop.systemd1.Target",
.fallback_vtables = BUS_FALLBACK_VTABLES(
{ bus_target_vtable, bus_unit_interface_find }),
};
static const BusObjectImplementation bus_timer_object = {
"/org/freedesktop/systemd1/unit",
"org.freedesktop.systemd1.Timer",
.fallback_vtables = BUS_FALLBACK_VTABLES(
{ bus_timer_vtable, bus_unit_interface_find }),
};
static const BusObjectImplementation bus_manager_object = {
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
.vtables = BUS_VTABLES(bus_manager_vtable),
.children = BUS_IMPLEMENTATIONS(
&job_object,
&unit_object,
&bus_automount_object,
&bus_device_object,
&bus_mount_object,
&bus_path_object,
&bus_scope_object,
&bus_service_object,
&bus_slice_object,
&bus_socket_object,
&bus_swap_object,
&bus_target_object,
&bus_timer_object),
};
static const BusObjectImplementation manager_log_control_object = {
"/org/freedesktop/LogControl1",
"org.freedesktop.LogControl1",
.vtables = BUS_VTABLES(bus_manager_log_control_vtable),
};
int bus_manager_introspect_implementations(FILE *out, const char *pattern) {
return bus_introspect_implementations(
out,
pattern,
BUS_IMPLEMENTATIONS(&bus_manager_object,
&manager_log_control_object));
}
static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
UnitType t;
int r;
assert(m);
@ -535,63 +629,11 @@ static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
return log_error_errno(r, "Failed to add SELinux access filter: %m");
#endif
r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
r = bus_add_implementation(bus, &bus_manager_object, m);
if (r < 0)
return log_error_errno(r, "Failed to register Manager vtable: %m");
return r;
r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/LogControl1", "org.freedesktop.LogControl1", bus_manager_log_control_vtable, m);
if (r < 0)
return log_error_errno(r, "Failed to register service API vtable: %m");
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
if (r < 0)
return log_error_errno(r, "Failed to register Job vtable: %m");
r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
if (r < 0)
return log_error_errno(r, "Failed to add job enumerator: %m");
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
if (r < 0)
return log_error_errno(r, "Failed to register Unit vtable: %m");
r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
if (r < 0)
return log_error_errno(r, "Failed to add job enumerator: %m");
for (t = 0; t < _UNIT_TYPE_MAX; t++) {
const char *interface;
assert_se(interface = unit_dbus_interface_from_type(t));
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
if (r < 0)
return log_error_errno(r, "Failed to register type specific vtable for %s: %m", interface);
if (unit_vtable[t]->cgroup_context_offset > 0) {
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
if (r < 0)
return log_error_errno(r, "Failed to register control group unit vtable for %s: %m", interface);
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
if (r < 0)
return log_error_errno(r, "Failed to register control group vtable for %s: %m", interface);
}
if (unit_vtable[t]->exec_context_offset > 0) {
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_exec_vtable, bus_exec_context_find, m);
if (r < 0)
return log_error_errno(r, "Failed to register execute vtable for %s: %m", interface);
}
if (unit_vtable[t]->kill_context_offset > 0) {
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_kill_vtable, bus_kill_context_find, m);
if (r < 0)
return log_error_errno(r, "Failed to register kill vtable for %s: %m", interface);
}
}
return 0;
return bus_add_implementation(bus, &manager_log_control_object, m);
}
static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {

View File

@ -33,3 +33,4 @@ int bus_forward_agent_released(Manager *m, const char *path);
uint64_t manager_bus_n_queued_write(Manager *m);
void dump_bus_properties(FILE *f);
int bus_manager_introspect_implementations(FILE *out, const char *pattern);

View File

@ -1081,8 +1081,6 @@ const UnitVTable device_vtable = {
.active_state = device_active_state,
.sub_state_to_string = device_sub_state_to_string,
.bus_vtable = bus_device_vtable,
.following = device_following,
.following_set = device_following_set,

View File

@ -93,8 +93,11 @@ static enum {
ACTION_TEST,
ACTION_DUMP_CONFIGURATION_ITEMS,
ACTION_DUMP_BUS_PROPERTIES,
ACTION_BUS_INTROSPECT,
} arg_action = ACTION_RUN;
static const char *arg_bus_introspect = NULL;
/* Those variables are initialized to 0 automatically, so we avoid uninitialized memory access.
* Real defaults are assigned in reset_arguments() below. */
static char *arg_default_unit;
@ -729,6 +732,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_VERSION,
ARG_DUMP_CONFIGURATION_ITEMS,
ARG_DUMP_BUS_PROPERTIES,
ARG_BUS_INTROSPECT,
ARG_DUMP_CORE,
ARG_CRASH_CHVT,
ARG_CRASH_SHELL,
@ -758,6 +762,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "version", no_argument, NULL, ARG_VERSION },
{ "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS },
{ "dump-bus-properties", no_argument, NULL, ARG_DUMP_BUS_PROPERTIES },
{ "bus-introspect", required_argument, NULL, ARG_BUS_INTROSPECT },
{ "dump-core", optional_argument, NULL, ARG_DUMP_CORE },
{ "crash-chvt", required_argument, NULL, ARG_CRASH_CHVT },
{ "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL },
@ -885,6 +890,11 @@ static int parse_argv(int argc, char *argv[]) {
arg_action = ACTION_DUMP_BUS_PROPERTIES;
break;
case ARG_BUS_INTROSPECT:
arg_bus_introspect = optarg;
arg_action = ACTION_BUS_INTROSPECT;
break;
case ARG_DUMP_CORE:
if (!optarg)
arg_dump_core = true;
@ -1033,7 +1043,9 @@ static int help(void) {
return log_oom();
printf("%s [OPTIONS...]\n\n"
"Starts up and maintains the system or user services.\n\n"
"%sStarts and monitors system and user services.%s\n\n"
"This program takes no positional arguments.\n\n"
"%sOptions%s:\n"
" -h --help Show this help\n"
" --version Show version\n"
" --test Determine initial transaction, dump it and exit\n"
@ -1042,6 +1054,7 @@ static int help(void) {
" --no-pager Do not pipe output into a pager\n"
" --dump-configuration-items Dump understood unit configuration items\n"
" --dump-bus-properties Dump exposed bus properties\n"
" --bus-introspect=PATH Write XML introspection data\n"
" --unit=UNIT Set default unit\n"
" --dump-core[=BOOL] Dump core on crash\n"
" --crash-vt=NR Change to specified VT on crash\n"
@ -1058,6 +1071,8 @@ static int help(void) {
" --default-standard-error= Set default standard error output for services\n"
"\nSee the %s for details.\n"
, program_invocation_short_name
, ansi_highlight(), ansi_normal()
, ansi_underline(), ansi_normal()
, link
);
@ -2611,7 +2626,7 @@ int main(int argc, char *argv[]) {
if (r < 0)
goto finish;
if (IN_SET(arg_action, ACTION_TEST, ACTION_HELP, ACTION_DUMP_CONFIGURATION_ITEMS, ACTION_DUMP_BUS_PROPERTIES))
if (IN_SET(arg_action, ACTION_TEST, ACTION_HELP, ACTION_DUMP_CONFIGURATION_ITEMS, ACTION_DUMP_BUS_PROPERTIES, ACTION_BUS_INTROSPECT))
(void) pager_open(arg_pager_flags);
if (arg_action != ACTION_RUN)
@ -2631,6 +2646,10 @@ int main(int argc, char *argv[]) {
dump_bus_properties(stdout);
retval = EXIT_SUCCESS;
goto finish;
} else if (arg_action == ACTION_BUS_INTROSPECT) {
r = bus_manager_introspect_implementations(stdout, arg_bus_introspect);
retval = r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
goto finish;
}
assert_se(IN_SET(arg_action, ACTION_RUN, ACTION_TEST));

View File

@ -2110,7 +2110,6 @@ const UnitVTable mount_vtable = {
.control_pid = mount_control_pid,
.bus_vtable = bus_mount_vtable,
.bus_set_property = bus_mount_set_property,
.bus_commit_properties = bus_mount_commit_properties,

View File

@ -830,6 +830,5 @@ const UnitVTable path_vtable = {
.reset_failed = path_reset_failed,
.bus_vtable = bus_path_vtable,
.bus_set_property = bus_path_set_property,
};

View File

@ -652,7 +652,6 @@ const UnitVTable scope_vtable = {
.notify_cgroup_empty = scope_notify_cgroup_empty_event,
.bus_vtable = bus_scope_vtable,
.bus_set_property = bus_scope_set_property,
.bus_commit_properties = bus_scope_commit_properties,

View File

@ -4484,7 +4484,6 @@ const UnitVTable service_vtable = {
.bus_name_owner_change = service_bus_name_owner_change,
.bus_vtable = bus_service_vtable,
.bus_set_property = bus_service_set_property,
.bus_commit_properties = bus_service_commit_properties,

View File

@ -458,7 +458,6 @@ const UnitVTable slice_vtable = {
.active_state = slice_active_state,
.sub_state_to_string = slice_sub_state_to_string,
.bus_vtable = bus_slice_vtable,
.bus_set_property = bus_slice_set_property,
.bus_commit_properties = bus_slice_commit_properties,

View File

@ -3462,7 +3462,6 @@ const UnitVTable socket_vtable = {
.control_pid = socket_control_pid,
.bus_vtable = bus_socket_vtable,
.bus_set_property = bus_socket_set_property,
.bus_commit_properties = bus_socket_commit_properties,

View File

@ -1655,7 +1655,6 @@ const UnitVTable swap_vtable = {
.control_pid = swap_control_pid,
.bus_vtable = bus_swap_vtable,
.bus_set_property = bus_swap_set_property,
.bus_commit_properties = bus_swap_commit_properties,

View File

@ -207,8 +207,6 @@ const UnitVTable target_vtable = {
.active_state = target_active_state,
.sub_state_to_string = target_sub_state_to_string,
.bus_vtable = bus_target_vtable,
.status_message_formats = {
.finished_start_job = {
[JOB_DONE] = "Reached target %s.",

View File

@ -925,6 +925,5 @@ const UnitVTable timer_vtable = {
.time_change = timer_time_change,
.timezone_change = timer_timezone_change,
.bus_vtable = bus_timer_vtable,
.bus_set_property = bus_timer_set_property,
};

View File

@ -600,9 +600,6 @@ typedef struct UnitVTable {
* of this type will immediately fail. */
bool (*supported)(void);
/* The bus vtable */
const sd_bus_vtable *bus_vtable;
/* The strings to print in status messages */
UnitStatusMessageFormats status_message_formats;

View File

@ -712,38 +712,13 @@ int bus_home_method_release(
/* We map a uid_t as uint32_t bus property, let's ensure this is safe. */
assert_cc(sizeof(uid_t) == sizeof(uint32_t));
const sd_bus_vtable home_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("UserName", "s", NULL, offsetof(Home, user_name), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("UID", "u", NULL, offsetof(Home, uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("UnixRecord", "(suusss)", property_get_unix_record, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
SD_BUS_PROPERTY("UserRecord", "(sb)", property_get_user_record, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Activate", "s", NULL, bus_home_method_activate, SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Deactivate", NULL, NULL, bus_home_method_deactivate, 0),
SD_BUS_METHOD("Unregister", NULL, NULL, bus_home_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Realize", "s", NULL, bus_home_method_realize, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Remove", NULL, NULL, bus_home_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Fixate", "s", NULL, bus_home_method_fixate, SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Authenticate", "s", NULL, bus_home_method_authenticate, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Update", "s", NULL, bus_home_method_update, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Resize", "ts", NULL, bus_home_method_resize, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("ChangePassword", "ss", NULL, bus_home_method_change_password, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Lock", NULL, NULL, bus_home_method_lock, 0),
SD_BUS_METHOD("Unlock", "s", NULL, bus_home_method_unlock, SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Acquire", "sb", "h", bus_home_method_acquire, SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Ref", "b", "h", bus_home_method_ref, 0),
SD_BUS_METHOD("Release", NULL, NULL, bus_home_method_release, 0),
SD_BUS_VTABLE_END
};
int bus_home_path(Home *h, char **ret) {
assert(ret);
return sd_bus_path_encode("/org/freedesktop/home1/home", h->user_name, ret);
}
int bus_home_object_find(
static int bus_home_object_find(
sd_bus *bus,
const char *path,
const char *interface,
@ -772,7 +747,7 @@ int bus_home_object_find(
return 1;
}
int bus_home_node_enumerator(
static int bus_home_node_enumerator(
sd_bus *bus,
const char *path,
void *userdata,
@ -802,6 +777,107 @@ int bus_home_node_enumerator(
return 1;
}
const sd_bus_vtable home_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("UserName", "s",
NULL, offsetof(Home, user_name),
SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("UID", "u",
NULL, offsetof(Home, uid),
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("UnixRecord", "(suusss)",
property_get_unix_record, 0,
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("State", "s",
property_get_state, 0,
0),
SD_BUS_PROPERTY("UserRecord", "(sb)",
property_get_user_record, 0,
SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("Activate",
"s",
SD_BUS_PARAM(user_record),
NULL,,
bus_home_method_activate,
SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Deactivate", NULL, NULL, bus_home_method_deactivate, 0),
SD_BUS_METHOD("Unregister", NULL, NULL, bus_home_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("Realize",
"s",
SD_BUS_PARAM(user_record),
NULL,,
bus_home_method_realize,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Remove", NULL, NULL, bus_home_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("Fixate",
"s",
SD_BUS_PARAM(user_record),
NULL,,
bus_home_method_fixate,
SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("Authenticate",
"s",
SD_BUS_PARAM(user_record),
NULL,,
bus_home_method_authenticate,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("Update",
"s",
SD_BUS_PARAM(user_record),
NULL,,
bus_home_method_update,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("Resize",
"ts",
SD_BUS_PARAM(size)
SD_BUS_PARAM(user_record),
NULL,,
bus_home_method_resize,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("ChangePassword",
"ss",
SD_BUS_PARAM(new_user_record)
SD_BUS_PARAM(old_user_record),
NULL,,
bus_home_method_change_password,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Lock", NULL, NULL, bus_home_method_lock, 0),
SD_BUS_METHOD_WITH_NAMES("Unlock",
"s",
SD_BUS_PARAM(user_record),
NULL,,
bus_home_method_unlock,
SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("Acquire",
"sb",
SD_BUS_PARAM(user_record)
SD_BUS_PARAM(please_suspend),
"h",
SD_BUS_PARAM(send_fd),
bus_home_method_acquire,
SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("Ref",
"b",
SD_BUS_PARAM(please_suspend),
"h",
SD_BUS_PARAM(send_fd),
bus_home_method_ref,
0),
SD_BUS_METHOD("Release", NULL, NULL, bus_home_method_release, 0),
SD_BUS_VTABLE_END
};
const BusObjectImplementation home_object = {
"/org/freedesktop/home1/home",
"org.freedesktop.home1.Home",
.fallback_vtables = BUS_FALLBACK_VTABLES({home_vtable, bus_home_object_find}),
.node_enumerator = bus_home_node_enumerator,
.manager = true,
};
static int on_deferred_change(sd_event_source *s, void *userdata) {
_cleanup_free_ char *path = NULL;
Home *h = userdata;

View File

@ -3,6 +3,7 @@
#include "sd-bus.h"
#include "bus-util.h"
#include "homed-home.h"
int bus_home_client_is_trusted(Home *h, sd_bus_message *message);
@ -25,12 +26,9 @@ int bus_home_method_acquire(sd_bus_message *message, void *userdata, sd_bus_erro
int bus_home_method_ref(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_home_method_release(sd_bus_message *message, void *userdata, sd_bus_error *error);
extern const sd_bus_vtable home_vtable[];
extern const BusObjectImplementation home_object;
int bus_home_path(Home *h, char **ret);
int bus_home_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
int bus_home_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
int bus_home_emit_change(Home *h);
int bus_home_emit_remove(Home *h);

View File

@ -600,44 +600,210 @@ static int method_lock_all_homes(sd_bus_message *message, void *userdata, sd_bus
return sd_bus_reply_method_return(message, NULL);
}
const sd_bus_vtable manager_vtable[] = {
static const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("AutoLogin", "a(sso)", property_get_auto_login, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_METHOD("GetHomeByName", "s", "usussso", method_get_home_by_name, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetHomeByUID", "u", "ssussso", method_get_home_by_uid, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetUserRecordByName", "s", "sbo", method_get_user_record_by_name, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("GetUserRecordByUID", "u", "sbo", method_get_user_record_by_uid, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("ListHomes", NULL, "a(susussso)", method_list_homes, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("GetHomeByName",
"s",
SD_BUS_PARAM(user_name),
"usussso",
SD_BUS_PARAM(uid)
SD_BUS_PARAM(home_state)
SD_BUS_PARAM(gid)
SD_BUS_PARAM(real_name)
SD_BUS_PARAM(home_directory)
SD_BUS_PARAM(shell)
SD_BUS_PARAM(bus_path),
method_get_home_by_name,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("GetHomeByUID",
"u",
SD_BUS_PARAM(uid),
"ssussso",
SD_BUS_PARAM(user_name)
SD_BUS_PARAM(home_state)
SD_BUS_PARAM(gid)
SD_BUS_PARAM(real_name)
SD_BUS_PARAM(home_directory)
SD_BUS_PARAM(shell)
SD_BUS_PARAM(bus_path),
method_get_home_by_uid,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("GetUserRecordByName",
"s",
SD_BUS_PARAM(user_name),
"sbo",
SD_BUS_PARAM(user_record)
SD_BUS_PARAM(incomplete)
SD_BUS_PARAM(bus_path),
method_get_user_record_by_name,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("GetUserRecordByUID",
"u",
SD_BUS_PARAM(uid),
"sbo",
SD_BUS_PARAM(user_record)
SD_BUS_PARAM(incomplete)
SD_BUS_PARAM(bus_path),
method_get_user_record_by_uid,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("ListHomes",
NULL,,
"a(susussso)",
SD_BUS_PARAM(home_areas),
method_list_homes,
SD_BUS_VTABLE_UNPRIVILEGED),
/* The following methods directly execute an operation on a home area, without ref-counting, queueing
* or anything, and are accessible through homectl. */
SD_BUS_METHOD("ActivateHome", "ss", NULL, method_activate_home, SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("DeactivateHome", "s", NULL, method_deactivate_home, 0),
SD_BUS_METHOD("RegisterHome", "s", NULL, method_register_home, SD_BUS_VTABLE_UNPRIVILEGED), /* Add JSON record to homed, but don't create actual $HOME */
SD_BUS_METHOD("UnregisterHome", "s", NULL, method_unregister_home, SD_BUS_VTABLE_UNPRIVILEGED), /* Remove JSON record from homed, but don't remove actual $HOME */
SD_BUS_METHOD("CreateHome", "s", NULL, method_create_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Add JSON record, and create $HOME for it */
SD_BUS_METHOD("RealizeHome", "ss", NULL, method_realize_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Create $HOME for already registered JSON entry */
SD_BUS_METHOD("RemoveHome", "s", NULL, method_remove_home, SD_BUS_VTABLE_UNPRIVILEGED), /* Remove JSON record and remove $HOME */
SD_BUS_METHOD("FixateHome", "ss", NULL, method_fixate_home, SD_BUS_VTABLE_SENSITIVE), /* Investigate $HOME and propagate contained JSON record into our database */
SD_BUS_METHOD("AuthenticateHome", "ss", NULL, method_authenticate_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Just check credentials */
SD_BUS_METHOD("UpdateHome", "s", NULL, method_update_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Update JSON record of existing user */
SD_BUS_METHOD("ResizeHome", "sts", NULL, method_resize_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("ChangePasswordHome", "sss", NULL, method_change_password_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("LockHome", "s", NULL, method_lock_home, 0), /* Prepare active home for system suspend: flush out passwords, suspend access */
SD_BUS_METHOD("UnlockHome", "ss", NULL, method_unlock_home, SD_BUS_VTABLE_SENSITIVE), /* Make $HOME usable after system resume again */
SD_BUS_METHOD_WITH_NAMES("ActivateHome",
"ss",
SD_BUS_PARAM(user_name)
SD_BUS_PARAM(user_record),
NULL,,
method_activate_home,
SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("DeactivateHome",
"s",
SD_BUS_PARAM(user_name),
NULL,,
method_deactivate_home,
0),
/* The following methods implement ref-counted activation, and are what the PAM module calls (and
* what "homectl with" runs). In contrast to the methods above which fail if an operation is already
* being executed on a home directory, these ones will queue the request, and are thus more
* reliable. Moreover, they are a bit smarter: AcquireHome() will fixate, activate, unlock, or
* authenticate depending on the state of the home, so that the end result is always the same
* (i.e. the home directory is accessible), and we always validate the specified passwords. RefHome()
* will not authenticate, and thus only works if home is already active. */
SD_BUS_METHOD("AcquireHome", "ssb", "h", method_acquire_home, SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("RefHome", "sb", "h", method_ref_home, 0),
SD_BUS_METHOD("ReleaseHome", "s", NULL, method_release_home, 0),
/* Add the JSON record to homed, but don't create actual $HOME */
SD_BUS_METHOD_WITH_NAMES("RegisterHome",
"s",
SD_BUS_PARAM(home_record),
NULL,,
method_register_home,
SD_BUS_VTABLE_UNPRIVILEGED),
/* Remove the JSON record from homed, but don't remove actual $HOME */
SD_BUS_METHOD_WITH_NAMES("UnregisterHome",
"s",
SD_BUS_PARAM(user_name),
NULL,,
method_unregister_home,
SD_BUS_VTABLE_UNPRIVILEGED),
/* Add JSON record, and create $HOME for it */
SD_BUS_METHOD_WITH_NAMES("CreateHome",
"s",
SD_BUS_PARAM(home_record),
NULL,,
method_create_home,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
/* Create $HOME for already registered JSON entry */
SD_BUS_METHOD_WITH_NAMES("RealizeHome",
"ss",
SD_BUS_PARAM(user_name)
SD_BUS_PARAM(user_record),
NULL,,
method_realize_home,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
/* Remove the JSON record and remove $HOME */
SD_BUS_METHOD_WITH_NAMES("RemoveHome",
"s",
SD_BUS_PARAM(user_name),
NULL,,
method_remove_home,
SD_BUS_VTABLE_UNPRIVILEGED),
/* Investigate $HOME and propagate contained JSON record into our database */
SD_BUS_METHOD_WITH_NAMES("FixateHome",
"ss",
SD_BUS_PARAM(user_name)
SD_BUS_PARAM(user_record),
NULL,,
method_fixate_home,
SD_BUS_VTABLE_SENSITIVE),
/* Just check credentials */
SD_BUS_METHOD_WITH_NAMES("AuthenticateHome",
"ss",
SD_BUS_PARAM(user_name)
SD_BUS_PARAM(user_record),
NULL,,
method_authenticate_home,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
/* Update the JSON record of existing user */
SD_BUS_METHOD_WITH_NAMES("UpdateHome",
"s",
SD_BUS_PARAM(user_record),
NULL,,
method_update_home,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("ResizeHome",
"sts",
SD_BUS_PARAM(user_name)
SD_BUS_PARAM(size)
SD_BUS_PARAM(user_record),
NULL,,
method_resize_home,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("ChangePasswordHome",
"sss",
SD_BUS_PARAM(user_name)
SD_BUS_PARAM(new_user_record)
SD_BUS_PARAM(old_user_record),
NULL,,
method_change_password_home,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
/* Prepare active home for system suspend: flush out passwords, suspend access */
SD_BUS_METHOD_WITH_NAMES("LockHome",
"s",
SD_BUS_PARAM(user_name),
NULL,,
method_lock_home,
0),
/* Make $HOME usable after system resume again */
SD_BUS_METHOD_WITH_NAMES("UnlockHome",
"ss",
SD_BUS_PARAM(user_name)
SD_BUS_PARAM(user_record),
NULL,,
method_unlock_home,
SD_BUS_VTABLE_SENSITIVE),
/* The following methods implement ref-counted activation, and are what the PAM module and "homectl
* with" use. In contrast to the methods above which fail if an operation is already being executed
* on a home directory, these ones will queue the request, and are thus more reliable. Moreover,
* they are a bit smarter: AcquireHome() will fixate, activate, unlock, or authenticate depending on
* the state of the home area, so that the end result is always the same (i.e. the home directory is
* accessible), and we always validate the specified passwords. RefHome() will not authenticate, and
* thus only works if the home area is already active. */
SD_BUS_METHOD_WITH_NAMES("AcquireHome",
"ssb",
SD_BUS_PARAM(user_name)
SD_BUS_PARAM(user_record)
SD_BUS_PARAM(please_suspend),
"h",
SD_BUS_PARAM(send_fd),
method_acquire_home,
SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("RefHome",
"sb",
SD_BUS_PARAM(user_name)
SD_BUS_PARAM(please_suspend),
"h",
SD_BUS_PARAM(send_fd),
method_ref_home,
0),
SD_BUS_METHOD_WITH_NAMES("ReleaseHome",
"s",
SD_BUS_PARAM(user_name),
NULL,,
method_release_home,
0),
/* An operation that acts on all homes that allow it */
SD_BUS_METHOD("LockAllHomes", NULL, NULL, method_lock_all_homes, 0),
@ -645,6 +811,13 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_END
};
const BusObjectImplementation manager_object = {
"/org/freedesktop/home1",
"org.freedesktop.home1.Manager",
.vtables = BUS_VTABLES(manager_vtable),
.children = BUS_IMPLEMENTATIONS(&home_object),
};
static int on_deferred_auto_login(sd_event_source *s, void *userdata) {
Manager *m = userdata;
int r;

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "sd-bus.h"
#include "bus-util.h"
extern const sd_bus_vtable manager_vtable[];
extern const BusObjectImplementation manager_object;

View File

@ -879,23 +879,7 @@ static int manager_connect_bus(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to connect to system bus: %m");
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/home1", "org.freedesktop.home1.Manager", manager_vtable, m);
if (r < 0)
return log_error_errno(r, "Failed to add manager object vtable: %m");
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/home1/home", "org.freedesktop.home1.Home", home_vtable, bus_home_object_find, m);
if (r < 0)
return log_error_errno(r, "Failed to add image object vtable: %m");
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/home1/home", bus_home_node_enumerator, m);
if (r < 0)
return log_error_errno(r, "Failed to add image enumerator: %m");
r = sd_bus_add_object_manager(m->bus, NULL, "/org/freedesktop/home1/home");
if (r < 0)
return log_error_errno(r, "Failed to add object manager: %m");
r = bus_log_control_api_register(m->bus);
r = bus_add_implementation(m->bus, &manager_object, m);
if (r < 0)
return r;

View File

@ -3,10 +3,13 @@
#include <sys/stat.h>
#include <sys/types.h>
#include "bus-log-control-api.h"
#include "daemon-util.h"
#include "homed-manager.h"
#include "homed-manager-bus.h"
#include "log.h"
#include "main-func.h"
#include "service-util.h"
#include "signal-util.h"
static int run(int argc, char *argv[]) {
@ -16,10 +19,15 @@ static int run(int argc, char *argv[]) {
log_setup_service();
umask(0022);
r = service_parse_argv("systemd-homed.service",
"A service to create, remove, change or inspect home areas.",
BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object),
argc, argv);
if (r <= 0)
return r;
if (argc != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
umask(0022);
if (setenv("SYSTEMD_BYPASS_USERDB", "io.systemd.Home", 1) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set $SYSTEMD_BYPASS_USERDB: %m");

View File

@ -26,6 +26,7 @@
#include "parse-util.h"
#include "path-util.h"
#include "selinux-util.h"
#include "service-util.h"
#include "signal-util.h"
#include "strv.h"
#include "user-util.h"
@ -739,6 +740,12 @@ static const sd_bus_vtable hostname_vtable[] = {
SD_BUS_VTABLE_END,
};
static const BusObjectImplementation manager_object = {
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
.vtables = BUS_VTABLES(hostname_vtable),
};
static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
int r;
@ -751,9 +758,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
if (r < 0)
return log_error_errno(r, "Failed to get system bus connection: %m");
r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/hostname1", "org.freedesktop.hostname1", hostname_vtable, c);
r = bus_add_implementation(bus, &manager_object, c);
if (r < 0)
return log_error_errno(r, "Failed to register object: %m");
return r;
r = bus_log_control_api_register(bus);
if (r < 0)
@ -780,14 +787,17 @@ static int run(int argc, char *argv[]) {
log_setup_service();
r = service_parse_argv("systemd-hostnamed.service",
"Manage the system hostname and related metadata.",
BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object),
argc, argv);
if (r <= 0)
return r;
umask(0022);
mac_selinux_init();
if (argc != 1) {
log_error("This program takes no arguments.");
return -EINVAL;
}
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
r = sd_event_default(&event);

View File

@ -8,6 +8,7 @@
#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-log-control-api.h"
#include "bus-util.h"
#include "bus-polkit.h"
#include "def.h"
#include "fd-util.h"
@ -22,6 +23,7 @@
#include "path-util.h"
#include "process-util.h"
#include "signal-util.h"
#include "service-util.h"
#include "socket-util.h"
#include "stat-util.h"
#include "string-table.h"
@ -488,11 +490,13 @@ static int transfer_start(Transfer *t) {
t->stdin_fd = safe_close(t->stdin_fd);
r = sd_event_add_child(t->manager->event, &t->pid_event_source, t->pid, WEXITED, transfer_on_pid, t);
r = sd_event_add_child(t->manager->event, &t->pid_event_source,
t->pid, WEXITED, transfer_on_pid, t);
if (r < 0)
return r;
r = sd_event_add_io(t->manager->event, &t->log_event_source, t->log_fd, EPOLLIN, transfer_on_log, t);
r = sd_event_add_io(t->manager->event, &t->log_event_source,
t->log_fd, EPOLLIN, transfer_on_log, t);
if (r < 0)
return r;
@ -657,7 +661,8 @@ static int manager_new(Manager **ret) {
if (r < 0)
return r;
r = sd_event_add_io(m->event, &m->notify_event_source, m->notify_fd, EPOLLIN, manager_on_notify, m);
r = sd_event_add_io(m->event, &m->notify_event_source,
m->notify_fd, EPOLLIN, manager_on_notify, m);
if (r < 0)
return r;
@ -718,13 +723,15 @@ static int method_import_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
return -EINVAL;
if (!machine_name_is_valid(local))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Local name %s is invalid", local);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Local name %s is invalid", local);
r = setup_machine_directory(error);
if (r < 0)
return r;
type = streq_ptr(sd_bus_message_get_member(msg), "ImportTar") ? TRANSFER_IMPORT_TAR : TRANSFER_IMPORT_RAW;
type = streq_ptr(sd_bus_message_get_member(msg), "ImportTar") ?
TRANSFER_IMPORT_TAR : TRANSFER_IMPORT_RAW;
r = transfer_new(m, &t);
if (r < 0)
@ -786,7 +793,8 @@ static int method_import_fs(sd_bus_message *msg, void *userdata, sd_bus_error *e
return r;
if (!machine_name_is_valid(local))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Local name %s is invalid", local);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Local name %s is invalid", local);
r = setup_machine_directory(error);
if (r < 0)
@ -850,7 +858,8 @@ static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
return r;
if (!machine_name_is_valid(local))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Local name %s is invalid", local);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Local name %s is invalid", local);
if (fstat(fd, &st) < 0)
return -errno;
@ -858,7 +867,8 @@ static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
if (!S_ISREG(st.st_mode) && !S_ISFIFO(st.st_mode))
return -EINVAL;
type = streq_ptr(sd_bus_message_get_member(msg), "ExportTar") ? TRANSFER_EXPORT_TAR : TRANSFER_EXPORT_RAW;
type = streq_ptr(sd_bus_message_get_member(msg), "ExportTar") ?
TRANSFER_EXPORT_TAR : TRANSFER_EXPORT_RAW;
r = transfer_new(m, &t);
if (r < 0)
@ -922,28 +932,33 @@ static int method_pull_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_er
return r;
if (!http_url_is_valid(remote))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "URL %s is invalid", remote);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"URL %s is invalid", remote);
if (isempty(local))
local = NULL;
else if (!machine_name_is_valid(local))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Local name %s is invalid", local);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Local name %s is invalid", local);
if (isempty(verify))
v = IMPORT_VERIFY_SIGNATURE;
else
v = import_verify_from_string(verify);
if (v < 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown verification mode %s", verify);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Unknown verification mode %s", verify);
r = setup_machine_directory(error);
if (r < 0)
return r;
type = streq_ptr(sd_bus_message_get_member(msg), "PullTar") ? TRANSFER_PULL_TAR : TRANSFER_PULL_RAW;
type = streq_ptr(sd_bus_message_get_member(msg), "PullTar") ?
TRANSFER_PULL_TAR : TRANSFER_PULL_RAW;
if (manager_find(m, type, remote))
return sd_bus_error_setf(error, BUS_ERROR_TRANSFER_IN_PROGRESS, "Transfer for %s already in progress.", remote);
return sd_bus_error_setf(error, BUS_ERROR_TRANSFER_IN_PROGRESS,
"Transfer for %s already in progress.", remote);
r = transfer_new(m, &t);
if (r < 0)
@ -1103,6 +1118,73 @@ static int property_get_progress(
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, transfer_type, TransferType);
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_verify, import_verify, ImportVerify);
static int transfer_object_find(
sd_bus *bus,
const char *path,
const char *interface,
void *userdata,
void **found,
sd_bus_error *error) {
Manager *m = userdata;
Transfer *t;
const char *p;
uint32_t id;
int r;
assert(bus);
assert(path);
assert(interface);
assert(found);
assert(m);
p = startswith(path, "/org/freedesktop/import1/transfer/_");
if (!p)
return 0;
r = safe_atou32(p, &id);
if (r < 0 || id == 0)
return 0;
t = hashmap_get(m->transfers, UINT32_TO_PTR(id));
if (!t)
return 0;
*found = t;
return 1;
}
static int transfer_node_enumerator(
sd_bus *bus,
const char *path,
void *userdata,
char ***nodes,
sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
Manager *m = userdata;
Transfer *t;
unsigned k = 0;
Iterator i;
l = new0(char*, hashmap_size(m->transfers) + 1);
if (!l)
return -ENOMEM;
HASHMAP_FOREACH(t, m->transfers, i) {
l[k] = strdup(t->object_path);
if (!l[k])
return -ENOMEM;
k++;
}
*nodes = TAKE_PTR(l);
return 1;
}
static const sd_bus_vtable transfer_vtable[] = {
SD_BUS_VTABLE_START(0),
@ -1124,6 +1206,13 @@ static const sd_bus_vtable transfer_vtable[] = {
SD_BUS_VTABLE_END,
};
static const BusObjectImplementation transfer_object = {
"/org/freedesktop/import1/transfer",
"org.freedesktop.import1.Transfer",
.fallback_vtables = BUS_FALLBACK_VTABLES({transfer_vtable, transfer_object_find}),
.node_enumerator = transfer_node_enumerator,
};
static const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_START(0),
@ -1230,76 +1319,21 @@ static const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_END,
};
static int transfer_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
Manager *m = userdata;
Transfer *t;
const char *p;
uint32_t id;
int r;
assert(bus);
assert(path);
assert(interface);
assert(found);
assert(m);
p = startswith(path, "/org/freedesktop/import1/transfer/_");
if (!p)
return 0;
r = safe_atou32(p, &id);
if (r < 0 || id == 0)
return 0;
t = hashmap_get(m->transfers, UINT32_TO_PTR(id));
if (!t)
return 0;
*found = t;
return 1;
}
static int transfer_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
Manager *m = userdata;
Transfer *t;
unsigned k = 0;
Iterator i;
l = new0(char*, hashmap_size(m->transfers) + 1);
if (!l)
return -ENOMEM;
HASHMAP_FOREACH(t, m->transfers, i) {
l[k] = strdup(t->object_path);
if (!l[k])
return -ENOMEM;
k++;
}
*nodes = TAKE_PTR(l);
return 1;
}
static const BusObjectImplementation manager_object = {
"/org/freedesktop/import1",
"org.freedesktop.import1.Manager",
.vtables = BUS_VTABLES(manager_vtable),
.children = BUS_IMPLEMENTATIONS(&transfer_object),
};
static int manager_add_bus_objects(Manager *m) {
int r;
assert(m);
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/import1", "org.freedesktop.import1.Manager", manager_vtable, m);
r = bus_add_implementation(m->bus, &manager_object, m);
if (r < 0)
return log_error_errno(r, "Failed to register object: %m");
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/import1/transfer", "org.freedesktop.import1.Transfer", transfer_vtable, transfer_object_find, m);
if (r < 0)
return log_error_errno(r, "Failed to register object: %m");
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/import1/transfer", transfer_node_enumerator, m);
if (r < 0)
return log_error_errno(r, "Failed to add transfer enumerator: %m");
return r;
r = bus_log_control_api_register(m->bus);
if (r < 0)
@ -1340,12 +1374,15 @@ static int run(int argc, char *argv[]) {
log_setup_service();
umask(0022);
r = service_parse_argv("systemd-importd.service",
"VM and container image import and export service.",
BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object),
argc, argv);
if (r <= 0)
return r;
if (argc != 1) {
log_error("This program takes no arguments.");
return -EINVAL;
}
umask(0022);
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0);

View File

@ -10,6 +10,63 @@
#include "memory-util.h"
#include "string-util.h"
#define BUS_INTROSPECT_DOCTYPE \
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n" \
"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
#define BUS_INTROSPECT_INTERFACE_PEER \
" <interface name=\"org.freedesktop.DBus.Peer\">\n" \
" <method name=\"Ping\"/>\n" \
" <method name=\"GetMachineId\">\n" \
" <arg type=\"s\" name=\"machine_uuid\" direction=\"out\"/>\n" \
" </method>\n" \
" </interface>\n"
#define BUS_INTROSPECT_INTERFACE_INTROSPECTABLE \
" <interface name=\"org.freedesktop.DBus.Introspectable\">\n" \
" <method name=\"Introspect\">\n" \
" <arg name=\"data\" type=\"s\" direction=\"out\"/>\n" \
" </method>\n" \
" </interface>\n"
#define BUS_INTROSPECT_INTERFACE_PROPERTIES \
" <interface name=\"org.freedesktop.DBus.Properties\">\n" \
" <method name=\"Get\">\n" \
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
" <arg name=\"property\" direction=\"in\" type=\"s\"/>\n" \
" <arg name=\"value\" direction=\"out\" type=\"v\"/>\n" \
" </method>\n" \
" <method name=\"GetAll\">\n" \
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
" <arg name=\"properties\" direction=\"out\" type=\"a{sv}\"/>\n" \
" </method>\n" \
" <method name=\"Set\">\n" \
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
" <arg name=\"property\" direction=\"in\" type=\"s\"/>\n" \
" <arg name=\"value\" direction=\"in\" type=\"v\"/>\n" \
" </method>\n" \
" <signal name=\"PropertiesChanged\">\n" \
" <arg type=\"s\" name=\"interface\"/>\n" \
" <arg type=\"a{sv}\" name=\"changed_properties\"/>\n" \
" <arg type=\"as\" name=\"invalidated_properties\"/>\n" \
" </signal>\n" \
" </interface>\n"
#define BUS_INTROSPECT_INTERFACE_OBJECT_MANAGER \
" <interface name=\"org.freedesktop.DBus.ObjectManager\">\n" \
" <method name=\"GetManagedObjects\">\n" \
" <arg type=\"a{oa{sa{sv}}}\" name=\"object_paths_interfaces_and_properties\" direction=\"out\"/>\n" \
" </method>\n" \
" <signal name=\"InterfacesAdded\">\n" \
" <arg type=\"o\" name=\"object_path\"/>\n" \
" <arg type=\"a{sa{sv}}\" name=\"interfaces_and_properties\"/>\n" \
" </signal>\n" \
" <signal name=\"InterfacesRemoved\">\n" \
" <arg type=\"o\" name=\"object_path\"/>\n" \
" <arg type=\"as\" name=\"interfaces\"/>\n" \
" </signal>\n" \
" </interface>\n"
int introspect_begin(struct introspect *i, bool trusted) {
assert(i);
@ -40,12 +97,27 @@ int introspect_write_default_interfaces(struct introspect *i, bool object_manage
return 0;
}
static int set_interface_name(struct introspect *intro, const char *interface_name) {
if (streq_ptr(intro->interface_name, interface_name))
return 0;
if (intro->interface_name)
fputs(" </interface>\n", intro->f);
if (interface_name)
fprintf(intro->f, " <interface name=\"%s\">\n", interface_name);
return free_and_strdup(&intro->interface_name, interface_name);
}
int introspect_write_child_nodes(struct introspect *i, Set *s, const char *prefix) {
char *node;
assert(i);
assert(prefix);
assert_se(set_interface_name(i, NULL) >= 0);
while ((node = set_steal_first(s))) {
const char *e;
@ -115,13 +187,23 @@ static int introspect_write_arguments(struct introspect *i, const char *signatur
}
}
int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v) {
int introspect_write_interface(
struct introspect *i,
const char *interface_name,
const sd_bus_vtable *v) {
const sd_bus_vtable *vtable = v;
const char *names = "";
int r;
assert(i);
assert(interface_name);
assert(v);
r = set_interface_name(i, interface_name);
if (r < 0)
return r;
for (; v->type != _SD_BUS_VTABLE_END; v = bus_vtable_next(vtable, v)) {
/* Ignore methods, signals and properties that are
@ -178,6 +260,8 @@ int introspect_finish(struct introspect *i, char **ret) {
assert(i);
assert_se(set_interface_name(i, NULL) >= 0);
fputs("</node>\n", i->f);
r = fflush_and_check(i->f);
@ -196,5 +280,6 @@ void introspect_free(struct introspect *i) {
/* Normally introspect_finish() does all the work, this is just a backup for error paths */
safe_fclose(i->f);
free(i->interface_name);
free(i->introspection);
}

View File

@ -9,6 +9,7 @@
struct introspect {
FILE *f;
char *interface_name;
char *introspection;
size_t size;
bool trusted;
@ -17,6 +18,9 @@ struct introspect {
int introspect_begin(struct introspect *i, bool trusted);
int introspect_write_default_interfaces(struct introspect *i, bool object_manager);
int introspect_write_child_nodes(struct introspect *i, Set *s, const char *prefix);
int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v);
int introspect_write_interface(
struct introspect *i,
const char *interface_name,
const sd_bus_vtable *v);
int introspect_finish(struct introspect *i, char **ret);
void introspect_free(struct introspect *i);

View File

@ -827,10 +827,10 @@ static int property_get_all_callbacks_run(
if (r < 0)
return r;
found_interface = !iface ||
streq(iface, "org.freedesktop.DBus.Properties") ||
streq(iface, "org.freedesktop.DBus.Peer") ||
streq(iface, "org.freedesktop.DBus.Introspectable");
found_interface = !iface || STR_IN_SET(iface,
"org.freedesktop.DBus.Properties",
"org.freedesktop.DBus.Peer",
"org.freedesktop.DBus.Introspectable");
LIST_FOREACH(vtables, c, first) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
@ -939,7 +939,6 @@ int introspect_path(
sd_bus_error *error) {
_cleanup_set_free_free_ Set *s = NULL;
const char *previous_interface = NULL;
_cleanup_(introspect_free) struct introspect intro = {};
struct node_vtable *c;
bool empty;
@ -984,23 +983,11 @@ int introspect_path(
if (c->vtable[0].flags & SD_BUS_VTABLE_HIDDEN)
continue;
if (!streq_ptr(previous_interface, c->interface)) {
if (previous_interface)
fputs(" </interface>\n", intro.f);
fprintf(intro.f, " <interface name=\"%s\">\n", c->interface);
}
r = introspect_write_interface(&intro, c->vtable);
r = introspect_write_interface(&intro, c->interface, c->vtable);
if (r < 0)
return r;
previous_interface = c->interface;
}
if (previous_interface)
fputs(" </interface>\n", intro.f);
if (empty) {
/* Nothing?, let's see if we exist at all, and if not
* refuse to do anything */

View File

@ -103,60 +103,3 @@ enum {
BUS_START_REPLY_SUCCESS = 1,
BUS_START_REPLY_ALREADY_RUNNING = 2,
};
#define BUS_INTROSPECT_DOCTYPE \
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n" \
"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
#define BUS_INTROSPECT_INTERFACE_PEER \
" <interface name=\"org.freedesktop.DBus.Peer\">\n" \
" <method name=\"Ping\"/>\n" \
" <method name=\"GetMachineId\">\n" \
" <arg type=\"s\" name=\"machine_uuid\" direction=\"out\"/>\n" \
" </method>\n" \
" </interface>\n"
#define BUS_INTROSPECT_INTERFACE_INTROSPECTABLE \
" <interface name=\"org.freedesktop.DBus.Introspectable\">\n" \
" <method name=\"Introspect\">\n" \
" <arg name=\"data\" type=\"s\" direction=\"out\"/>\n" \
" </method>\n" \
" </interface>\n"
#define BUS_INTROSPECT_INTERFACE_PROPERTIES \
" <interface name=\"org.freedesktop.DBus.Properties\">\n" \
" <method name=\"Get\">\n" \
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
" <arg name=\"property\" direction=\"in\" type=\"s\"/>\n" \
" <arg name=\"value\" direction=\"out\" type=\"v\"/>\n" \
" </method>\n" \
" <method name=\"GetAll\">\n" \
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
" <arg name=\"properties\" direction=\"out\" type=\"a{sv}\"/>\n" \
" </method>\n" \
" <method name=\"Set\">\n" \
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
" <arg name=\"property\" direction=\"in\" type=\"s\"/>\n" \
" <arg name=\"value\" direction=\"in\" type=\"v\"/>\n" \
" </method>\n" \
" <signal name=\"PropertiesChanged\">\n" \
" <arg type=\"s\" name=\"interface\"/>\n" \
" <arg type=\"a{sv}\" name=\"changed_properties\"/>\n" \
" <arg type=\"as\" name=\"invalidated_properties\"/>\n" \
" </signal>\n" \
" </interface>\n"
#define BUS_INTROSPECT_INTERFACE_OBJECT_MANAGER \
" <interface name=\"org.freedesktop.DBus.ObjectManager\">\n" \
" <method name=\"GetManagedObjects\">\n" \
" <arg type=\"a{oa{sa{sv}}}\" name=\"object_paths_interfaces_and_properties\" direction=\"out\"/>\n" \
" </method>\n" \
" <signal name=\"InterfacesAdded\">\n" \
" <arg type=\"o\" name=\"object_path\"/>\n" \
" <arg type=\"a{sa{sv}}\" name=\"interfaces_and_properties\"/>\n" \
" </signal>\n" \
" <signal name=\"InterfacesRemoved\">\n" \
" <arg type=\"o\" name=\"object_path\"/>\n" \
" <arg type=\"as\" name=\"interfaces\"/>\n" \
" </signal>\n" \
" </interface>\n"

View File

@ -14,11 +14,11 @@ static void test_manual_introspection(const sd_bus_vtable vtable[]) {
assert_se(introspect_begin(&intro, false) >= 0);
fprintf(intro.f, " <interface name=\"org.foo\">\n");
assert_se(introspect_write_interface(&intro, vtable) >= 0);
fputs(" </interface>\n", intro.f);
assert_se(introspect_write_interface(&intro, "org.foo", vtable) >= 0);
/* write again to check if output looks OK for a different interface */
assert_se(introspect_write_interface(&intro, "org.foo.bar", vtable) >= 0);
assert_se(introspect_finish(&intro, &s) == 0);
fputs(s, stdout);
fputs("\n", stdout);
}

View File

@ -25,6 +25,7 @@
#include "missing_capability.h"
#include "path-util.h"
#include "selinux-util.h"
#include "service-util.h"
#include "signal-util.h"
#include "string-util.h"
#include "strv.h"
@ -709,6 +710,12 @@ static const sd_bus_vtable locale_vtable[] = {
SD_BUS_VTABLE_END
};
static const BusObjectImplementation manager_object = {
"/org/freedesktop/locale1",
"org.freedesktop.locale1",
.vtables = BUS_VTABLES(locale_vtable),
};
static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
int r;
@ -721,9 +728,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
if (r < 0)
return log_error_errno(r, "Failed to get system bus connection: %m");
r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/locale1", "org.freedesktop.locale1", locale_vtable, c);
r = bus_add_implementation(bus, &manager_object, c);
if (r < 0)
return log_error_errno(r, "Failed to register object: %m");
return r;
r = bus_log_control_api_register(bus);
if (r < 0)
@ -754,12 +761,17 @@ static int run(int argc, char *argv[]) {
log_setup_service();
r = service_parse_argv("systemd-localed.service",
"Manage system locale settings and key mappings.",
BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object),
argc, argv);
if (r <= 0)
return r;
umask(0022);
mac_selinux_init();
if (argc != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
r = sd_event_default(&event);

View File

@ -3322,7 +3322,7 @@ fail:
return r;
}
const sd_bus_vtable manager_vtable[] = {
static const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 0),
@ -3754,6 +3754,15 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_END
};
const BusObjectImplementation manager_object = {
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
.vtables = BUS_VTABLES(manager_vtable),
.children = BUS_IMPLEMENTATIONS(&seat_object,
&session_object,
&user_object),
};
static int session_jobs_reply(Session *s, uint32_t jid, const char *unit, const char *result) {
assert(s);
assert(unit);

View File

@ -3,6 +3,7 @@
#include "sd-bus.h"
#include "bus-util.h"
#include "logind.h"
#include "logind-session.h"
#include "logind-user.h"
@ -29,3 +30,5 @@ int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *err
int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error);
int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *error);
int manager_job_is_active(Manager *manager, const char *path, sd_bus_error *error);
extern const BusObjectImplementation manager_object;

View File

@ -291,41 +291,7 @@ static int method_switch_to_previous(sd_bus_message *message, void *userdata, sd
return sd_bus_reply_method_return(message, NULL);
}
const sd_bus_vtable seat_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Seat, id), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ActiveSession", "(so)", property_get_active_session, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("CanMultiSession", "b", property_get_const_true, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("CanTTY", "b", property_get_can_tty, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CanGraphical", "b", property_get_can_graphical, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0),
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_METHOD("Terminate", NULL, NULL, bus_seat_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("ActivateSession",
"s",
SD_BUS_PARAM(session_id),
NULL,,
method_activate_session,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SwitchTo",
"u",
SD_BUS_PARAM(vtnr),
NULL,,
method_switch_to,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SwitchToNext", NULL, NULL, method_switch_to_next, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SwitchToPrevious", NULL, NULL, method_switch_to_previous, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
int seat_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
static int seat_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
_cleanup_free_ char *e = NULL;
sd_bus_message *message;
Manager *m = userdata;
@ -373,7 +339,7 @@ char *seat_bus_path(Seat *s) {
return strjoin("/org/freedesktop/login1/seat/", t);
}
int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
static int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
sd_bus_message *message;
Manager *m = userdata;
@ -478,3 +444,44 @@ int seat_send_changed(Seat *s, const char *properties, ...) {
return sd_bus_emit_properties_changed_strv(s->manager->bus, p, "org.freedesktop.login1.Seat", l);
}
static const sd_bus_vtable seat_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Seat, id), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ActiveSession", "(so)", property_get_active_session, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("CanMultiSession", "b", property_get_const_true, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("CanTTY", "b", property_get_can_tty, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CanGraphical", "b", property_get_can_graphical, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0),
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_METHOD("Terminate", NULL, NULL, bus_seat_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("ActivateSession",
"s",
SD_BUS_PARAM(session_id),
NULL,,
method_activate_session,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SwitchTo",
"u",
SD_BUS_PARAM(vtnr),
NULL,,
method_switch_to,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SwitchToNext", NULL, NULL, method_switch_to_next, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SwitchToPrevious", NULL, NULL, method_switch_to_previous, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
const BusObjectImplementation seat_object = {
"/org/freedesktop/login1/seat",
"org.freedesktop.login1.Seat",
.fallback_vtables = BUS_FALLBACK_VTABLES({seat_vtable, seat_object_find}),
.node_enumerator = seat_node_enumerator,
};

View File

@ -4,11 +4,10 @@
#include "sd-bus.h"
#include "logind-seat.h"
#include "bus-util.h"
extern const sd_bus_vtable seat_vtable[];
extern const BusObjectImplementation seat_object;
int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
int seat_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
char *seat_bus_path(Seat *s);
int seat_send_signal(Seat *s, bool new_seat);

View File

@ -581,141 +581,7 @@ static int method_set_brightness(sd_bus_message *message, void *userdata, sd_bus
return 1;
}
const sd_bus_vtable session_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Session, id), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("User", "(uo)", property_get_user, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Session, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("VTNr", "u", NULL, offsetof(Session, vtnr), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Seat", "(so)", property_get_seat, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TTY", "s", NULL, offsetof(Session, tty), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Display", "s", NULL, offsetof(Session, display), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Remote", "b", bus_property_get_bool, offsetof(Session, remote), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RemoteHost", "s", NULL, offsetof(Session, remote_host), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RemoteUser", "s", NULL, offsetof(Session, remote_user), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Active", "b", property_get_active, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("State", "s", property_get_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_METHOD("Terminate",
NULL,
NULL,
bus_session_method_terminate,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Activate",
NULL,
NULL,
bus_session_method_activate,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Lock",
NULL,
NULL,
bus_session_method_lock,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Unlock",
NULL,
NULL,
bus_session_method_lock,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetIdleHint",
"b",
SD_BUS_PARAM(idle),
NULL,,
method_set_idle_hint,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetLockedHint",
"b",
SD_BUS_PARAM(locked),
NULL,,
method_set_locked_hint,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("Kill",
"si",
SD_BUS_PARAM(who)
SD_BUS_PARAM(signal_number),
NULL,,
bus_session_method_kill,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("TakeControl",
"b",
SD_BUS_PARAM(force),
NULL,,
method_take_control,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ReleaseControl",
NULL,
NULL,
method_release_control,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetType",
"s",
SD_BUS_PARAM(type),
NULL,,
method_set_type,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("TakeDevice",
"uu",
SD_BUS_PARAM(major)
SD_BUS_PARAM(minor),
"hb",
SD_BUS_PARAM(fd)
SD_BUS_PARAM(inactive),
method_take_device,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("ReleaseDevice",
"uu",
SD_BUS_PARAM(major)
SD_BUS_PARAM(minor),
NULL,,
method_release_device,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("PauseDeviceComplete",
"uu",
SD_BUS_PARAM(major)
SD_BUS_PARAM(minor),
NULL,,
method_pause_device_complete,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetBrightness",
"ssu",
SD_BUS_PARAM(subsystem)
SD_BUS_PARAM(name)
SD_BUS_PARAM(brightness),
NULL,,
method_set_brightness,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL_WITH_NAMES("PauseDevice",
"uus",
SD_BUS_PARAM(major)
SD_BUS_PARAM(minor)
SD_BUS_PARAM(type),
0),
SD_BUS_SIGNAL_WITH_NAMES("ResumeDevice",
"uuh",
SD_BUS_PARAM(major)
SD_BUS_PARAM(minor)
SD_BUS_PARAM(fd),
0),
SD_BUS_SIGNAL("Lock", NULL, 0),
SD_BUS_SIGNAL("Unlock", NULL, 0),
SD_BUS_VTABLE_END
};
int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
static int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
_cleanup_free_ char *e = NULL;
sd_bus_message *message;
Manager *m = userdata;
@ -763,7 +629,7 @@ char *session_bus_path(Session *s) {
return strjoin("/org/freedesktop/login1/session/", t);
}
int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
static int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
sd_bus_message *message;
Manager *m = userdata;
@ -964,3 +830,144 @@ int session_send_create_reply(Session *s, sd_bus_error *error) {
(uint32_t) s->vtnr,
false);
}
static const sd_bus_vtable session_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Session, id), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("User", "(uo)", property_get_user, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Session, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("VTNr", "u", NULL, offsetof(Session, vtnr), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Seat", "(so)", property_get_seat, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TTY", "s", NULL, offsetof(Session, tty), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Display", "s", NULL, offsetof(Session, display), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Remote", "b", bus_property_get_bool, offsetof(Session, remote), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RemoteHost", "s", NULL, offsetof(Session, remote_host), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RemoteUser", "s", NULL, offsetof(Session, remote_user), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Session, service), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Desktop", "s", NULL, offsetof(Session, desktop), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Session, scope), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Leader", "u", bus_property_get_pid, offsetof(Session, leader), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Audit", "u", NULL, offsetof(Session, audit_id), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Session, type), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Session, class), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Active", "b", property_get_active, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("State", "s", property_get_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_METHOD("Terminate",
NULL,
NULL,
bus_session_method_terminate,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Activate",
NULL,
NULL,
bus_session_method_activate,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Lock",
NULL,
NULL,
bus_session_method_lock,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Unlock",
NULL,
NULL,
bus_session_method_lock,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetIdleHint",
"b",
SD_BUS_PARAM(idle),
NULL,,
method_set_idle_hint,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetLockedHint",
"b",
SD_BUS_PARAM(locked),
NULL,,
method_set_locked_hint,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("Kill",
"si",
SD_BUS_PARAM(who)
SD_BUS_PARAM(signal_number),
NULL,,
bus_session_method_kill,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("TakeControl",
"b",
SD_BUS_PARAM(force),
NULL,,
method_take_control,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ReleaseControl",
NULL,
NULL,
method_release_control,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetType",
"s",
SD_BUS_PARAM(type),
NULL,,
method_set_type,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("TakeDevice",
"uu",
SD_BUS_PARAM(major)
SD_BUS_PARAM(minor),
"hb",
SD_BUS_PARAM(fd)
SD_BUS_PARAM(inactive),
method_take_device,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("ReleaseDevice",
"uu",
SD_BUS_PARAM(major)
SD_BUS_PARAM(minor),
NULL,,
method_release_device,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("PauseDeviceComplete",
"uu",
SD_BUS_PARAM(major)
SD_BUS_PARAM(minor),
NULL,,
method_pause_device_complete,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetBrightness",
"ssu",
SD_BUS_PARAM(subsystem)
SD_BUS_PARAM(name)
SD_BUS_PARAM(brightness),
NULL,,
method_set_brightness,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL_WITH_NAMES("PauseDevice",
"uus",
SD_BUS_PARAM(major)
SD_BUS_PARAM(minor)
SD_BUS_PARAM(type),
0),
SD_BUS_SIGNAL_WITH_NAMES("ResumeDevice",
"uuh",
SD_BUS_PARAM(major)
SD_BUS_PARAM(minor)
SD_BUS_PARAM(fd),
0),
SD_BUS_SIGNAL("Lock", NULL, 0),
SD_BUS_SIGNAL("Unlock", NULL, 0),
SD_BUS_VTABLE_END
};
const BusObjectImplementation session_object = {
"/org/freedesktop/login1/session",
"org.freedesktop.login1.Session",
.fallback_vtables = BUS_FALLBACK_VTABLES({session_vtable, session_object_find}),
.node_enumerator = session_node_enumerator,
};

View File

@ -5,9 +5,8 @@
#include "logind-session.h"
extern const sd_bus_vtable session_vtable[];
int session_node_enumerator(sd_bus *bus, const char *path,void *userdata, char ***nodes, sd_bus_error *error);
int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
extern const BusObjectImplementation session_object;
char *session_bus_path(Session *s);
int session_send_signal(Session *s, bool new_session);

View File

@ -258,36 +258,7 @@ int bus_user_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *
return sd_bus_reply_method_return(message, NULL);
}
const sd_bus_vtable user_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("UID", "u", property_get_uid, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("GID", "u", property_get_gid, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(User, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RuntimePath", "s", NULL, offsetof(User, runtime_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(User, service), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Slice", "s", NULL, offsetof(User, slice), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Display", "(so)", property_get_display, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0),
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Linger", "b", property_get_linger, 0, 0),
SD_BUS_METHOD("Terminate", NULL, NULL, bus_user_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("Kill",
"i",
SD_BUS_PARAM(signal_number),
NULL,,
bus_user_method_kill,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
int user_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
static int user_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
Manager *m = userdata;
uid_t uid;
User *user;
@ -342,7 +313,7 @@ char *user_bus_path(User *u) {
return s;
}
int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
static int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
sd_bus_message *message;
Manager *m = userdata;
@ -391,6 +362,42 @@ int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***
return 1;
}
static const sd_bus_vtable user_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("UID", "u", property_get_uid, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("GID", "u", property_get_gid, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Name", "s", property_get_name, 0, SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(User, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RuntimePath", "s", NULL, offsetof(User, runtime_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(User, service), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Slice", "s", NULL, offsetof(User, slice), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Display", "(so)", property_get_display, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, 0),
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Linger", "b", property_get_linger, 0, 0),
SD_BUS_METHOD("Terminate", NULL, NULL, bus_user_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("Kill",
"i",
SD_BUS_PARAM(signal_number),
NULL,,
bus_user_method_kill,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
const BusObjectImplementation user_object = {
"/org/freedesktop/login1/user",
"org.freedesktop.login1.User",
.fallback_vtables = BUS_FALLBACK_VTABLES({user_vtable, user_object_find}),
.node_enumerator = user_node_enumerator,
};
int user_send_signal(User *u, bool new_user) {
_cleanup_free_ char *p = NULL;

View File

@ -5,9 +5,8 @@
#include "logind-user.h"
extern const sd_bus_vtable user_vtable[];
int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
int user_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
extern const BusObjectImplementation user_object;
char *user_bus_path(User *s);
int user_send_signal(User *u, bool new_user);

View File

@ -27,6 +27,7 @@
#include "parse-util.h"
#include "process-util.h"
#include "selinux-util.h"
#include "service-util.h"
#include "signal-util.h"
#include "strv.h"
#include "terminal-util.h"
@ -623,33 +624,13 @@ static int manager_connect_bus(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to connect to system bus: %m");
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
r = bus_add_implementation(m->bus, &manager_object, m);
if (r < 0)
return log_error_errno(r, "Failed to add manager object vtable: %m");
return r;
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
r = bus_log_control_api_register(m->bus);
if (r < 0)
return log_error_errno(r, "Failed to add seat object vtable: %m");
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
if (r < 0)
return log_error_errno(r, "Failed to add seat enumerator: %m");
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
if (r < 0)
return log_error_errno(r, "Failed to add session object vtable: %m");
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m);
if (r < 0)
return log_error_errno(r, "Failed to add session enumerator: %m");
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
if (r < 0)
return log_error_errno(r, "Failed to add user object vtable: %m");
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m);
if (r < 0)
return log_error_errno(r, "Failed to add user enumerator: %m");
return r;
r = sd_bus_match_signal_async(
m->bus,
@ -707,10 +688,6 @@ static int manager_connect_bus(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to enable subscription: %m");
r = bus_log_control_api_register(m->bus);
if (r < 0)
return r;
r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.login1", 0, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Failed to request name: %m");
@ -1201,12 +1178,15 @@ static int run(int argc, char *argv[]) {
log_set_facility(LOG_AUTH);
log_setup_service();
umask(0022);
r = service_parse_argv("systemd-logind.service",
"Manager for user logins and devices and privileged operations.",
BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object),
argc, argv);
if (r <= 0)
return r;
if (argc != 1) {
log_error("This program takes no arguments.");
return -EINVAL;
}
umask(0022);
r = mac_selinux_init();
if (r < 0)

View File

@ -157,8 +157,6 @@ int manager_read_utmp(Manager *m);
void manager_connect_utmp(Manager *m);
void manager_reconnect_utmp(Manager *m);
extern const sd_bus_vtable manager_vtable[];
/* gperf lookup function */
const struct ConfigPerfItem* logind_gperf_lookup(const char *key, GPERF_LEN_TYPE length);

View File

@ -354,30 +354,6 @@ int bus_image_method_get_os_release(
return bus_reply_pair_array(message, image->os_release);
}
const sd_bus_vtable image_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0),
SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0),
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Image, type), 0),
SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0),
SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0),
SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0),
SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0),
SD_BUS_PROPERTY("Limit", "t", NULL, offsetof(Image, limit), 0),
SD_BUS_PROPERTY("UsageExclusive", "t", NULL, offsetof(Image, usage_exclusive), 0),
SD_BUS_PROPERTY("LimitExclusive", "t", NULL, offsetof(Image, limit_exclusive), 0),
SD_BUS_METHOD("Remove", NULL, NULL, bus_image_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Rename", "s", NULL, bus_image_method_rename, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetHostname", NULL, "s", bus_image_method_get_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetMachineID", NULL, "ay", bus_image_method_get_machine_id, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetMachineInfo", NULL, "a{ss}", bus_image_method_get_machine_info, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_image_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
static int image_flush_cache(sd_event_source *s, void *userdata) {
Manager *m = userdata;
@ -388,7 +364,7 @@ static int image_flush_cache(sd_event_source *s, void *userdata) {
return 0;
}
int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
static int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
_cleanup_free_ char *e = NULL;
Manager *m = userdata;
Image *image = NULL;
@ -462,7 +438,7 @@ char *image_bus_path(const char *name) {
return strjoin("/org/freedesktop/machine1/image/", e);
}
int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
static int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_hashmap_free_ Hashmap *images = NULL;
_cleanup_strv_free_ char **l = NULL;
Image *image;
@ -497,3 +473,34 @@ int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char **
return 1;
}
const sd_bus_vtable image_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0),
SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0),
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Image, type), 0),
SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0),
SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0),
SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0),
SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0),
SD_BUS_PROPERTY("Limit", "t", NULL, offsetof(Image, limit), 0),
SD_BUS_PROPERTY("UsageExclusive", "t", NULL, offsetof(Image, usage_exclusive), 0),
SD_BUS_PROPERTY("LimitExclusive", "t", NULL, offsetof(Image, limit_exclusive), 0),
SD_BUS_METHOD("Remove", NULL, NULL, bus_image_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Rename", "s", NULL, bus_image_method_rename, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetHostname", NULL, "s", bus_image_method_get_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetMachineID", NULL, "ay", bus_image_method_get_machine_id, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetMachineInfo", NULL, "a{ss}", bus_image_method_get_machine_info, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_image_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
const BusObjectImplementation image_object = {
"/org/freedesktop/machine1/image",
"org.freedesktop.machine1.Image",
.fallback_vtables = BUS_FALLBACK_VTABLES({image_vtable, image_object_find}),
.node_enumerator = image_node_enumerator,
};

View File

@ -1,15 +1,13 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "bus-util.h"
#include "machined.h"
extern const sd_bus_vtable image_vtable[];
extern const BusObjectImplementation image_object;
char *image_bus_path(const char *name);
int image_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
int bus_image_method_remove(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_image_method_rename(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_image_method_clone(sd_bus_message *message, void *userdata, sd_bus_error *error);

View File

@ -1321,7 +1321,99 @@ int bus_machine_method_get_uid_shift(sd_bus_message *message, void *userdata, sd
return sd_bus_reply_method_return(message, "u", (uint32_t) shift);
}
const sd_bus_vtable machine_vtable[] = {
static int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
Manager *m = userdata;
Machine *machine;
int r;
assert(bus);
assert(path);
assert(interface);
assert(found);
assert(m);
if (streq(path, "/org/freedesktop/machine1/machine/self")) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
sd_bus_message *message;
pid_t pid;
message = sd_bus_get_current_message(bus);
if (!message)
return 0;
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
if (r < 0)
return r;
r = sd_bus_creds_get_pid(creds, &pid);
if (r < 0)
return r;
r = manager_get_machine_by_pid(m, pid, &machine);
if (r <= 0)
return 0;
} else {
_cleanup_free_ char *e = NULL;
const char *p;
p = startswith(path, "/org/freedesktop/machine1/machine/");
if (!p)
return 0;
e = bus_label_unescape(p);
if (!e)
return -ENOMEM;
machine = hashmap_get(m->machines, e);
if (!machine)
return 0;
}
*found = machine;
return 1;
}
char *machine_bus_path(Machine *m) {
_cleanup_free_ char *e = NULL;
assert(m);
e = bus_label_escape(m->name);
if (!e)
return NULL;
return strjoin("/org/freedesktop/machine1/machine/", e);
}
static int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
Machine *machine = NULL;
Manager *m = userdata;
Iterator i;
int r;
assert(bus);
assert(path);
assert(nodes);
HASHMAP_FOREACH(machine, m->machines, i) {
char *p;
p = machine_bus_path(machine);
if (!p)
return -ENOMEM;
r = strv_consume(&l, p);
if (r < 0)
return r;
}
*nodes = TAKE_PTR(l);
return 1;
}
static const sd_bus_vtable machine_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Id", "ay", bus_property_get_id128, offsetof(Machine, id), SD_BUS_VTABLE_PROPERTY_CONST),
@ -1423,97 +1515,12 @@ const sd_bus_vtable machine_vtable[] = {
SD_BUS_VTABLE_END
};
int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
Manager *m = userdata;
Machine *machine;
int r;
assert(bus);
assert(path);
assert(interface);
assert(found);
assert(m);
if (streq(path, "/org/freedesktop/machine1/machine/self")) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
sd_bus_message *message;
pid_t pid;
message = sd_bus_get_current_message(bus);
if (!message)
return 0;
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
if (r < 0)
return r;
r = sd_bus_creds_get_pid(creds, &pid);
if (r < 0)
return r;
r = manager_get_machine_by_pid(m, pid, &machine);
if (r <= 0)
return 0;
} else {
_cleanup_free_ char *e = NULL;
const char *p;
p = startswith(path, "/org/freedesktop/machine1/machine/");
if (!p)
return 0;
e = bus_label_unescape(p);
if (!e)
return -ENOMEM;
machine = hashmap_get(m->machines, e);
if (!machine)
return 0;
}
*found = machine;
return 1;
}
char *machine_bus_path(Machine *m) {
_cleanup_free_ char *e = NULL;
assert(m);
e = bus_label_escape(m->name);
if (!e)
return NULL;
return strjoin("/org/freedesktop/machine1/machine/", e);
}
int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
Machine *machine = NULL;
Manager *m = userdata;
Iterator i;
int r;
assert(bus);
assert(path);
assert(nodes);
HASHMAP_FOREACH(machine, m->machines, i) {
char *p;
p = machine_bus_path(machine);
if (!p)
return -ENOMEM;
r = strv_consume(&l, p);
if (r < 0)
return r;
}
*nodes = TAKE_PTR(l);
return 1;
}
const BusObjectImplementation machine_object = {
"/org/freedesktop/machine1/machine",
"org.freedesktop.machine1.Machine",
.fallback_vtables = BUS_FALLBACK_VTABLES({machine_vtable, machine_object_find}),
.node_enumerator = machine_node_enumerator,
};
int machine_send_signal(Machine *m, bool new_machine) {
_cleanup_free_ char *p = NULL;

View File

@ -3,13 +3,12 @@
#include "sd-bus.h"
#include "bus-util.h"
#include "machine.h"
extern const sd_bus_vtable machine_vtable[];
extern const BusObjectImplementation machine_object;
char *machine_bus_path(Machine *s);
int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
int bus_machine_method_unregister(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error);

View File

@ -1440,6 +1440,14 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_END
};
const BusObjectImplementation manager_object = {
"/org/freedesktop/machine1",
"org.freedesktop.machine1.Manager",
.vtables = BUS_VTABLES(manager_vtable),
.children = BUS_IMPLEMENTATIONS( &machine_object,
&image_object ),
};
int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *path, *result, *unit;
Manager *m = userdata;

View File

@ -22,6 +22,7 @@
#include "machined.h"
#include "main-func.h"
#include "process-util.h"
#include "service-util.h"
#include "signal-util.h"
#include "special.h"
@ -188,25 +189,9 @@ static int manager_connect_bus(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to connect to system bus: %m");
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", manager_vtable, m);
r = bus_add_implementation(m->bus, &manager_object, m);
if (r < 0)
return log_error_errno(r, "Failed to add manager object vtable: %m");
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/machine", "org.freedesktop.machine1.Machine", machine_vtable, machine_object_find, m);
if (r < 0)
return log_error_errno(r, "Failed to add machine object vtable: %m");
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/machine", machine_node_enumerator, m);
if (r < 0)
return log_error_errno(r, "Failed to add machine enumerator: %m");
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/image", "org.freedesktop.machine1.Image", image_vtable, image_object_find, m);
if (r < 0)
return log_error_errno(r, "Failed to add image object vtable: %m");
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/image", image_node_enumerator, m);
if (r < 0)
return log_error_errno(r, "Failed to add image enumerator: %m");
return r;
r = sd_bus_match_signal_async(
m->bus,
@ -357,12 +342,15 @@ static int run(int argc, char *argv[]) {
log_set_facility(LOG_AUTH);
log_setup_service();
umask(0022);
r = service_parse_argv("systemd-machined.service",
"Manage registrations of local VMs and containers.",
BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object),
argc, argv);
if (r <= 0)
return r;
if (argc != 1) {
log_error("This program takes no arguments.");
return -EINVAL;
}
umask(0022);
/* Always create the directories people can create inotify watches in. Note that some applications might check
* for the existence of /run/systemd/machines/ to determine whether machined is available, so please always

View File

@ -42,7 +42,7 @@ struct Manager {
int manager_add_machine(Manager *m, const char *name, Machine **_machine);
int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine);
extern const sd_bus_vtable manager_vtable[];
extern const BusObjectImplementation manager_object;
int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error);

View File

@ -1942,7 +1942,7 @@ static const sd_bus_vtable resolve_vtable[] = {
"q", service_port,
"q", service_priority,
"q", service_weight,
"a{say}", txt_datas),
"aa{say}", txt_datas),
SD_BUS_RESULT("o", service_path),
bus_method_register_service,
SD_BUS_VTABLE_UNPRIVILEGED),
@ -1970,6 +1970,14 @@ static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_VTABLE_END,
};
const BusObjectImplementation manager_object = {
"/org/freedesktop/resolve1",
"org.freedesktop.resolve1.Manager",
.vtables = BUS_VTABLES(resolve_vtable),
.children = BUS_IMPLEMENTATIONS(&link_object,
&dnssd_object),
};
static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
Manager *m = userdata;
int b, r;
@ -2004,25 +2012,9 @@ int manager_connect_bus(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to connect to system bus: %m");
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
r = bus_add_implementation(m->bus, &manager_object, m);
if (r < 0)
return log_error_errno(r, "Failed to register object: %m");
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/resolve1/link", "org.freedesktop.resolve1.Link", link_vtable, link_object_find, m);
if (r < 0)
return log_error_errno(r, "Failed to register link objects: %m");
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/resolve1/link", link_node_enumerator, m);
if (r < 0)
return log_error_errno(r, "Failed to register link enumerator: %m");
r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/resolve1/dnssd", "org.freedesktop.resolve1.DnssdService", dnssd_vtable, dnssd_object_find, m);
if (r < 0)
return log_error_errno(r, "Failed to register dnssd objects: %m");
r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/resolve1/dnssd", dnssd_node_enumerator, m);
if (r < 0)
return log_error_errno(r, "Failed to register dnssd enumerator: %m");
return r;
r = bus_log_control_api_register(m->bus);
if (r < 0)

View File

@ -1,8 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "bus-util.h"
#include "resolved-manager.h"
extern const BusObjectImplementation manager_object;
int manager_connect_bus(Manager *m);
int _manager_send_changed(Manager *manager, const char *property, ...) _sentinel_;
#define manager_send_changed(manager, ...) _manager_send_changed(manager, __VA_ARGS__, NULL)

View File

@ -62,16 +62,7 @@ int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_
return sd_bus_reply_method_return(message, NULL);
}
const sd_bus_vtable dnssd_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("Unregister", NULL, NULL, bus_dnssd_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL("Conflicted", NULL, 0),
SD_BUS_VTABLE_END
};
int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
static int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
_cleanup_free_ char *name = NULL;
Manager *m = userdata;
DnssdService *service;
@ -95,7 +86,7 @@ int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void
return 1;
}
int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
static int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
Manager *m = userdata;
DnssdService *service;
@ -127,3 +118,19 @@ int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char **
return 1;
}
static const sd_bus_vtable dnssd_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("Unregister", NULL, NULL, bus_dnssd_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL("Conflicted", NULL, 0),
SD_BUS_VTABLE_END
};
const BusObjectImplementation dnssd_object = {
"/org/freedesktop/resolve1/dnssd",
"org.freedesktop.resolve1.DnssdService",
.fallback_vtables = BUS_FALLBACK_VTABLES({dnssd_vtable, dnssd_object_find}),
.node_enumerator = dnssd_node_enumerator,
};

View File

@ -2,9 +2,8 @@
#include "sd-bus.h"
extern const sd_bus_vtable dnssd_vtable[];
#include "bus-util.h"
int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
extern const BusObjectImplementation dnssd_object;
int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_error *error);

View File

@ -682,7 +682,82 @@ int bus_link_method_revert(sd_bus_message *message, void *userdata, sd_bus_error
return sd_bus_reply_method_return(message, NULL);
}
const sd_bus_vtable link_vtable[] = {
static int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
_cleanup_free_ char *e = NULL;
Manager *m = userdata;
Link *link;
int ifindex, r;
assert(bus);
assert(path);
assert(interface);
assert(found);
assert(m);
r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/link", &e);
if (r <= 0)
return 0;
ifindex = parse_ifindex(e);
if (ifindex < 0)
return 0;
link = hashmap_get(m->links, INT_TO_PTR(ifindex));
if (!link)
return 0;
*found = link;
return 1;
}
char *link_bus_path(const Link *link) {
char *p, ifindex[DECIMAL_STR_MAX(link->ifindex)];
int r;
assert(link);
xsprintf(ifindex, "%i", link->ifindex);
r = sd_bus_path_encode("/org/freedesktop/resolve1/link", ifindex, &p);
if (r < 0)
return NULL;
return p;
}
static int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
Manager *m = userdata;
Link *link;
Iterator i;
unsigned c = 0;
assert(bus);
assert(path);
assert(m);
assert(nodes);
l = new0(char*, hashmap_size(m->links) + 1);
if (!l)
return -ENOMEM;
HASHMAP_FOREACH(link, m->links, i) {
char *p;
p = link_bus_path(link);
if (!p)
return -ENOMEM;
l[c++] = p;
}
l[c] = NULL;
*nodes = TAKE_PTR(l);
return 1;
}
static const sd_bus_vtable link_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("ScopesMask", "t", property_get_scopes_mask, 0, 0),
@ -746,77 +821,9 @@ const sd_bus_vtable link_vtable[] = {
SD_BUS_VTABLE_END
};
int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
_cleanup_free_ char *e = NULL;
Manager *m = userdata;
Link *link;
int ifindex, r;
assert(bus);
assert(path);
assert(interface);
assert(found);
assert(m);
r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/link", &e);
if (r <= 0)
return 0;
ifindex = parse_ifindex(e);
if (ifindex < 0)
return 0;
link = hashmap_get(m->links, INT_TO_PTR(ifindex));
if (!link)
return 0;
*found = link;
return 1;
}
char *link_bus_path(const Link *link) {
char *p, ifindex[DECIMAL_STR_MAX(link->ifindex)];
int r;
assert(link);
xsprintf(ifindex, "%i", link->ifindex);
r = sd_bus_path_encode("/org/freedesktop/resolve1/link", ifindex, &p);
if (r < 0)
return NULL;
return p;
}
int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
Manager *m = userdata;
Link *link;
Iterator i;
unsigned c = 0;
assert(bus);
assert(path);
assert(m);
assert(nodes);
l = new0(char*, hashmap_size(m->links) + 1);
if (!l)
return -ENOMEM;
HASHMAP_FOREACH(link, m->links, i) {
char *p;
p = link_bus_path(link);
if (!p)
return -ENOMEM;
l[c++] = p;
}
l[c] = NULL;
*nodes = TAKE_PTR(l);
return 1;
}
const BusObjectImplementation link_object = {
"/org/freedesktop/resolve1/link",
"org.freedesktop.resolve1.Link",
.fallback_vtables = BUS_FALLBACK_VTABLES({link_vtable, link_object_find}),
.node_enumerator = link_node_enumerator,
};

View File

@ -3,13 +3,12 @@
#include "sd-bus.h"
#include "bus-util.h"
#include "resolved-link.h"
extern const sd_bus_vtable link_vtable[];
extern const BusObjectImplementation link_object;
int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
char *link_bus_path(const Link *link);
int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error);

View File

@ -7,14 +7,17 @@
#include "sd-daemon.h"
#include "sd-event.h"
#include "bus-log-control-api.h"
#include "capability-util.h"
#include "daemon-util.h"
#include "main-func.h"
#include "mkdir.h"
#include "resolved-bus.h"
#include "resolved-conf.h"
#include "resolved-manager.h"
#include "resolved-resolv-conf.h"
#include "selinux-util.h"
#include "service-util.h"
#include "signal-util.h"
#include "user-util.h"
@ -25,8 +28,13 @@ static int run(int argc, char *argv[]) {
log_setup_service();
if (argc != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
r = service_parse_argv("systemd-resolved.service",
"Provide name resolution with caching using DNS, mDNS, LLMNR.",
BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object),
argc, argv);
if (r <= 0)
return r;
umask(0022);

View File

@ -107,17 +107,8 @@ static const sd_bus_vtable log_control_vtable[] = {
SD_BUS_VTABLE_END,
};
int bus_log_control_api_register(sd_bus *bus) {
int r;
r = sd_bus_add_object_vtable(
bus,
NULL,
"/org/freedesktop/LogControl1",
"org.freedesktop.LogControl1",
log_control_vtable, NULL);
if (r < 0)
return log_error_errno(r, "Failed to register service API object: %m");
return 0;
}
const BusObjectImplementation log_control_object = {
"/org/freedesktop/LogControl1",
"org.freedesktop.LogControl1",
.vtables = BUS_VTABLES(log_control_vtable),
};

View File

@ -2,7 +2,12 @@
#include "sd-bus.h"
int bus_log_control_api_register(sd_bus *bus);
#include "bus-util.h"
extern const BusObjectImplementation log_control_object;
static inline int bus_log_control_api_register(sd_bus *bus) {
return bus_add_implementation(bus, &log_control_object, NULL);
}
int bus_property_get_log_level(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
int bus_property_set_log_level(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error);

View File

@ -16,6 +16,7 @@
#include "alloc-util.h"
#include "bus-internal.h"
#include "bus-introspect.h"
#include "bus-label.h"
#include "bus-message.h"
#include "bus-util.h"
@ -1549,3 +1550,171 @@ int bus_message_new_method_call(
return sd_bus_message_new_method_call(bus, m, locator->destination, locator->path, locator->interface, member);
}
int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, void *userdata) {
int r;
log_debug("Registering bus object implementation for path=%s iface=%s", impl->path, impl->interface);
for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) {
r = sd_bus_add_object_vtable(bus, NULL,
impl->path,
impl->interface,
*p,
userdata);
if (r < 0)
return log_error_errno(r, "Failed to register bus path %s with interface %s: %m",
impl->path,
impl->interface);
}
for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) {
r = sd_bus_add_fallback_vtable(bus, NULL,
impl->path,
impl->interface,
p->vtable,
p->object_find,
userdata);
if (r < 0)
return log_error_errno(r, "Failed to register bus path %s with interface %s: %m",
impl->path,
impl->interface);
}
if (impl->node_enumerator) {
r = sd_bus_add_node_enumerator(bus, NULL,
impl->path,
impl->node_enumerator,
userdata);
if (r < 0)
return log_error_errno(r, "Failed to add node enumerator for %s: %m",
impl->path);
}
for (size_t i = 0; impl->children && impl->children[i]; i++) {
r = bus_add_implementation(bus, impl->children[i], userdata);
if (r < 0)
return r;
}
return 0;
}
static const BusObjectImplementation* find_implementation(
const char *pattern,
const BusObjectImplementation* const* bus_objects) {
for (size_t i = 0; bus_objects && bus_objects[i]; i++) {
const BusObjectImplementation *impl = bus_objects[i];
if (STR_IN_SET(pattern, impl->path, impl->interface))
return impl;
impl = find_implementation(pattern, impl->children);
if (impl)
return impl;
}
return NULL;
}
static int bus_introspect_implementation(
struct introspect *intro,
const BusObjectImplementation *impl) {
int r;
for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) {
r = introspect_write_interface(intro, impl->interface, *p);
if (r < 0)
return log_error_errno(r, "Failed to write introspection data: %m");
}
for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) {
r = introspect_write_interface(intro, impl->interface, p->vtable);
if (r < 0)
return log_error_errno(r, "Failed to write introspection data: %m");
}
return 0;
}
static void list_paths(
FILE *out,
const BusObjectImplementation* const* bus_objects) {
for (size_t i = 0; bus_objects[i]; i++) {
fprintf(out, "%s\t%s\n", bus_objects[i]->path, bus_objects[i]->interface);
if (bus_objects[i]->children)
list_paths(out, bus_objects[i]->children);
}
}
int bus_introspect_implementations(
FILE *out,
const char *pattern,
const BusObjectImplementation* const* bus_objects) {
const BusObjectImplementation *impl, *main_impl = NULL;
_cleanup_free_ char *s = NULL;
int r;
if (streq(pattern, "list")) {
list_paths(out, bus_objects);
return 0;
}
struct introspect intro = {};
bool is_interface = interface_name_is_valid(pattern);
impl = find_implementation(pattern, bus_objects);
if (!impl)
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
"%s %s not found",
is_interface ? "Interface" : "Object path",
pattern);
/* We use trusted=false here to get all the @org.freedesktop.systemd1.Privileged annotations. */
r = introspect_begin(&intro, false);
if (r < 0)
return log_error_errno(r, "Failed to write introspection data: %m");
r = introspect_write_default_interfaces(&intro, impl->manager);
if (r < 0)
return log_error_errno(r, "Failed to write introspection data: %m");
/* Check if there is a non-fallback path that applies to the given interface, also
* print it. This is useful in the case of units: o.fd.systemd1.Service is declared
* as a fallback vtable for o/fd/systemd1/unit, and we also want to print
* o.fd.systemd1.Unit, which is the non-fallback implementation. */
if (impl->fallback_vtables && is_interface)
main_impl = find_implementation(impl->path, bus_objects);
if (main_impl)
bus_introspect_implementation(&intro, main_impl);
if (impl != main_impl)
bus_introspect_implementation(&intro, impl);
_cleanup_set_free_free_ Set *nodes = NULL;
for (size_t i = 0; impl->children && impl->children[i]; i++) {
r = set_ensure_allocated(&nodes, &string_hash_ops);
if (r < 0)
return log_oom();
r = set_put_strdup(nodes, impl->children[i]->path);
if (r < 0)
return log_oom();
}
r = introspect_write_child_nodes(&intro, nodes, impl->path);
if (r < 0)
return r;
r = introspect_finish(&intro, &s);
if (r < 0)
return log_error_errno(r, "Failed to write introspection data: %m");
fputs(s, out);
return 0;
}

View File

@ -23,11 +23,32 @@ typedef enum BusTransport {
} BusTransport;
typedef struct BusLocator {
const char *destination;
const char *path;
const char *interface;
const char *destination;
const char *path;
const char *interface;
} BusLocator;
typedef struct BusObjectImplementation BusObjectImplementation;
typedef struct BusObjectVtablePair {
const sd_bus_vtable *vtable;
sd_bus_object_find_t object_find;
} BusObjectVtablePair;
struct BusObjectImplementation {
const char *path;
const char *interface;
const sd_bus_vtable **vtables;
const BusObjectVtablePair *fallback_vtables;
sd_bus_node_enumerator_t node_enumerator;
bool manager;
const BusObjectImplementation **children;
};
#define BUS_VTABLES(...) ((const sd_bus_vtable* []){ __VA_ARGS__, NULL })
#define BUS_FALLBACK_VTABLES(...) ((const BusObjectVtablePair[]) { __VA_ARGS__, {} })
#define BUS_IMPLEMENTATIONS(...) ((const BusObjectImplementation* []) { __VA_ARGS__, NULL })
typedef int (*bus_property_set_t) (sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
struct bus_properties_map {
@ -199,3 +220,9 @@ int bus_set_property(sd_bus *bus, const BusLocator *locator, const char *member,
int bus_match_signal(sd_bus *bus, sd_bus_slot **ret, const BusLocator *locator, const char *member, sd_bus_message_handler_t callback, void *userdata);
int bus_match_signal_async(sd_bus *bus, sd_bus_slot **ret, const BusLocator *locator, const char *member, sd_bus_message_handler_t callback, sd_bus_message_handler_t install_callback, void *userdata);
int bus_message_new_method_call(sd_bus *bus, sd_bus_message **m, const BusLocator *locator, const char *member);
int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, void *userdata);
int bus_introspect_implementations(
FILE *out,
const char *pattern,
const BusObjectImplementation* const* bus_objects);

View File

@ -73,6 +73,7 @@ typedef struct TableData {
bool uppercase; /* Uppercase string on display */
const char *color; /* ANSI color string to use for this cell. When written to terminal should not move cursor. Will automatically be reset after the cell */
const char *rgap_color; /* The ANSI color to use for the gap right of this cell. Usually used to underline entire rows in a gapless fashion */
char *url; /* A URL to use for a clickable hyperlink */
char *formatted; /* A cached textual representation of the cell data, before ellipsation/alignment */
@ -334,7 +335,7 @@ static bool table_data_matches(
return false;
/* If a color/url/uppercase flag is set, refuse to merge */
if (d->color)
if (d->color || d->rgap_color)
return false;
if (d->url)
return false;
@ -542,6 +543,7 @@ static int table_dedup_cell(Table *t, TableCell *cell) {
return -ENOMEM;
nd->color = od->color;
nd->rgap_color = od->rgap_color;
nd->url = TAKE_PTR(curl);
nd->uppercase = od->uppercase;
@ -671,6 +673,20 @@ int table_set_color(Table *t, TableCell *cell, const char *color) {
return 0;
}
int table_set_rgap_color(Table *t, TableCell *cell, const char *color) {
int r;
assert(t);
assert(cell);
r = table_dedup_cell(t, cell);
if (r < 0)
return r;
table_get_data(t, cell)->rgap_color = empty_to_null(color);
return 0;
}
int table_set_url(Table *t, TableCell *cell, const char *url) {
_cleanup_free_ char *copy = NULL;
int r;
@ -744,6 +760,7 @@ int table_update(Table *t, TableCell *cell, TableDataType type, const void *data
return -ENOMEM;
nd->color = od->color;
nd->rgap_color = od->rgap_color;
nd->url = TAKE_PTR(curl);
nd->uppercase = od->uppercase;
@ -952,6 +969,25 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
break;
}
case TABLE_SET_RGAP_COLOR: {
const char *c = va_arg(ap, const char*);
r = table_set_rgap_color(t, last_cell, c);
break;
}
case TABLE_SET_BOTH_COLORS: {
const char *c = va_arg(ap, const char*);
r = table_set_color(t, last_cell, c);
if (r < 0) {
va_end(ap);
return r;
}
r = table_set_rgap_color(t, last_cell, c);
break;
}
case TABLE_SET_URL: {
const char *u = va_arg(ap, const char*);
r = table_set_url(t, last_cell, u);
@ -1272,6 +1308,9 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
case TABLE_STRV: {
char *p;
if (strv_isempty(d->strv))
return strempty(t->empty_string);
p = strv_join(d->strv, "\n");
if (!p)
return NULL;
@ -1694,6 +1733,20 @@ static char *align_string_mem(const char *str, const char *url, size_t new_lengt
return ret;
}
static bool table_data_isempty(TableData *d) {
assert(d);
if (d->type == TABLE_EMPTY)
return true;
/* Let's also consider an empty strv as truly empty. */
if (d->type == TABLE_STRV)
return strv_isempty(d->strv);
/* Note that an empty string we do not consider empty here! */
return false;
}
static const char* table_data_color(TableData *d) {
assert(d);
@ -1701,12 +1754,21 @@ static const char* table_data_color(TableData *d) {
return d->color;
/* Let's implicitly color all "empty" cells in grey, in case an "empty_string" is set that is not empty */
if (d->type == TABLE_EMPTY)
if (table_data_isempty(d))
return ansi_grey();
return NULL;
}
static const char* table_data_rgap_color(TableData *d) {
assert(d);
if (d->rgap_color)
return d->rgap_color;
return NULL;
}
int table_print(Table *t, FILE *f) {
size_t n_rows, *minimum_width, *maximum_width, display_columns, *requested_width,
i, j, table_minimum_width, table_maximum_width, table_requested_width, table_effective_width,
@ -1958,12 +2020,13 @@ int table_print(Table *t, FILE *f) {
row = t->data + i * t->n_columns;
do {
const char *gap_color = NULL;
more_sublines = false;
for (j = 0; j < display_columns; j++) {
_cleanup_free_ char *buffer = NULL, *extracted = NULL;
bool lines_truncated = false;
const char *field;
const char *field, *color = NULL;
TableData *d;
size_t l;
@ -2042,23 +2105,35 @@ int table_print(Table *t, FILE *f) {
field = buffer;
}
if (row == t->data) /* underline header line fully, including the column separator */
fputs(ansi_underline(), f);
if (colors_enabled()) {
if (gap_color)
fputs(gap_color, f);
else if (row == t->data) /* underline header line fully, including the column separator */
fputs(ansi_underline(), f);
}
if (j > 0)
fputc(' ', f); /* column separator */
fputc(' ', f); /* column separator left of cell */
if (table_data_color(d) && colors_enabled()) {
if (row == t->data) /* first undo header underliner */
if (colors_enabled()) {
color = table_data_color(d);
/* Undo gap color */
if (gap_color || (color && row == t->data))
fputs(ANSI_NORMAL, f);
fputs(table_data_color(d), f);
if (color)
fputs(color, f);
else if (gap_color && row == t->data) /* underline header line cell */
fputs(ansi_underline(), f);
}
fputs(field, f);
if (colors_enabled() && (table_data_color(d) || row == t->data))
if (colors_enabled() && (color || row == t->data))
fputs(ANSI_NORMAL, f);
gap_color = table_data_rgap_color(d);
}
fputc('\n', f);

View File

@ -47,6 +47,8 @@ typedef enum TableDataType {
TABLE_SET_ALIGN_PERCENT,
TABLE_SET_ELLIPSIZE_PERCENT,
TABLE_SET_COLOR,
TABLE_SET_RGAP_COLOR,
TABLE_SET_BOTH_COLORS,
TABLE_SET_URL,
TABLE_SET_UPPERCASE,
@ -89,6 +91,7 @@ int table_set_weight(Table *t, TableCell *cell, unsigned weight);
int table_set_align_percent(Table *t, TableCell *cell, unsigned percent);
int table_set_ellipsize_percent(Table *t, TableCell *cell, unsigned percent);
int table_set_color(Table *t, TableCell *cell, const char *color);
int table_set_rgap_color(Table *t, TableCell *cell, const char *color);
int table_set_url(Table *t, TableCell *cell, const char *url);
int table_set_uppercase(Table *t, TableCell *cell, bool b);

View File

@ -184,6 +184,8 @@ shared_sources = files('''
securebits-util.h
serialize.c
serialize.h
service-util.c
service-util.h
sleep-config.c
sleep-config.h
socket-netlink.c

87
src/shared/service-util.c Normal file
View File

@ -0,0 +1,87 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include <getopt.h>
#include <stdio.h>
#include "alloc-util.h"
#include "pretty-print.h"
#include "service-util.h"
#include "terminal-util.h"
#include "util.h"
static int help(const char *program_path, const char *service, const char *description, bool bus_introspect) {
_cleanup_free_ char *link = NULL;
int r;
r = terminal_urlify_man(service, "8", &link);
if (r < 0)
return log_oom();
printf("%s [OPTIONS...]\n\n"
"%s%s%s\n\n"
"This program takes no positional arguments.\n\n"
"%sOptions%s:\n"
" -h --help Show this help\n"
" --version Show package version\n"
" --bus-introspect=PATH Write D-Bus XML introspection data\n"
"\nSee the %s for details.\n"
, program_path
, ansi_highlight(), description, ansi_normal()
, ansi_underline(), ansi_normal()
, link
);
return 0; /* No further action */
}
int service_parse_argv(
const char *service,
const char *description,
const BusObjectImplementation* const* bus_objects,
int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
ARG_BUS_INTROSPECT,
};
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{ "bus-introspect", required_argument, NULL, ARG_BUS_INTROSPECT },
{}
};
int c;
assert(argc >= 0);
assert(argv);
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
switch(c) {
case 'h':
return help(argv[0], service, description, bus_objects);
case ARG_VERSION:
return version();
case ARG_BUS_INTROSPECT:
return bus_introspect_implementations(
stdout,
optarg,
bus_objects);
case '?':
return -EINVAL;
default:
assert_not_reached("Unknown option code.");
}
if (optind < argc)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"This program takes no arguments.");
return 1; /* Further action */
}

10
src/shared/service-util.h Normal file
View File

@ -0,0 +1,10 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "bus-util.h"
int service_parse_argv(
const char *service,
const char *description,
const BusObjectImplementation* const* bus_objects,
int argc, char *argv[]);

View File

@ -425,6 +425,8 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
if (arg_full)
table_set_width(table, 0);
(void) table_set_empty_string(table, "-");
for (u = unit_infos; unit_infos && u < unit_infos + c; u++) {
_cleanup_free_ char *j = NULL;
const char *on_underline = "", *on_loaded = "", *on_active = "";
@ -438,14 +440,15 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
}
if (STR_IN_SET(u->load_state, "error", "not-found", "bad-setting", "masked") && !arg_plain) {
on_circle = ansi_highlight_yellow();
on_circle = underline ? ansi_highlight_yellow_underline() : ansi_highlight_yellow();
circle = true;
on_loaded = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
} else if (streq(u->active_state, "failed") && !arg_plain) {
on_circle = ansi_highlight_red();
on_circle = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
circle = true;
on_active = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
} else {
on_circle = on_underline;
on_active = on_underline;
on_loaded = on_underline;
}
@ -461,19 +464,19 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
r = table_add_many(table,
TABLE_STRING, circle ? special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE) : " ",
TABLE_SET_COLOR, on_circle,
TABLE_SET_BOTH_COLORS, on_circle,
TABLE_STRING, id,
TABLE_SET_COLOR, on_active,
TABLE_SET_BOTH_COLORS, on_active,
TABLE_STRING, u->load_state,
TABLE_SET_COLOR, on_loaded,
TABLE_SET_BOTH_COLORS, on_loaded,
TABLE_STRING, u->active_state,
TABLE_SET_COLOR, on_active,
TABLE_SET_BOTH_COLORS, on_active,
TABLE_STRING, u->sub_state,
TABLE_SET_COLOR, on_active,
TABLE_SET_BOTH_COLORS, on_active,
TABLE_STRING, u->job_id ? u->job_type: "",
TABLE_SET_COLOR, u->job_id ? on_underline : "",
TABLE_SET_BOTH_COLORS, u->job_id ? on_underline : "",
TABLE_STRING, u->description,
TABLE_SET_COLOR, on_underline);
TABLE_SET_BOTH_COLORS, on_underline);
if (r < 0)
return table_log_add_error(r);
@ -1006,7 +1009,7 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
const char *on, *off;
int r;
table = table_new("listen", "type", "units", "activates");
table = table_new("listen", "type", "unit", "activates");
if (!table)
return log_oom();
@ -1021,9 +1024,11 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
if (arg_full)
table_set_width(table, 0);
(void) table_set_empty_string(table, "-");
if (cs) {
for (s = socket_infos; s < socket_infos + cs; s++) {
_cleanup_free_ char *j = NULL, *activates = NULL;
_cleanup_free_ char *j = NULL;
const char *path;
if (s->machine) {
@ -1034,17 +1039,25 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
} else
path = s->path;
activates = strv_join(s->triggered, ", ");
if (!activates)
return log_oom();
r = table_add_many(table,
TABLE_STRING, path,
TABLE_STRING, s->type,
TABLE_STRING, s->id,
TABLE_STRING, activates);
TABLE_STRING, s->id);
if (r < 0)
return table_log_add_error(r);
if (strv_isempty(s->triggered))
r = table_add_cell(table, NULL, TABLE_EMPTY, NULL);
else if (strv_length(s->triggered) == 1)
r = table_add_cell(table, NULL, TABLE_STRING, s->triggered[0]);
else
/* This should never happen, currently our socket units can only trigger a
* single unit. But let's handle this anyway, who knows what the future
* brings? */
r = table_add_cell(table, NULL, TABLE_STRV, s->triggered);
if (r < 0)
return table_log_add_error(r);
}
on = ansi_highlight();
@ -1265,6 +1278,8 @@ static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
if (arg_full)
table_set_width(table, 0);
(void) table_set_empty_string(table, "-");
if (n > 0) {
for (t = timer_infos; t < timer_infos + n; t++) {
_cleanup_free_ char *j = NULL, *activates = NULL;
@ -1478,6 +1493,8 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
if (arg_full)
table_set_width(table, 0);
(void) table_set_empty_string(table, "-");
for (const UnitFileList *u = units; u < units + c; u++) {
const char *on_underline = NULL, *on_unit_color = NULL, *id;
bool underline;
@ -1505,9 +1522,9 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
r = table_add_many(table,
TABLE_STRING, id,
TABLE_SET_COLOR, strempty(on_underline),
TABLE_SET_BOTH_COLORS, strempty(on_underline),
TABLE_STRING, unit_file_state_to_string(u->state),
TABLE_SET_COLOR, strempty(on_unit_color));
TABLE_SET_BOTH_COLORS, strempty(on_unit_color));
if (r < 0)
return table_log_add_error(r);
@ -1528,10 +1545,11 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
r = table_add_many(table,
TABLE_STRING, unit_preset_str,
TABLE_SET_COLOR, strempty(on_preset_color));
TABLE_SET_BOTH_COLORS, strempty(on_preset_color));
} else
r = table_add_many(table, TABLE_EMPTY);
r = table_add_many(table,
TABLE_EMPTY,
TABLE_SET_BOTH_COLORS, underline ? ansi_grey_underline() : ansi_grey());
if (r < 0)
return table_log_add_error(r);
}
@ -2031,6 +2049,8 @@ static int output_machines_list(struct machine_info *machine_infos, unsigned n)
if (arg_full)
table_set_width(table, 0);
(void) table_set_empty_string(table, "-");
for (m = machine_infos; m < machine_infos + n; m++) {
_cleanup_free_ char *mname = NULL;
const char *on_state = "", *on_failed = "";
@ -2351,13 +2371,14 @@ static int output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n
if (arg_full)
table_set_width(table, 0);
(void) table_set_empty_string(table, "-");
for (j = jobs; j < jobs + n; j++) {
if (streq(j->state, "running"))
on = ansi_highlight();
else
on = "";
r = table_add_many(table,
TABLE_UINT, j->id,
TABLE_STRING, j->name,

View File

@ -17,7 +17,7 @@ static int test_acpi_fpdt(void) {
r = acpi_get_boot_usec(&loader_start, &loader_exit);
if (r < 0) {
bool ok = r == -ENOENT || (getuid() != 0 && r == -EACCES) || r == -ENODATA;
bool ok = r == -ENOENT || r == -EACCES || r == -ENODATA;
log_full_errno(ok ? LOG_DEBUG : LOG_ERR, r, "Failed to read ACPI FPDT: %m");
return ok ? 0 : r;
@ -37,7 +37,7 @@ static int test_efi_loader(void) {
r = efi_loader_get_boot_usec(&loader_start, &loader_exit);
if (r < 0) {
bool ok = r == -ENOENT || (getuid() != 0 && r == -EACCES) || r == -EOPNOTSUPP;
bool ok = r == -ENOENT || r == -EACCES || r == -EOPNOTSUPP;
log_full_errno(ok ? LOG_DEBUG : LOG_ERR, r, "Failed to read EFI loader data: %m");
return ok ? 0 : r;
@ -59,7 +59,7 @@ static int test_boot_timestamps(void) {
r = boot_timestamps(NULL, &fw, &l);
if (r < 0) {
bool ok = r == -ENOENT || (getuid() != 0 && r == -EACCES) || r == -EOPNOTSUPP;
bool ok = r == -ENOENT || r == -EACCES || r == -EOPNOTSUPP;
log_full_errno(ok ? LOG_DEBUG : LOG_ERR, r, "Failed to read variables: %m");
return ok ? 0 : r;

View File

@ -14,6 +14,7 @@
#include "bus-error.h"
#include "bus-log-control-api.h"
#include "bus-polkit.h"
#include "bus-util.h"
#include "clock-util.h"
#include "conf-files.h"
#include "def.h"
@ -28,6 +29,7 @@
#include "missing_capability.h"
#include "path-util.h"
#include "selinux-util.h"
#include "service-util.h"
#include "signal-util.h"
#include "string-util.h"
#include "strv.h"
@ -1085,6 +1087,12 @@ static const sd_bus_vtable timedate_vtable[] = {
SD_BUS_VTABLE_END,
};
const BusObjectImplementation manager_object = {
"/org/freedesktop/timedate1",
"org.freedesktop.timedate1",
.vtables = BUS_VTABLES(timedate_vtable),
};
static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
int r;
@ -1097,9 +1105,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
if (r < 0)
return log_error_errno(r, "Failed to get system bus connection: %m");
r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/timedate1", "org.freedesktop.timedate1", timedate_vtable, c);
r = bus_add_implementation(bus, &manager_object, c);
if (r < 0)
return log_error_errno(r, "Failed to register object: %m");
return r;
r = bus_log_control_api_register(bus);
if (r < 0)
@ -1126,10 +1134,15 @@ static int run(int argc, char *argv[]) {
log_setup_service();
umask(0022);
r = service_parse_argv("systemd-timedated.service",
"Manage the system clock and timezone and NTP enablement.",
BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object),
argc, argv);
if (r <= 0)
return r;
if (argc != 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
umask(0022);
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);

View File

@ -3,10 +3,10 @@
import collections
import sys
import os
import shlex
import subprocess
import io
import pprint
from lxml import etree
PARSER = etree.XMLParser(no_network=True,
@ -19,23 +19,6 @@ PRINT_ERRORS = True
class NoCommand(Exception):
pass
def find_command(lines):
acc = []
for num, line in enumerate(lines):
# skip empty leading line
if num == 0 and not line:
continue
cont = line.endswith('\\')
if cont:
line = line[:-1].rstrip()
acc.append(line if not acc else line.lstrip())
if not cont:
break
joined = ' '.join(acc)
if not joined.startswith('$ '):
raise NoCommand
return joined[2:], lines[:num+1] + [''], lines[-1]
BORING_INTERFACES = [
'org.freedesktop.DBus.Peer',
'org.freedesktop.DBus.Introspectable',
@ -183,31 +166,27 @@ def xml_to_text(destination, xml, *, only_interface=None):
return file.getvalue(), declarations, interfaces
def subst_output(document, programlisting):
try:
cmd, prefix_lines, footer = find_command(programlisting.text.splitlines())
except NoCommand:
executable = programlisting.get('executable', None)
if executable is None:
# Not our thing
return
executable = programlisting.get('executable')
node = programlisting.get('node')
interface = programlisting.get('interface')
only_interface = programlisting.get('interface', None)
argv = shlex.split(cmd)
argv += ['--xml']
argv = [f'{build_dir}/{executable}', f'--bus-introspect={interface}']
print(f'COMMAND: {shlex.join(argv)}')
object_idx = argv.index('--object-path')
object_path = argv[object_idx + 1]
try:
out = subprocess.check_output(argv, text=True)
except subprocess.CalledProcessError:
print('command failed, ignoring', file=sys.stderr)
except FileNotFoundError:
print(f'{executable} not found, ignoring', file=sys.stderr)
return
xml = etree.fromstring(out, parser=PARSER)
new_text, declarations, interfaces = xml_to_text(object_path, xml, only_interface=only_interface)
programlisting.text = '\n'.join(prefix_lines) + '\n' + new_text + footer
new_text, declarations, interfaces = xml_to_text(node, xml, only_interface=interface)
programlisting.text = '\n' + new_text + ' '
if declarations:
missing = check_documented(document, declarations)
@ -291,5 +270,14 @@ def process(page):
if __name__ == '__main__':
pages = sys.argv[1:]
if pages[0].startswith('--build-dir='):
build_dir = pages[0].partition('=')[2]
pages = pages[1:]
else:
build_dir = 'build'
if not os.path.exists(f'{build_dir}/systemd'):
exit(f"{build_dir}/systemd doesn't exist. Use --build-dir=.")
for page in pages:
process(page)

View File

@ -8,7 +8,7 @@
# (at your option) any later version.
[Unit]
Description=Login Service
Description=User Login Management
Documentation=man:systemd-logind.service(8) man:logind.conf(5)
Documentation=https://www.freedesktop.org/wiki/Software/systemd/logind
Documentation=https://www.freedesktop.org/wiki/Software/systemd/multiseat