chiark / gitweb /
core: fix return value on OOM
[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 "unit.h"
23 #include "mount.h"
24 #include "dbus-execute.h"
25 #include "dbus-kill.h"
26 #include "dbus-cgroup.h"
27 #include "dbus-mount.h"
28 #include "bus-util.h"
29
30 static int property_get_what(
31                 sd_bus *bus,
32                 const char *path,
33                 const char *interface,
34                 const char *property,
35                 sd_bus_message *reply,
36                 void *userdata,
37                 sd_bus_error *error) {
38
39         Mount *m = userdata;
40         const char *d;
41
42         assert(bus);
43         assert(reply);
44         assert(m);
45
46         if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
47                 d = m->parameters_proc_self_mountinfo.what;
48         else if (m->from_fragment && m->parameters_fragment.what)
49                 d = m->parameters_fragment.what;
50         else
51                 d = "";
52
53         return sd_bus_message_append(reply, "s", d);
54 }
55
56 static int property_get_options(
57                 sd_bus *bus,
58                 const char *path,
59                 const char *interface,
60                 const char *property,
61                 sd_bus_message *reply,
62                 void *userdata,
63                 sd_bus_error *error) {
64
65         Mount *m = userdata;
66         const char *d;
67
68         assert(bus);
69         assert(reply);
70         assert(m);
71
72         if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options)
73                 d = m->parameters_proc_self_mountinfo.options;
74         else if (m->from_fragment && m->parameters_fragment.options)
75                 d = m->parameters_fragment.options;
76         else
77                 d = "";
78
79         return sd_bus_message_append(reply, "s", d);
80 }
81
82 static int property_get_type(
83                 sd_bus *bus,
84                 const char *path,
85                 const char *interface,
86                 const char *property,
87                 sd_bus_message *reply,
88                 void *userdata,
89                 sd_bus_error *error) {
90
91         Mount *m = userdata;
92         const char *d;
93
94         assert(bus);
95         assert(reply);
96         assert(m);
97
98         if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype)
99                 d = m->parameters_proc_self_mountinfo.fstype;
100         else if (m->from_fragment && m->parameters_fragment.fstype)
101                 d = m->parameters_fragment.fstype;
102         else
103                 d = "";
104
105         return sd_bus_message_append(reply, "s", d);
106 }
107
108 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, mount_result, MountResult);
109
110 const sd_bus_vtable bus_mount_vtable[] = {
111         SD_BUS_VTABLE_START(0),
112         SD_BUS_PROPERTY("Where", "s", NULL, offsetof(Mount, where), SD_BUS_VTABLE_PROPERTY_CONST),
113         SD_BUS_PROPERTY("What", "s", property_get_what, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
114         SD_BUS_PROPERTY("Options","s", property_get_options, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
115         SD_BUS_PROPERTY("Type", "s", property_get_type, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
116         SD_BUS_PROPERTY("TimeoutUSec", "t", bus_property_get_usec, offsetof(Mount, timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
117         SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Mount, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
118         SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Mount, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
119         SD_BUS_PROPERTY("SloppyOptions", "b", bus_property_get_bool, offsetof(Mount, sloppy_options), SD_BUS_VTABLE_PROPERTY_CONST),
120         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Mount, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
121         BUS_EXEC_COMMAND_VTABLE("ExecMount", offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
122         BUS_EXEC_COMMAND_VTABLE("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
123         BUS_EXEC_COMMAND_VTABLE("ExecRemount", offsetof(Mount, exec_command[MOUNT_EXEC_REMOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
124         SD_BUS_VTABLE_END
125 };
126
127 static int bus_mount_set_transient_property(
128                 Mount *m,
129                 const char *name,
130                 sd_bus_message *message,
131                 UnitSetPropertiesMode mode,
132                 sd_bus_error *error) {
133
134         const char *new_property;
135         char **property;
136         char *p;
137         int r;
138
139         assert(m);
140         assert(name);
141         assert(message);
142
143         if (streq(name, "What"))
144                 property = &m->parameters_fragment.what;
145         else if (streq(name, "Options"))
146                 property = &m->parameters_fragment.options;
147         else if (streq(name, "Type"))
148                 property = &m->parameters_fragment.fstype;
149         else
150                 return 0;
151
152         r = sd_bus_message_read(message, "s", &new_property);
153         if (r < 0)
154                 return r;
155
156         if (mode != UNIT_CHECK) {
157                 p = strdup(new_property);
158                 if (!p)
159                         return -ENOMEM;
160
161                 free(*property);
162                 *property = p;
163         }
164
165         return 1;
166 }
167
168 int bus_mount_set_property(
169                 Unit *u,
170                 const char *name,
171                 sd_bus_message *message,
172                 UnitSetPropertiesMode mode,
173                 sd_bus_error *error) {
174
175         Mount *m = MOUNT(u);
176         int r;
177
178         assert(m);
179         assert(name);
180         assert(message);
181
182         r = bus_cgroup_set_property(u, &m->cgroup_context, name, message, mode, error);
183         if (r != 0)
184                 return r;
185
186         if (u->transient && u->load_state == UNIT_STUB) {
187                 /* This is a transient unit, let's load a little more */
188
189                 r = bus_mount_set_transient_property(m, name, message, mode, error);
190                 if (r != 0)
191                         return r;
192
193                 r = bus_exec_context_set_transient_property(u, &m->exec_context, name, message, mode, error);
194                 if (r != 0)
195                         return r;
196
197                 r = bus_kill_context_set_transient_property(u, &m->kill_context, name, message, mode, error);
198                 if (r != 0)
199                         return r;
200         }
201
202         return 0;
203 }
204
205 int bus_mount_commit_properties(Unit *u) {
206         assert(u);
207
208         unit_update_cgroup_members_masks(u);
209         unit_realize_cgroup(u);
210
211         return 0;
212 }