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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

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

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

View File

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

View File

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

View File

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