chiark / gitweb /
core: add new "scope" unit type for making a unit of pre-existing processes
[elogind.git] / src / core / dbus-mount.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23
24 #include "dbus-unit.h"
25 #include "dbus-execute.h"
26 #include "dbus-kill.h"
27 #include "dbus-cgroup.h"
28 #include "dbus-common.h"
29 #include "selinux-access.h"
30 #include "dbus-mount.h"
31
32 #define BUS_MOUNT_INTERFACE                                             \
33         " <interface name=\"org.freedesktop.systemd1.Mount\">\n"        \
34         "  <property name=\"Where\" type=\"s\" access=\"read\"/>\n"     \
35         "  <property name=\"What\" type=\"s\" access=\"read\"/>\n"      \
36         "  <property name=\"Options\" type=\"s\" access=\"read\"/>\n"   \
37         "  <property name=\"Type\" type=\"s\" access=\"read\"/>\n"      \
38         "  <property name=\"TimeoutUSec\" type=\"t\" access=\"read\"/>\n" \
39         BUS_EXEC_COMMAND_INTERFACE("ExecMount")                         \
40         BUS_EXEC_COMMAND_INTERFACE("ExecUnmount")                       \
41         BUS_EXEC_COMMAND_INTERFACE("ExecRemount")                       \
42         BUS_EXEC_CONTEXT_INTERFACE                                      \
43         BUS_KILL_CONTEXT_INTERFACE                                      \
44         BUS_CGROUP_CONTEXT_INTERFACE                                    \
45         "  <property name=\"ControlPID\" type=\"u\" access=\"read\"/>\n" \
46         "  <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \
47         "  <property name=\"Result\" type=\"s\" access=\"read\"/>\n"    \
48         " </interface>\n"
49
50 #define INTROSPECTION                                                   \
51         DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
52         "<node>\n"                                                      \
53         BUS_UNIT_INTERFACE                                              \
54         BUS_MOUNT_INTERFACE                                             \
55         BUS_PROPERTIES_INTERFACE                                        \
56         BUS_PEER_INTERFACE                                              \
57         BUS_INTROSPECTABLE_INTERFACE                                    \
58         "</node>\n"
59
60 #define INTERFACES_LIST                              \
61         BUS_UNIT_INTERFACES_LIST                     \
62         "org.freedesktop.systemd1.Mount\0"
63
64 const char bus_mount_interface[] _introspect_("Mount") = BUS_MOUNT_INTERFACE;
65
66 const char bus_mount_invalidating_properties[] =
67         "What\0"
68         "Options\0"
69         "Type\0"
70         "ExecMount\0"
71         "ExecUnmount\0"
72         "ExecRemount\0"
73         "ControlPID\0"
74         "Result\0";
75
76 static int bus_mount_append_what(DBusMessageIter *i, const char *property, void *data) {
77         Mount *m = data;
78         const char *d;
79
80         assert(i);
81         assert(property);
82         assert(m);
83
84         if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
85                 d = m->parameters_proc_self_mountinfo.what;
86         else if (m->from_fragment && m->parameters_fragment.what)
87                 d = m->parameters_fragment.what;
88         else
89                 d = "";
90
91         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
92                 return -ENOMEM;
93
94         return 0;
95 }
96
97 static int bus_mount_append_options(DBusMessageIter *i, const char *property, void *data) {
98         Mount *m = data;
99         const char *d;
100
101         assert(i);
102         assert(property);
103         assert(m);
104
105         if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options)
106                 d = m->parameters_proc_self_mountinfo.options;
107         else if (m->from_fragment && m->parameters_fragment.options)
108                 d = m->parameters_fragment.options;
109         else
110                 d = "";
111
112         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
113                 return -ENOMEM;
114
115         return 0;
116 }
117
118 static int bus_mount_append_type(DBusMessageIter *i, const char *property, void *data) {
119         Mount *m = data;
120         const char *d;
121
122         assert(i);
123         assert(property);
124         assert(m);
125
126         if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype)
127                 d = m->parameters_proc_self_mountinfo.fstype;
128         else if (m->from_fragment && m->parameters_fragment.fstype)
129                 d = m->parameters_fragment.fstype;
130         else
131                 d = "";
132
133         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
134                 return -ENOMEM;
135
136         return 0;
137 }
138
139 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_mount_append_mount_result, mount_result, MountResult);
140
141 static const BusProperty bus_mount_properties[] = {
142         { "Where",         bus_property_append_string, "s", offsetof(Mount, where),    true },
143         { "What",          bus_mount_append_what,      "s", 0 },
144         { "Options",       bus_mount_append_options,   "s", 0 },
145         { "Type",          bus_mount_append_type,      "s", 0 },
146         { "TimeoutUSec",   bus_property_append_usec,   "t", offsetof(Mount, timeout_usec)   },
147         BUS_EXEC_COMMAND_PROPERTY("ExecMount",   offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]),   false),
148         BUS_EXEC_COMMAND_PROPERTY("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), false),
149         BUS_EXEC_COMMAND_PROPERTY("ExecRemount", offsetof(Mount, exec_command[MOUNT_EXEC_REMOUNT]), false),
150         { "ControlPID",    bus_property_append_pid,    "u", offsetof(Mount, control_pid)    },
151         { "DirectoryMode", bus_property_append_mode,   "u", offsetof(Mount, directory_mode) },
152         { "Result",        bus_mount_append_mount_result, "s", offsetof(Mount, result)      },
153         { NULL, }
154 };
155
156 DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
157         Mount *m = MOUNT(u);
158
159         const BusBoundProperties bps[] = {
160                 { "org.freedesktop.systemd1.Unit",  bus_unit_properties,           u },
161                 { "org.freedesktop.systemd1.Mount", bus_mount_properties,          m },
162                 { "org.freedesktop.systemd1.Mount", bus_exec_context_properties,   &m->exec_context },
163                 { "org.freedesktop.systemd1.Mount", bus_kill_context_properties,   &m->kill_context },
164                 { "org.freedesktop.systemd1.Mount", bus_cgroup_context_properties, &m->cgroup_context },
165                 { NULL, }
166         };
167
168         SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status");
169
170         return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps );
171 }
172
173 int bus_mount_set_property(
174                 Unit *u,
175                 const char *name,
176                 DBusMessageIter *i,
177                 UnitSetPropertiesMode mode,
178                 DBusError *error) {
179
180         Mount *m = MOUNT(u);
181         int r;
182
183         assert(name);
184         assert(u);
185         assert(i);
186
187         r = bus_cgroup_set_property(u, &m->cgroup_context, name, i, mode, error);
188         if (r != 0)
189                 return r;
190
191         return 0;
192 }
193
194 int bus_mount_commit_properties(Unit *u) {
195         assert(u);
196
197         unit_realize_cgroup(u);
198         return 0;
199 }