Merge pull request #15473 from keszybz/bus-introspection

This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-05-06 15:00:07 +02:00
commit ba5a389d24
87 changed files with 2548 additions and 1123 deletions

View File

@ -34,6 +34,7 @@ custom_entities_ent = configure_file(
man_pages = [] man_pages = []
html_pages = [] html_pages = []
source_xml_files = [] source_xml_files = []
dbus_docs = []
foreach tuple : xsltproc.found() ? manpages : [] foreach tuple : xsltproc.found() ? manpages : []
stem = tuple[0] stem = tuple[0]
section = tuple[1] section = tuple[1]
@ -90,7 +91,11 @@ foreach tuple : xsltproc.found() ? manpages : []
install_dir : join_paths(docdir, 'html')) install_dir : join_paths(docdir, 'html'))
html_pages += p3 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 else
message('Skipping @0@.@1@ because @2@ is false'.format(stem, section, condition)) message('Skipping @0@.@1@ because @2@ is false'.format(stem, section, condition))
endif 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() if git.found()
custom_target( custom_target(
'update-man-rules', '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> <para>The service exposes the following interfaces on the bus:</para>
<programlisting> <programlisting executable="systemd-hostnamed" node="/org/freedesktop/hostname1" interface="org.freedesktop.hostname1">
$ gdbus introspect --system \
--dest org.freedesktop.hostname1 \
--object-path /org/freedesktop/hostname1
node /org/freedesktop/hostname1 { node /org/freedesktop/hostname1 {
interface org.freedesktop.hostname1 { interface org.freedesktop.hostname1 {
methods: methods:
@ -349,6 +345,19 @@ node /org/freedesktop/hostname1 {
the usual interface versioning guidelines</ulink>.</para> the usual interface versioning guidelines</ulink>.</para>
</refsect1> </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> <refsect1>
<title>See also</title> <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> <para>The service exposes the following interfaces on the Manager object on the bus:</para>
<programlisting> <programlisting executable="systemd-importd" node="/org/freedesktop/import1" interface="org.freedesktop.import1.Manager">
$ gdbus introspect --system \
--dest org.freedesktop.import1 \
--object-path /org/freedesktop/import1
node /org/freedesktop/import1 { node /org/freedesktop/import1 {
interface org.freedesktop.import1.Manager { interface org.freedesktop.import1.Manager {
methods: methods:
@ -238,11 +234,7 @@ node /org/freedesktop/import1 {
<refsect1> <refsect1>
<title>The Transfer Object</title> <title>The Transfer Object</title>
<programlisting> <programlisting executable="systemd-importd" node="/org/freedesktop/import1/transfer/_1" interface="org.freedesktop.import1.Transfer">
$ gdbus introspect --system \
--dest org.freedesktop.import1 \
--object-path /org/freedesktop/import1/transfer/_1
node /org/freedesktop/import1/transfer/_1 { node /org/freedesktop/import1/transfer/_1 {
interface org.freedesktop.import1.Transfer { interface org.freedesktop.import1.Transfer {
methods: methods:
@ -325,6 +317,28 @@ node /org/freedesktop/import1/transfer/_1 {
</refsect2> </refsect2>
</refsect1> </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> <refsect1>
<title>Versioning</title> <title>Versioning</title>

View File

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

View File

@ -38,11 +38,7 @@
<para>The service exposes the following interfaces on the Manager object on the bus:</para> <para>The service exposes the following interfaces on the Manager object on the bus:</para>
<programlisting> <programlisting executable="systemd-logind" node="/org/freedesktop/login1" interface="org.freedesktop.login1.Manager">
$ gdbus introspect --system \
--dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1
node /org/freedesktop/login1 { node /org/freedesktop/login1 {
interface org.freedesktop.login1.Manager { interface org.freedesktop.login1.Manager {
methods: methods:
@ -741,10 +737,7 @@ node /org/freedesktop/login1 {
<refsect1> <refsect1>
<title>Seat Objects</title> <title>Seat Objects</title>
<programlisting> <programlisting executable="systemd-logind" node="/org/freedesktop/login1/seat/seat0" interface="org.freedesktop.login1.Seat">
$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1/seat/seat0
node /org/freedesktop/login1/seat/seat0 { node /org/freedesktop/login1/seat/seat0 {
interface org.freedesktop.login1.Seat { interface org.freedesktop.login1.Seat {
methods: methods:
@ -758,8 +751,6 @@ node /org/freedesktop/login1/seat/seat0 {
readonly s Id = '...'; readonly s Id = '...';
readonly (so) ActiveSession = ...; readonly (so) ActiveSession = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b CanMultiSession = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b CanTTY = ...; readonly b CanTTY = ...;
readonly b CanGraphical = ...; readonly b CanGraphical = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false") @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="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="CanTTY"/>
<variablelist class="dbus-property" generated="True" extra-ref="CanGraphical"/> <variablelist class="dbus-property" generated="True" extra-ref="CanGraphical"/>
@ -827,7 +816,7 @@ node /org/freedesktop/login1/seat/seat0 {
<title>Signals</title> <title>Signals</title>
<para>Whenever <function>ActiveSession</function>, <function>Sessions</function>, <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 or the idle state changes, <function>PropertyChanged</function> signals are sent out to which clients
can subscribe.</para> can subscribe.</para>
</refsect2> </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 <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> structure consisting of the session id and the object path.</para>
<para><varname>CanMultiSession</varname> encodes whether the session is multi-session capable, <para><varname>CanTTY</varname> encodes whether the session is suitable for text logins, and
<varname>CanTTY</varname> whether it is suitable for text logins, <varname>CanGraphical</varname> <varname>CanGraphical</varname> whether it is suitable for graphical sessions.</para>
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 <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> encoded in a structure consisting of the ID and the object path.</para>
@ -856,10 +844,7 @@ node /org/freedesktop/login1/seat/seat0 {
<refsect1> <refsect1>
<title>User Objects</title> <title>User Objects</title>
<programlisting> <programlisting executable="systemd-logind" node="/org/freedesktop/login1/user/_1000" interface="org.freedesktop.login1.User">
$ gdbus introspect --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1/user/_1000
node /org/freedesktop/login1/user/_1000 { node /org/freedesktop/login1/user/_1000 {
interface org.freedesktop.login1.User { interface org.freedesktop.login1.User {
methods: methods:
@ -1004,11 +989,8 @@ node /org/freedesktop/login1/user/_1000 {
<refsect1> <refsect1>
<title>Session Objects</title> <title>Session Objects</title>
<programlisting> <programlisting executable="systemd-logind" node="/org/freedesktop/login1/session/1" interface="org.freedesktop.login1.Session">
$ gdbus introspect --system --dest org.freedesktop.login1 \ node /org/freedesktop/login1/session/1 {
--object-path /org/freedesktop/login1/session/45
node /org/freedesktop/login1/session/45 {
interface org.freedesktop.login1.Session { interface org.freedesktop.login1.Session {
methods: methods:
Terminate(); Terminate();
@ -1021,6 +1003,7 @@ node /org/freedesktop/login1/session/45 {
in i signal_number); in i signal_number);
TakeControl(in b force); TakeControl(in b force);
ReleaseControl(); ReleaseControl();
SetType(in s type);
TakeDevice(in u major, TakeDevice(in u major,
in u minor, in u minor,
out h fd, out h fd,
@ -1076,7 +1059,6 @@ node /org/freedesktop/login1/session/45 {
readonly u Leader = ...; readonly u Leader = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly u Audit = ...; readonly u Audit = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Type = '...'; readonly s Type = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Class = '...'; readonly s Class = '...';
@ -1093,6 +1075,100 @@ node /org/freedesktop/login1/session/45 {
}; };
</programlisting> </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> <refsect2>
<title>Methods</title> <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 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> 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 <para><function>ReleaseControl()</function> drops control of a given session. Closing the D-Bus
D-Bus connection implicitly releases control as well. See <function>TakeControl()</function> for more information. This connection implicitly releases control as well. See <function>TakeControl()</function> for more
method also releases all devices for which the controller requested ownership via <function>TakeDevice()</function>. information. This method also releases all devices for which the controller requested ownership via
</para> <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 <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 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> </refsect2>
</refsect1> </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> <refsect1>
<title>Versioning</title> <title>Versioning</title>

View File

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

View File

@ -46,11 +46,7 @@
<para>The service exposes the following interfaces on the Manager object on the bus:</para> <para>The service exposes the following interfaces on the Manager object on the bus:</para>
<programlisting> <programlisting executable="systemd-resolved" node="/org/freedesktop/resolve1" interface="org.freedesktop.resolve1.Manager">
$ gdbus introspect --system \
--dest org.freedesktop.resolve1 \
--object-path /org/freedesktop/resolve1
node /org/freedesktop/resolve1 { node /org/freedesktop/resolve1 {
interface org.freedesktop.resolve1.Manager { interface org.freedesktop.resolve1.Manager {
methods: methods:
@ -145,9 +141,6 @@ node /org/freedesktop/resolve1 {
readonly as DNSSECNegativeTrustAnchors = ['...', ...]; readonly as DNSSECNegativeTrustAnchors = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("false") @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s DNSStubListener = '...'; 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.Peer { ... };
interface org.freedesktop.DBus.Introspectable { ... }; 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="DNSStubListener"/>
<variablelist class="dbus-property" generated="True" extra-ref="LogLevel"/>
<!--End of Autogenerated section--> <!--End of Autogenerated section-->
<refsect2> <refsect2>
@ -551,12 +542,8 @@ node /org/freedesktop/resolve1 {
<refsect1> <refsect1>
<title>Link Object</title> <title>Link Object</title>
<programlisting> <programlisting executable="systemd-resolved" node="/org/freedesktop/resolve1/link/_1" interface="org.freedesktop.resolve1.Link">
$ gdbus introspect --system \ node /org/freedesktop/resolve1/link/_1 {
--dest org.freedesktop.resolve1 \
--object-path /org/freedesktop/resolve1/link/_34
node /org/freedesktop/resolve1/link/_34 {
interface org.freedesktop.resolve1.Link { interface org.freedesktop.resolve1.Link {
methods: methods:
SetDNS(in a(iay) addresses); SetDNS(in a(iay) addresses);
@ -790,6 +777,30 @@ node /org/freedesktop/resolve1/link/_34 {
</variablelist> </variablelist>
</refsect1> </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> <refsect1>
<title>Versioning</title> <title>Versioning</title>

View File

@ -57,11 +57,7 @@
<para>The main entry point object is available on the fixed <para>The main entry point object is available on the fixed
<constant>/org/freedesktop/systemd1</constant> object path:</para> <constant>/org/freedesktop/systemd1</constant> object path:</para>
<programlisting> <programlisting executable="systemd" node="/org/freedesktop/systemd1" interface="org.freedesktop.systemd1.Manager">
$ gdbus introspect --system \
--dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1
node /org/freedesktop/systemd1 { node /org/freedesktop/systemd1 {
interface org.freedesktop.systemd1.Manager { interface org.freedesktop.systemd1.Manager {
methods: methods:
@ -1484,10 +1480,7 @@ node /org/freedesktop/systemd1 {
<refsect1> <refsect1>
<title>Unit Objects</title> <title>Unit Objects</title>
<programlisting interface="org.freedesktop.systemd1.Unit"> <programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice" interface="org.freedesktop.systemd1.Unit">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice
node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
interface org.freedesktop.systemd1.Unit { interface org.freedesktop.systemd1.Unit {
methods: methods:
@ -1674,7 +1667,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
interface org.freedesktop.DBus.Peer { ... }; interface org.freedesktop.DBus.Peer { ... };
interface org.freedesktop.DBus.Introspectable { ... }; interface org.freedesktop.DBus.Introspectable { ... };
interface org.freedesktop.DBus.Properties { ... }; interface org.freedesktop.DBus.Properties { ... };
interface org.freedesktop.systemd1.Service { ... };
}; };
</programlisting> </programlisting>
@ -1746,12 +1738,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<!--Autogenerated cross-references for systemd.directives, do not edit--> <!--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.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.Unit"/>
<variablelist class="dbus-method" generated="True" extra-ref="Start()"/> <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 <interfacename>org.freedesktop.systemd1.Service</interfacename> interface (described here) in addition to
the generic <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para> the generic <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Service"> <programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice" interface="org.freedesktop.systemd1.Service">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice
node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
interface org.freedesktop.systemd1.Service { interface org.freedesktop.systemd1.Service {
methods: methods:
@ -3135,14 +3120,14 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<!--Autogenerated cross-references for systemd.directives, do not edit--> <!--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.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Service"/> <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.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="GetProcesses()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/> <variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/>
@ -3746,10 +3731,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<refsect1> <refsect1>
<title>Socket Unit Objects</title> <title>Socket Unit Objects</title>
<programlisting interface="org.freedesktop.systemd1.Socket"> <programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket" interface="org.freedesktop.systemd1.Socket">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket
node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
interface org.freedesktop.systemd1.Socket { interface org.freedesktop.systemd1.Socket {
methods: methods:
@ -4777,14 +4759,14 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
<!--Autogenerated cross-references for systemd.directives, do not edit--> <!--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.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Socket"/> <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.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="GetProcesses()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/> <variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/>
@ -5340,10 +5322,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
<refsect1> <refsect1>
<title>Target Unit Objects</title> <title>Target Unit Objects</title>
<programlisting interface="org.freedesktop.systemd1.Target"> <programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/basic_2etarget" interface="org.freedesktop.systemd1.Target">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/basic_2etarget
node /org/freedesktop/systemd1/unit/basic_2etarget { node /org/freedesktop/systemd1/unit/basic_2etarget {
interface org.freedesktop.systemd1.Target { 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) <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> in addition to the generic <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Device"> <programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/dev_2dttyS0_2edevice" interface="org.freedesktop.systemd1.Device">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \ node /org/freedesktop/systemd1/unit/dev_2dttyS0_2edevice {
--object-path /org/freedesktop/systemd1/unit/dev_2dfoo_2edevice
node /org/freedesktop/systemd1/unit/dev_2dfoo_2edevice {
interface org.freedesktop.systemd1.Device { interface org.freedesktop.systemd1.Device {
properties: properties:
readonly s SysFSPath = '...'; readonly s SysFSPath = '...';
@ -5382,14 +5358,14 @@ node /org/freedesktop/systemd1/unit/dev_2dfoo_2edevice {
<!--Autogenerated cross-references for systemd.directives, do not edit--> <!--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.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Device"/> <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.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Device"/>
<variablelist class="dbus-property" generated="True" extra-ref="SysFSPath"/> <variablelist class="dbus-property" generated="True" extra-ref="SysFSPath"/>
<!--End of Autogenerated section--> <!--End of Autogenerated section-->
@ -5411,10 +5387,7 @@ node /org/freedesktop/systemd1/unit/dev_2dfoo_2edevice {
interface (described here) in addition to the generic interface (described here) in addition to the generic
<interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para> <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Mount"> <programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/home_2emount" interface="org.freedesktop.systemd1.Mount">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/home_2emount
node /org/freedesktop/systemd1/unit/home_2emount { node /org/freedesktop/systemd1/unit/home_2emount {
interface org.freedesktop.systemd1.Mount { interface org.freedesktop.systemd1.Mount {
methods: methods:
@ -6291,14 +6264,14 @@ node /org/freedesktop/systemd1/unit/home_2emount {
<!--Autogenerated cross-references for systemd.directives, do not edit--> <!--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.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Mount"/> <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.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="GetProcesses()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/> <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 <interfacename>org.freedesktop.systemd1.Automount</interfacename> interface (described here) in addition
to the generic <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para> to the generic <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Automount"> <programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount" interface="org.freedesktop.systemd1.Automount">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount
node /org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount { node /org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount {
interface org.freedesktop.systemd1.Automount { interface org.freedesktop.systemd1.Automount {
properties: 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--> <!--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.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Automount"/> <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.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="Where"/>
<variablelist class="dbus-property" generated="True" extra-ref="DirectoryMode"/> <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 interface (described here) in addition to the generic
<interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para> <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Timer"> <programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer" interface="org.freedesktop.systemd1.Timer">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer
node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer { node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer {
interface org.freedesktop.systemd1.Timer { interface org.freedesktop.systemd1.Timer {
properties: properties:
@ -6901,14 +6868,14 @@ node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer {
<!--Autogenerated cross-references for systemd.directives, do not edit--> <!--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.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Timer"/> <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.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="Unit"/>
<variablelist class="dbus-property" generated="True" extra-ref="TimersMonotonic"/> <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 interface (described here) in addition to the generic
<interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para> <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Swap"> <programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/dev_2dsda3_2eswap" interface="org.freedesktop.systemd1.Swap">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap
node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
interface org.freedesktop.systemd1.Swap { interface org.freedesktop.systemd1.Swap {
methods: methods:
@ -7836,14 +7800,14 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
<!--Autogenerated cross-references for systemd.directives, do not edit--> <!--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.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Swap"/> <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.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="GetProcesses()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/> <variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/>
@ -8306,10 +8270,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
<refsect1> <refsect1>
<title>Path Unit Objects</title> <title>Path Unit Objects</title>
<programlisting interface="org.freedesktop.systemd1.Path"> <programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/cups_2epath" interface="org.freedesktop.systemd1.Path">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/cups_2epath
node /org/freedesktop/systemd1/unit/cups_2epath { node /org/freedesktop/systemd1/unit/cups_2epath {
interface org.freedesktop.systemd1.Path { interface org.freedesktop.systemd1.Path {
properties: properties:
@ -8336,14 +8297,14 @@ node /org/freedesktop/systemd1/unit/cups_2epath {
<!--Autogenerated cross-references for systemd.directives, do not edit--> <!--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.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Path"/> <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.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="Unit"/>
<variablelist class="dbus-property" generated="True" extra-ref="Paths"/> <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 interface (described here) in addition to the generic
<interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para> <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Slice"> <programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/system_2eslice" interface="org.freedesktop.systemd1.Slice">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/system_2eslice
node /org/freedesktop/systemd1/unit/system_2eslice { node /org/freedesktop/systemd1/unit/system_2eslice {
interface org.freedesktop.systemd1.Slice { interface org.freedesktop.systemd1.Slice {
methods: methods:
@ -8645,14 +8603,14 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
<!--Autogenerated cross-references for systemd.directives, do not edit--> <!--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.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Slice"/> <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.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="GetProcesses()"/>
<variablelist class="dbus-method" generated="True" extra-ref="AttachProcesses()"/> <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 interface (described here) in addition to the generic
<interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para> <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>
<programlisting interface="org.freedesktop.systemd1.Scope"> <programlisting executable="systemd" node="/org/freedesktop/systemd1/unit/session_2d1_2escope" interface="org.freedesktop.systemd1.Scope">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \
--object-path /org/freedesktop/systemd1/unit/session_2d1_2escope
node /org/freedesktop/systemd1/unit/session_2d1_2escope { node /org/freedesktop/systemd1/unit/session_2d1_2escope {
interface org.freedesktop.systemd1.Scope { interface org.freedesktop.systemd1.Scope {
methods: methods:
@ -9097,14 +9052,14 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
<!--Autogenerated cross-references for systemd.directives, do not edit--> <!--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.Unit"/>
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Scope"/> <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.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="Abandon()"/>
<variablelist class="dbus-method" generated="True" extra-ref="GetProcesses()"/> <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 <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> execution queue. Each job is attached to exactly one unit.</para>
<programlisting> <programlisting executable="systemd" node="/org/freedesktop/systemd1/job/666" interface="org.freedesktop.systemd1.Job">
$ gdbus introspect --system --dest org.freedesktop.systemd1 \ node /org/freedesktop/systemd1/job/666 {
--object-path /org/freedesktop/systemd1/job/1292
node /org/freedesktop/systemd1/job/1292 {
interface org.freedesktop.systemd1.Job { interface org.freedesktop.systemd1.Job {
methods: methods:
Cancel(); Cancel();
@ -9373,6 +9325,41 @@ node /org/freedesktop/systemd1/job/1292 {
</refsect2> </refsect2>
</refsect1> </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> <refsect1>
<title>Versioning</title> <title>Versioning</title>

View File

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

View File

@ -44,6 +44,8 @@ manpages = [
['nss-mymachines', '8', ['libnss_mymachines.so.2'], 'ENABLE_NSS_MYMACHINES'], ['nss-mymachines', '8', ['libnss_mymachines.so.2'], 'ENABLE_NSS_MYMACHINES'],
['nss-resolve', '8', ['libnss_resolve.so.2'], 'ENABLE_NSS_RESOLVE'], ['nss-resolve', '8', ['libnss_resolve.so.2'], 'ENABLE_NSS_RESOLVE'],
['nss-systemd', '8', ['libnss_systemd.so.2'], 'ENABLE_NSS_SYSTEMD'], ['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.hostname1', '5', [], 'ENABLE_HOSTNAMED'],
['org.freedesktop.import1', '5', [], 'ENABLE_IMPORTD'], ['org.freedesktop.import1', '5', [], 'ENABLE_IMPORTD'],
['org.freedesktop.locale1', '5', [], 'ENABLE_LOCALED'], ['org.freedesktop.locale1', '5', [], 'ENABLE_LOCALED'],

View File

@ -56,7 +56,9 @@
is a command line client to this service.</para> is a command line client to this service.</para>
<para>See <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> for a description of the D-Bus API.</para>
</refsect1> </refsect1>

View File

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

View File

@ -41,7 +41,9 @@
is a command line client to this service.</para> is a command line client to this service.</para>
<para>See <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> for a description of the D-Bus API.</para>
</refsect1> </refsect1>

View File

@ -79,7 +79,9 @@
such as users, sessions and seats.</para> such as users, sessions and seats.</para>
<para>See <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> for information about the D-Bus APIs <filename>systemd-logind</filename> provides.</para>
<para>For more information on the inhibition logic see the <ulink <para>For more information on the inhibition logic see the <ulink

View File

@ -107,7 +107,9 @@
For more information please consult For more information please consult
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry> <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>
and 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>
<para>A small companion daemon <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, <listitem><para>The native, fully-featured API <command>systemd-resolved</command> exposes on the bus,
see see
<citerefentry><refentrytitle>org.freedesktop.resolve1</refentrytitle><manvolnum>5</manvolnum></citerefentry> <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 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 featured (for example, properly returns DNSSEC validation status and interface scope for addresses as
necessary for supporting link-local networking).</para></listitem> necessary for supporting link-local networking).</para></listitem>

View File

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

View File

@ -281,7 +281,10 @@
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para> <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
<para>The D-Bus API of <command>systemd</command> is described in <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 <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 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 # 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 # the wrong result when systemd is being built as a meson subproject
project_source_root = meson.current_source_dir() project_source_root = meson.current_source_dir()
project_build_root = meson.current_build_dir()
relative_source_path = run_command('realpath', 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() project_source_root).stdout().strip()
conf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path) 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('MEMORY_ACCOUNTING_DEFAULT', memory_accounting_default ? 'yes' : 'no')
substs.set('STATUS_UNIT_FORMAT_DEFAULT', status_unit_format_default) substs.set('STATUS_UNIT_FORMAT_DEFAULT', status_unit_format_default)
substs.set('HIGH_RLIMIT_NOFILE', conf.get('HIGH_RLIMIT_NOFILE')) 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', output : 'systemd-runtest.env',
command : ['sh', '-c', '{ ' + command : ['sh', '-c', '{ ' +
'echo SYSTEMD_TEST_DATA=@0@; '.format(join_paths(project_source_root, 'test')) + '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@'], '} >@OUTPUT@'],
build_by_default : true) build_by_default : true)

View File

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

View File

@ -140,6 +140,58 @@ const sd_bus_vtable bus_job_vtable[] = {
SD_BUS_VTABLE_END 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) { static int send_new_signal(sd_bus *bus, void *userdata) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
_cleanup_free_ char *p = NULL; _cleanup_free_ char *p = NULL;

View File

@ -2,11 +2,12 @@
#pragma once #pragma once
#include "sd-bus.h" #include "sd-bus.h"
#include "sd-bus-vtable.h"
#include "unit.h" #include "unit.h"
#include "bus-util.h"
extern const sd_bus_vtable bus_job_vtable[]; 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_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); 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 #pragma once
#include "sd-bus.h" #include "sd-bus.h"
#include "sd-bus-vtable.h"
#include "unit.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 #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) { 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 */ Unit *u = NULL; /* just to appease gcc, initialization is not really necessary */
int r; int r;
@ -472,32 +453,6 @@ static int bus_kill_context_find(sd_bus *bus, const char *path, const char *inte
return 1; 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) { 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; _cleanup_strv_free_ char **l = NULL;
Manager *m = userdata; Manager *m = userdata;
@ -522,8 +477,147 @@ static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, cha
return k; 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) { static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
UnitType t;
int r; int r;
assert(m); 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"); return log_error_errno(r, "Failed to add SELinux access filter: %m");
#endif #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) 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); return bus_add_implementation(bus, &manager_log_control_object, 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;
} }
static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) { 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); uint64_t manager_bus_n_queued_write(Manager *m);
void dump_bus_properties(FILE *f); 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, .active_state = device_active_state,
.sub_state_to_string = device_sub_state_to_string, .sub_state_to_string = device_sub_state_to_string,
.bus_vtable = bus_device_vtable,
.following = device_following, .following = device_following,
.following_set = device_following_set, .following_set = device_following_set,

View File

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

View File

@ -830,6 +830,5 @@ const UnitVTable path_vtable = {
.reset_failed = path_reset_failed, .reset_failed = path_reset_failed,
.bus_vtable = bus_path_vtable,
.bus_set_property = bus_path_set_property, .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, .notify_cgroup_empty = scope_notify_cgroup_empty_event,
.bus_vtable = bus_scope_vtable,
.bus_set_property = bus_scope_set_property, .bus_set_property = bus_scope_set_property,
.bus_commit_properties = bus_scope_commit_properties, .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_name_owner_change = service_bus_name_owner_change,
.bus_vtable = bus_service_vtable,
.bus_set_property = bus_service_set_property, .bus_set_property = bus_service_set_property,
.bus_commit_properties = bus_service_commit_properties, .bus_commit_properties = bus_service_commit_properties,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -600,9 +600,6 @@ typedef struct UnitVTable {
* of this type will immediately fail. */ * of this type will immediately fail. */
bool (*supported)(void); bool (*supported)(void);
/* The bus vtable */
const sd_bus_vtable *bus_vtable;
/* The strings to print in status messages */ /* The strings to print in status messages */
UnitStatusMessageFormats status_message_formats; 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. */ /* We map a uid_t as uint32_t bus property, let's ensure this is safe. */
assert_cc(sizeof(uid_t) == sizeof(uint32_t)); 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) { int bus_home_path(Home *h, char **ret) {
assert(ret); assert(ret);
return sd_bus_path_encode("/org/freedesktop/home1/home", h->user_name, 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, sd_bus *bus,
const char *path, const char *path,
const char *interface, const char *interface,
@ -772,7 +747,7 @@ int bus_home_object_find(
return 1; return 1;
} }
int bus_home_node_enumerator( static int bus_home_node_enumerator(
sd_bus *bus, sd_bus *bus,
const char *path, const char *path,
void *userdata, void *userdata,
@ -802,6 +777,107 @@ int bus_home_node_enumerator(
return 1; 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) { static int on_deferred_change(sd_event_source *s, void *userdata) {
_cleanup_free_ char *path = NULL; _cleanup_free_ char *path = NULL;
Home *h = userdata; Home *h = userdata;

View File

@ -3,6 +3,7 @@
#include "sd-bus.h" #include "sd-bus.h"
#include "bus-util.h"
#include "homed-home.h" #include "homed-home.h"
int bus_home_client_is_trusted(Home *h, sd_bus_message *message); 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_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); 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_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_change(Home *h);
int bus_home_emit_remove(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); 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_VTABLE_START(0),
SD_BUS_PROPERTY("AutoLogin", "a(sso)", property_get_auto_login, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), 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_WITH_NAMES("GetHomeByName",
SD_BUS_METHOD("GetHomeByUID", "u", "ssussso", method_get_home_by_uid, SD_BUS_VTABLE_UNPRIVILEGED), "s",
SD_BUS_METHOD("GetUserRecordByName", "s", "sbo", method_get_user_record_by_name, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), SD_BUS_PARAM(user_name),
SD_BUS_METHOD("GetUserRecordByUID", "u", "sbo", method_get_user_record_by_uid, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), "usussso",
SD_BUS_METHOD("ListHomes", NULL, "a(susussso)", method_list_homes, SD_BUS_VTABLE_UNPRIVILEGED), 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 /* The following methods directly execute an operation on a home area, without ref-counting, queueing
* or anything, and are accessible through homectl. */ * or anything, and are accessible through homectl. */
SD_BUS_METHOD("ActivateHome", "ss", NULL, method_activate_home, SD_BUS_VTABLE_SENSITIVE), SD_BUS_METHOD_WITH_NAMES("ActivateHome",
SD_BUS_METHOD("DeactivateHome", "s", NULL, method_deactivate_home, 0), "ss",
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_PARAM(user_name)
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_PARAM(user_record),
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 */ NULL,,
SD_BUS_METHOD("RealizeHome", "ss", NULL, method_realize_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Create $HOME for already registered JSON entry */ method_activate_home,
SD_BUS_METHOD("RemoveHome", "s", NULL, method_remove_home, SD_BUS_VTABLE_UNPRIVILEGED), /* Remove JSON record and remove $HOME */ SD_BUS_VTABLE_SENSITIVE),
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_WITH_NAMES("DeactivateHome",
SD_BUS_METHOD("AuthenticateHome", "ss", NULL, method_authenticate_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), /* Just check credentials */ "s",
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_PARAM(user_name),
SD_BUS_METHOD("ResizeHome", "sts", NULL, method_resize_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), NULL,,
SD_BUS_METHOD("ChangePasswordHome", "sss", NULL, method_change_password_home, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), method_deactivate_home,
SD_BUS_METHOD("LockHome", "s", NULL, method_lock_home, 0), /* Prepare active home for system suspend: flush out passwords, suspend access */ 0),
SD_BUS_METHOD("UnlockHome", "ss", NULL, method_unlock_home, SD_BUS_VTABLE_SENSITIVE), /* Make $HOME usable after system resume again */
/* The following methods implement ref-counted activation, and are what the PAM module calls (and /* Add the JSON record to homed, but don't create actual $HOME */
* what "homectl with" runs). In contrast to the methods above which fail if an operation is already SD_BUS_METHOD_WITH_NAMES("RegisterHome",
* being executed on a home directory, these ones will queue the request, and are thus more "s",
* reliable. Moreover, they are a bit smarter: AcquireHome() will fixate, activate, unlock, or SD_BUS_PARAM(home_record),
* authenticate depending on the state of the home, so that the end result is always the same NULL,,
* (i.e. the home directory is accessible), and we always validate the specified passwords. RefHome() method_register_home,
* will not authenticate, and thus only works if home is already active. */ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("AcquireHome", "ssb", "h", method_acquire_home, SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("RefHome", "sb", "h", method_ref_home, 0), /* Remove the JSON record from homed, but don't remove actual $HOME */
SD_BUS_METHOD("ReleaseHome", "s", NULL, method_release_home, 0), 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 */ /* An operation that acts on all homes that allow it */
SD_BUS_METHOD("LockAllHomes", NULL, NULL, method_lock_all_homes, 0), 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 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) { static int on_deferred_auto_login(sd_event_source *s, void *userdata) {
Manager *m = userdata; Manager *m = userdata;
int r; int r;

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once #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) if (r < 0)
return log_error_errno(r, "Failed to connect to system bus: %m"); 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); 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/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);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -3,10 +3,13 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include "bus-log-control-api.h"
#include "daemon-util.h" #include "daemon-util.h"
#include "homed-manager.h" #include "homed-manager.h"
#include "homed-manager-bus.h"
#include "log.h" #include "log.h"
#include "main-func.h" #include "main-func.h"
#include "service-util.h"
#include "signal-util.h" #include "signal-util.h"
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
@ -16,10 +19,15 @@ static int run(int argc, char *argv[]) {
log_setup_service(); 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) umask(0022);
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
if (setenv("SYSTEMD_BYPASS_USERDB", "io.systemd.Home", 1) < 0) if (setenv("SYSTEMD_BYPASS_USERDB", "io.systemd.Home", 1) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set $SYSTEMD_BYPASS_USERDB: %m"); 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 "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "selinux-util.h" #include "selinux-util.h"
#include "service-util.h"
#include "signal-util.h" #include "signal-util.h"
#include "strv.h" #include "strv.h"
#include "user-util.h" #include "user-util.h"
@ -739,6 +740,12 @@ static const sd_bus_vtable hostname_vtable[] = {
SD_BUS_VTABLE_END, 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) { static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
int r; int r;
@ -751,9 +758,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get system bus connection: %m"); 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) if (r < 0)
return log_error_errno(r, "Failed to register object: %m"); return r;
r = bus_log_control_api_register(bus); r = bus_log_control_api_register(bus);
if (r < 0) if (r < 0)
@ -780,14 +787,17 @@ static int run(int argc, char *argv[]) {
log_setup_service(); 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); umask(0022);
mac_selinux_init(); 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); assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
r = sd_event_default(&event); r = sd_event_default(&event);

View File

@ -8,6 +8,7 @@
#include "alloc-util.h" #include "alloc-util.h"
#include "bus-common-errors.h" #include "bus-common-errors.h"
#include "bus-log-control-api.h" #include "bus-log-control-api.h"
#include "bus-util.h"
#include "bus-polkit.h" #include "bus-polkit.h"
#include "def.h" #include "def.h"
#include "fd-util.h" #include "fd-util.h"
@ -22,6 +23,7 @@
#include "path-util.h" #include "path-util.h"
#include "process-util.h" #include "process-util.h"
#include "signal-util.h" #include "signal-util.h"
#include "service-util.h"
#include "socket-util.h" #include "socket-util.h"
#include "stat-util.h" #include "stat-util.h"
#include "string-table.h" #include "string-table.h"
@ -488,11 +490,13 @@ static int transfer_start(Transfer *t) {
t->stdin_fd = safe_close(t->stdin_fd); 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) if (r < 0)
return r; 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) if (r < 0)
return r; return r;
@ -657,7 +661,8 @@ static int manager_new(Manager **ret) {
if (r < 0) if (r < 0)
return r; 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) if (r < 0)
return r; return r;
@ -718,13 +723,15 @@ static int method_import_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
return -EINVAL; return -EINVAL;
if (!machine_name_is_valid(local)) 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); r = setup_machine_directory(error);
if (r < 0) if (r < 0)
return r; 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); r = transfer_new(m, &t);
if (r < 0) if (r < 0)
@ -786,7 +793,8 @@ static int method_import_fs(sd_bus_message *msg, void *userdata, sd_bus_error *e
return r; return r;
if (!machine_name_is_valid(local)) 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); r = setup_machine_directory(error);
if (r < 0) if (r < 0)
@ -850,7 +858,8 @@ static int method_export_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_
return r; return r;
if (!machine_name_is_valid(local)) 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) if (fstat(fd, &st) < 0)
return -errno; 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)) if (!S_ISREG(st.st_mode) && !S_ISFIFO(st.st_mode))
return -EINVAL; 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); r = transfer_new(m, &t);
if (r < 0) 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; return r;
if (!http_url_is_valid(remote)) 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)) if (isempty(local))
local = NULL; local = NULL;
else if (!machine_name_is_valid(local)) 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)) if (isempty(verify))
v = IMPORT_VERIFY_SIGNATURE; v = IMPORT_VERIFY_SIGNATURE;
else else
v = import_verify_from_string(verify); v = import_verify_from_string(verify);
if (v < 0) 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); r = setup_machine_directory(error);
if (r < 0) if (r < 0)
return r; 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)) 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); r = transfer_new(m, &t);
if (r < 0) 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_type, transfer_type, TransferType);
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_verify, import_verify, ImportVerify); 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[] = { static const sd_bus_vtable transfer_vtable[] = {
SD_BUS_VTABLE_START(0), SD_BUS_VTABLE_START(0),
@ -1124,6 +1206,13 @@ static const sd_bus_vtable transfer_vtable[] = {
SD_BUS_VTABLE_END, 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[] = { static const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_START(0), SD_BUS_VTABLE_START(0),
@ -1230,76 +1319,21 @@ static const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_END, 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) { static const BusObjectImplementation manager_object = {
Manager *m = userdata; "/org/freedesktop/import1",
Transfer *t; "org.freedesktop.import1.Manager",
const char *p; .vtables = BUS_VTABLES(manager_vtable),
uint32_t id; .children = BUS_IMPLEMENTATIONS(&transfer_object),
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 int manager_add_bus_objects(Manager *m) { static int manager_add_bus_objects(Manager *m) {
int r; int r;
assert(m); 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) if (r < 0)
return log_error_errno(r, "Failed to register object: %m"); return r;
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");
r = bus_log_control_api_register(m->bus); r = bus_log_control_api_register(m->bus);
if (r < 0) if (r < 0)
@ -1340,12 +1374,15 @@ static int run(int argc, char *argv[]) {
log_setup_service(); 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) { umask(0022);
log_error("This program takes no arguments.");
return -EINVAL;
}
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0); assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0);

View File

@ -10,6 +10,63 @@
#include "memory-util.h" #include "memory-util.h"
#include "string-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) { int introspect_begin(struct introspect *i, bool trusted) {
assert(i); assert(i);
@ -40,12 +97,27 @@ int introspect_write_default_interfaces(struct introspect *i, bool object_manage
return 0; 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) { int introspect_write_child_nodes(struct introspect *i, Set *s, const char *prefix) {
char *node; char *node;
assert(i); assert(i);
assert(prefix); assert(prefix);
assert_se(set_interface_name(i, NULL) >= 0);
while ((node = set_steal_first(s))) { while ((node = set_steal_first(s))) {
const char *e; 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 sd_bus_vtable *vtable = v;
const char *names = ""; const char *names = "";
int r;
assert(i); assert(i);
assert(interface_name);
assert(v); 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)) { for (; v->type != _SD_BUS_VTABLE_END; v = bus_vtable_next(vtable, v)) {
/* Ignore methods, signals and properties that are /* Ignore methods, signals and properties that are
@ -178,6 +260,8 @@ int introspect_finish(struct introspect *i, char **ret) {
assert(i); assert(i);
assert_se(set_interface_name(i, NULL) >= 0);
fputs("</node>\n", i->f); fputs("</node>\n", i->f);
r = fflush_and_check(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 */ /* Normally introspect_finish() does all the work, this is just a backup for error paths */
safe_fclose(i->f); safe_fclose(i->f);
free(i->interface_name);
free(i->introspection); free(i->introspection);
} }

View File

@ -9,6 +9,7 @@
struct introspect { struct introspect {
FILE *f; FILE *f;
char *interface_name;
char *introspection; char *introspection;
size_t size; size_t size;
bool trusted; bool trusted;
@ -17,6 +18,9 @@ struct introspect {
int introspect_begin(struct introspect *i, bool trusted); int introspect_begin(struct introspect *i, bool trusted);
int introspect_write_default_interfaces(struct introspect *i, bool object_manager); 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_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); int introspect_finish(struct introspect *i, char **ret);
void introspect_free(struct introspect *i); void introspect_free(struct introspect *i);

View File

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

View File

@ -103,60 +103,3 @@ enum {
BUS_START_REPLY_SUCCESS = 1, BUS_START_REPLY_SUCCESS = 1,
BUS_START_REPLY_ALREADY_RUNNING = 2, 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); assert_se(introspect_begin(&intro, false) >= 0);
fprintf(intro.f, " <interface name=\"org.foo\">\n"); assert_se(introspect_write_interface(&intro, "org.foo", vtable) >= 0);
assert_se(introspect_write_interface(&intro, vtable) >= 0); /* write again to check if output looks OK for a different interface */
fputs(" </interface>\n", intro.f); assert_se(introspect_write_interface(&intro, "org.foo.bar", vtable) >= 0);
assert_se(introspect_finish(&intro, &s) == 0); assert_se(introspect_finish(&intro, &s) == 0);
fputs(s, stdout); fputs(s, stdout);
fputs("\n", stdout); fputs("\n", stdout);
} }

View File

@ -25,6 +25,7 @@
#include "missing_capability.h" #include "missing_capability.h"
#include "path-util.h" #include "path-util.h"
#include "selinux-util.h" #include "selinux-util.h"
#include "service-util.h"
#include "signal-util.h" #include "signal-util.h"
#include "string-util.h" #include "string-util.h"
#include "strv.h" #include "strv.h"
@ -709,6 +710,12 @@ static const sd_bus_vtable locale_vtable[] = {
SD_BUS_VTABLE_END 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) { static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
int r; int r;
@ -721,9 +728,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get system bus connection: %m"); 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) if (r < 0)
return log_error_errno(r, "Failed to register object: %m"); return r;
r = bus_log_control_api_register(bus); r = bus_log_control_api_register(bus);
if (r < 0) if (r < 0)
@ -754,12 +761,17 @@ static int run(int argc, char *argv[]) {
log_setup_service(); 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); umask(0022);
mac_selinux_init(); 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); assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
r = sd_event_default(&event); r = sd_event_default(&event);

View File

@ -3322,7 +3322,7 @@ fail:
return r; return r;
} }
const sd_bus_vtable manager_vtable[] = { static const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_START(0), SD_BUS_VTABLE_START(0),
SD_BUS_WRITABLE_PROPERTY("EnableWallMessages", "b", NULL, NULL, offsetof(Manager, enable_wall_messages), 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 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) { static int session_jobs_reply(Session *s, uint32_t jid, const char *unit, const char *result) {
assert(s); assert(s);
assert(unit); assert(unit);

View File

@ -3,6 +3,7 @@
#include "sd-bus.h" #include "sd-bus.h"
#include "bus-util.h"
#include "logind.h" #include "logind.h"
#include "logind-session.h" #include "logind-session.h"
#include "logind-user.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_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_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); 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); return sd_bus_reply_method_return(message, NULL);
} }
const sd_bus_vtable seat_vtable[] = { static int seat_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
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) {
_cleanup_free_ char *e = NULL; _cleanup_free_ char *e = NULL;
sd_bus_message *message; sd_bus_message *message;
Manager *m = userdata; Manager *m = userdata;
@ -373,7 +339,7 @@ char *seat_bus_path(Seat *s) {
return strjoin("/org/freedesktop/login1/seat/", t); 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; _cleanup_strv_free_ char **l = NULL;
sd_bus_message *message; sd_bus_message *message;
Manager *m = userdata; 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); 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 "sd-bus.h"
#include "logind-seat.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); char *seat_bus_path(Seat *s);
int seat_send_signal(Seat *s, bool new_seat); 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; return 1;
} }
const sd_bus_vtable session_vtable[] = { static int session_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
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) {
_cleanup_free_ char *e = NULL; _cleanup_free_ char *e = NULL;
sd_bus_message *message; sd_bus_message *message;
Manager *m = userdata; Manager *m = userdata;
@ -763,7 +629,7 @@ char *session_bus_path(Session *s) {
return strjoin("/org/freedesktop/login1/session/", t); 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; _cleanup_strv_free_ char **l = NULL;
sd_bus_message *message; sd_bus_message *message;
Manager *m = userdata; Manager *m = userdata;
@ -964,3 +830,144 @@ int session_send_create_reply(Session *s, sd_bus_error *error) {
(uint32_t) s->vtnr, (uint32_t) s->vtnr,
false); 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" #include "logind-session.h"
extern const sd_bus_vtable session_vtable[]; extern const BusObjectImplementation session_object;
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);
char *session_bus_path(Session *s); char *session_bus_path(Session *s);
int session_send_signal(Session *s, bool new_session); 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); return sd_bus_reply_method_return(message, NULL);
} }
const sd_bus_vtable user_vtable[] = { static int user_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
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) {
Manager *m = userdata; Manager *m = userdata;
uid_t uid; uid_t uid;
User *user; User *user;
@ -342,7 +313,7 @@ char *user_bus_path(User *u) {
return s; 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; _cleanup_strv_free_ char **l = NULL;
sd_bus_message *message; sd_bus_message *message;
Manager *m = userdata; Manager *m = userdata;
@ -391,6 +362,42 @@ int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***
return 1; 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) { int user_send_signal(User *u, bool new_user) {
_cleanup_free_ char *p = NULL; _cleanup_free_ char *p = NULL;

View File

@ -5,9 +5,8 @@
#include "logind-user.h" #include "logind-user.h"
extern const sd_bus_vtable user_vtable[]; extern const BusObjectImplementation user_object;
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);
char *user_bus_path(User *s); char *user_bus_path(User *s);
int user_send_signal(User *u, bool new_user); int user_send_signal(User *u, bool new_user);

View File

@ -27,6 +27,7 @@
#include "parse-util.h" #include "parse-util.h"
#include "process-util.h" #include "process-util.h"
#include "selinux-util.h" #include "selinux-util.h"
#include "service-util.h"
#include "signal-util.h" #include "signal-util.h"
#include "strv.h" #include "strv.h"
#include "terminal-util.h" #include "terminal-util.h"
@ -623,33 +624,13 @@ static int manager_connect_bus(Manager *m) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to connect to system bus: %m"); 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) 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) if (r < 0)
return log_error_errno(r, "Failed to add seat object vtable: %m"); return r;
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");
r = sd_bus_match_signal_async( r = sd_bus_match_signal_async(
m->bus, m->bus,
@ -707,10 +688,6 @@ static int manager_connect_bus(Manager *m) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to enable subscription: %m"); 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); r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.login1", 0, NULL, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to request name: %m"); 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_set_facility(LOG_AUTH);
log_setup_service(); 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) { umask(0022);
log_error("This program takes no arguments.");
return -EINVAL;
}
r = mac_selinux_init(); r = mac_selinux_init();
if (r < 0) if (r < 0)

View File

@ -157,8 +157,6 @@ int manager_read_utmp(Manager *m);
void manager_connect_utmp(Manager *m); void manager_connect_utmp(Manager *m);
void manager_reconnect_utmp(Manager *m); void manager_reconnect_utmp(Manager *m);
extern const sd_bus_vtable manager_vtable[];
/* gperf lookup function */ /* gperf lookup function */
const struct ConfigPerfItem* logind_gperf_lookup(const char *key, GPERF_LEN_TYPE length); 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); 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) { static int image_flush_cache(sd_event_source *s, void *userdata) {
Manager *m = userdata; Manager *m = userdata;
@ -388,7 +364,7 @@ static int image_flush_cache(sd_event_source *s, void *userdata) {
return 0; 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; _cleanup_free_ char *e = NULL;
Manager *m = userdata; Manager *m = userdata;
Image *image = NULL; Image *image = NULL;
@ -462,7 +438,7 @@ char *image_bus_path(const char *name) {
return strjoin("/org/freedesktop/machine1/image/", e); 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_hashmap_free_ Hashmap *images = NULL;
_cleanup_strv_free_ char **l = NULL; _cleanup_strv_free_ char **l = NULL;
Image *image; Image *image;
@ -497,3 +473,34 @@ int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char **
return 1; 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+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once #pragma once
#include "bus-util.h"
#include "machined.h" #include "machined.h"
extern const sd_bus_vtable image_vtable[]; extern const BusObjectImplementation image_object;
char *image_bus_path(const char *name); 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_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_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); 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); 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_VTABLE_START(0),
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), SD_BUS_VTABLE_PROPERTY_CONST), 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), 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 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) { const BusObjectImplementation machine_object = {
Manager *m = userdata; "/org/freedesktop/machine1/machine",
Machine *machine; "org.freedesktop.machine1.Machine",
int r; .fallback_vtables = BUS_FALLBACK_VTABLES({machine_vtable, machine_object_find}),
.node_enumerator = machine_node_enumerator,
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;
}
int machine_send_signal(Machine *m, bool new_machine) { int machine_send_signal(Machine *m, bool new_machine) {
_cleanup_free_ char *p = NULL; _cleanup_free_ char *p = NULL;

View File

@ -3,13 +3,12 @@
#include "sd-bus.h" #include "sd-bus.h"
#include "bus-util.h"
#include "machine.h" #include "machine.h"
extern const sd_bus_vtable machine_vtable[]; extern const BusObjectImplementation machine_object;
char *machine_bus_path(Machine *s); 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_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); 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 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) { int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *path, *result, *unit; const char *path, *result, *unit;
Manager *m = userdata; Manager *m = userdata;

View File

@ -22,6 +22,7 @@
#include "machined.h" #include "machined.h"
#include "main-func.h" #include "main-func.h"
#include "process-util.h" #include "process-util.h"
#include "service-util.h"
#include "signal-util.h" #include "signal-util.h"
#include "special.h" #include "special.h"
@ -188,25 +189,9 @@ static int manager_connect_bus(Manager *m) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to connect to system bus: %m"); 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) 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/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");
r = sd_bus_match_signal_async( r = sd_bus_match_signal_async(
m->bus, m->bus,
@ -357,12 +342,15 @@ static int run(int argc, char *argv[]) {
log_set_facility(LOG_AUTH); log_set_facility(LOG_AUTH);
log_setup_service(); 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) { umask(0022);
log_error("This program takes no arguments.");
return -EINVAL;
}
/* Always create the directories people can create inotify watches in. Note that some applications might check /* 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 * 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_add_machine(Manager *m, const char *name, Machine **_machine);
int manager_get_machine_by_pid(Manager *m, pid_t pid, 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_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); int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error);

View File

@ -1970,6 +1970,14 @@ static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_VTABLE_END, 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) { static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
Manager *m = userdata; Manager *m = userdata;
int b, r; int b, r;
@ -2004,25 +2012,9 @@ int manager_connect_bus(Manager *m) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to connect to system bus: %m"); 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) if (r < 0)
return log_error_errno(r, "Failed to register object: %m"); return r;
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");
r = bus_log_control_api_register(m->bus); r = bus_log_control_api_register(m->bus);
if (r < 0) if (r < 0)

View File

@ -1,8 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once #pragma once
#include "bus-util.h"
#include "resolved-manager.h" #include "resolved-manager.h"
extern const BusObjectImplementation manager_object;
int manager_connect_bus(Manager *m); int manager_connect_bus(Manager *m);
int _manager_send_changed(Manager *manager, const char *property, ...) _sentinel_; int _manager_send_changed(Manager *manager, const char *property, ...) _sentinel_;
#define manager_send_changed(manager, ...) _manager_send_changed(manager, __VA_ARGS__, NULL) #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); return sd_bus_reply_method_return(message, NULL);
} }
const sd_bus_vtable dnssd_vtable[] = { static int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
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) {
_cleanup_free_ char *name = NULL; _cleanup_free_ char *name = NULL;
Manager *m = userdata; Manager *m = userdata;
DnssdService *service; DnssdService *service;
@ -95,7 +86,7 @@ int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void
return 1; 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; _cleanup_strv_free_ char **l = NULL;
Manager *m = userdata; Manager *m = userdata;
DnssdService *service; DnssdService *service;
@ -127,3 +118,19 @@ int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char **
return 1; 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" #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); extern const BusObjectImplementation dnssd_object;
int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_error *error); 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); 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_VTABLE_START(0),
SD_BUS_PROPERTY("ScopesMask", "t", property_get_scopes_mask, 0, 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 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) { const BusObjectImplementation link_object = {
_cleanup_free_ char *e = NULL; "/org/freedesktop/resolve1/link",
Manager *m = userdata; "org.freedesktop.resolve1.Link",
Link *link; .fallback_vtables = BUS_FALLBACK_VTABLES({link_vtable, link_object_find}),
int ifindex, r; .node_enumerator = link_node_enumerator,
};
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;
}

View File

@ -3,13 +3,12 @@
#include "sd-bus.h" #include "sd-bus.h"
#include "bus-util.h"
#include "resolved-link.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); 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_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); 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-daemon.h"
#include "sd-event.h" #include "sd-event.h"
#include "bus-log-control-api.h"
#include "capability-util.h" #include "capability-util.h"
#include "daemon-util.h" #include "daemon-util.h"
#include "main-func.h" #include "main-func.h"
#include "mkdir.h" #include "mkdir.h"
#include "resolved-bus.h"
#include "resolved-conf.h" #include "resolved-conf.h"
#include "resolved-manager.h" #include "resolved-manager.h"
#include "resolved-resolv-conf.h" #include "resolved-resolv-conf.h"
#include "selinux-util.h" #include "selinux-util.h"
#include "service-util.h"
#include "signal-util.h" #include "signal-util.h"
#include "user-util.h" #include "user-util.h"
@ -25,8 +28,13 @@ static int run(int argc, char *argv[]) {
log_setup_service(); log_setup_service();
if (argc != 1) r = service_parse_argv("systemd-resolved.service",
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments."); "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); umask(0022);

View File

@ -107,17 +107,8 @@ static const sd_bus_vtable log_control_vtable[] = {
SD_BUS_VTABLE_END, SD_BUS_VTABLE_END,
}; };
int bus_log_control_api_register(sd_bus *bus) { const BusObjectImplementation log_control_object = {
int r; "/org/freedesktop/LogControl1",
"org.freedesktop.LogControl1",
r = sd_bus_add_object_vtable( .vtables = BUS_VTABLES(log_control_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;
}

View File

@ -2,7 +2,12 @@
#include "sd-bus.h" #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_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); 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 "alloc-util.h"
#include "bus-internal.h" #include "bus-internal.h"
#include "bus-introspect.h"
#include "bus-label.h" #include "bus-label.h"
#include "bus-message.h" #include "bus-message.h"
#include "bus-util.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); 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; } BusTransport;
typedef struct BusLocator { typedef struct BusLocator {
const char *destination; const char *destination;
const char *path; const char *path;
const char *interface; const char *interface;
} BusLocator; } 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); 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 { 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(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_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_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

@ -184,6 +184,8 @@ shared_sources = files('''
securebits-util.h securebits-util.h
serialize.c serialize.c
serialize.h serialize.h
service-util.c
service-util.h
sleep-config.c sleep-config.c
sleep-config.h sleep-config.h
socket-netlink.c 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

@ -14,6 +14,7 @@
#include "bus-error.h" #include "bus-error.h"
#include "bus-log-control-api.h" #include "bus-log-control-api.h"
#include "bus-polkit.h" #include "bus-polkit.h"
#include "bus-util.h"
#include "clock-util.h" #include "clock-util.h"
#include "conf-files.h" #include "conf-files.h"
#include "def.h" #include "def.h"
@ -28,6 +29,7 @@
#include "missing_capability.h" #include "missing_capability.h"
#include "path-util.h" #include "path-util.h"
#include "selinux-util.h" #include "selinux-util.h"
#include "service-util.h"
#include "signal-util.h" #include "signal-util.h"
#include "string-util.h" #include "string-util.h"
#include "strv.h" #include "strv.h"
@ -1085,6 +1087,12 @@ static const sd_bus_vtable timedate_vtable[] = {
SD_BUS_VTABLE_END, 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) { static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
int r; int r;
@ -1097,9 +1105,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get system bus connection: %m"); 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) if (r < 0)
return log_error_errno(r, "Failed to register object: %m"); return r;
r = bus_log_control_api_register(bus); r = bus_log_control_api_register(bus);
if (r < 0) if (r < 0)
@ -1126,10 +1134,15 @@ static int run(int argc, char *argv[]) {
log_setup_service(); 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) umask(0022);
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes no arguments.");
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0); assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);

View File

@ -3,10 +3,10 @@
import collections import collections
import sys import sys
import os
import shlex import shlex
import subprocess import subprocess
import io import io
import pprint
from lxml import etree from lxml import etree
PARSER = etree.XMLParser(no_network=True, PARSER = etree.XMLParser(no_network=True,
@ -19,23 +19,6 @@ PRINT_ERRORS = True
class NoCommand(Exception): class NoCommand(Exception):
pass 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 = [ BORING_INTERFACES = [
'org.freedesktop.DBus.Peer', 'org.freedesktop.DBus.Peer',
'org.freedesktop.DBus.Introspectable', 'org.freedesktop.DBus.Introspectable',
@ -183,31 +166,27 @@ def xml_to_text(destination, xml, *, only_interface=None):
return file.getvalue(), declarations, interfaces return file.getvalue(), declarations, interfaces
def subst_output(document, programlisting): def subst_output(document, programlisting):
try: executable = programlisting.get('executable', None)
cmd, prefix_lines, footer = find_command(programlisting.text.splitlines()) if executable is None:
except NoCommand: # Not our thing
return return
executable = programlisting.get('executable')
node = programlisting.get('node')
interface = programlisting.get('interface')
only_interface = programlisting.get('interface', None) argv = [f'{build_dir}/{executable}', f'--bus-introspect={interface}']
argv = shlex.split(cmd)
argv += ['--xml']
print(f'COMMAND: {shlex.join(argv)}') print(f'COMMAND: {shlex.join(argv)}')
object_idx = argv.index('--object-path')
object_path = argv[object_idx + 1]
try: try:
out = subprocess.check_output(argv, text=True) out = subprocess.check_output(argv, text=True)
except subprocess.CalledProcessError: except FileNotFoundError:
print('command failed, ignoring', file=sys.stderr) print(f'{executable} not found, ignoring', file=sys.stderr)
return return
xml = etree.fromstring(out, parser=PARSER) xml = etree.fromstring(out, parser=PARSER)
new_text, declarations, interfaces = xml_to_text(object_path, xml, only_interface=only_interface) new_text, declarations, interfaces = xml_to_text(node, xml, only_interface=interface)
programlisting.text = '\n' + new_text + ' '
programlisting.text = '\n'.join(prefix_lines) + '\n' + new_text + footer
if declarations: if declarations:
missing = check_documented(document, declarations) missing = check_documented(document, declarations)
@ -291,5 +270,14 @@ def process(page):
if __name__ == '__main__': if __name__ == '__main__':
pages = sys.argv[1:] 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: for page in pages:
process(page) process(page)

View File

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