1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
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.
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.
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/>.
29 static int property_get_id(
32 const char *interface,
34 sd_bus_message *reply,
36 sd_bus_error *error) {
38 Machine *m = userdata;
45 r = sd_bus_message_append_array(reply, 'y', &m->id, 16);
52 static int property_get_state(
55 const char *interface,
57 sd_bus_message *reply,
59 sd_bus_error *error) {
61 Machine *m = userdata;
69 state = machine_state_to_string(machine_get_state(m));
71 r = sd_bus_message_append_basic(reply, 's', state);
78 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass);
80 static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
81 Machine *m = userdata;
92 return sd_bus_reply_method_return(message, NULL);
95 static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
96 Machine *m = userdata;
106 r = sd_bus_message_read(message, "si", &swho, &signo);
113 who = kill_who_from_string(swho);
115 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
118 if (signo <= 0 || signo >= _NSIG)
119 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
121 r = machine_kill(m, who, signo);
125 return sd_bus_reply_method_return(message, NULL);
128 const sd_bus_vtable machine_vtable[] = {
129 SD_BUS_VTABLE_START(0),
130 SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), 0),
131 SD_BUS_PROPERTY("Id", "ay", property_get_id, 0, 0),
132 SD_BUS_PROPERTY("Timestamp", "t", NULL, offsetof(Machine, timestamp.realtime), 0),
133 SD_BUS_PROPERTY("TimestampMonotonic", "t", NULL, offsetof(Machine, timestamp.monotonic), 0),
134 SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Machine, service), 0),
135 SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Machine, scope), 0),
136 SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader), 0),
137 SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Machine, class), 0),
138 SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
139 SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(Machine, root_directory), 0),
140 SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, 0),
141 SD_BUS_METHOD("Kill", "si", NULL, method_kill, 0),
145 int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
146 Manager *m = userdata;
156 if (streq(path, "/org/freedesktop/machine1/machine/self")) {
157 sd_bus_message *message;
160 message = sd_bus_get_current(bus);
164 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
168 r = manager_get_machine_by_pid(m, pid, &machine);
172 _cleanup_free_ char *e = NULL;
175 p = startswith(path, "/org/freedesktop/machine1/machine/");
179 e = sd_bus_label_unescape(p);
183 machine = hashmap_get(m->machines, e);
192 char *machine_bus_path(Machine *m) {
193 _cleanup_free_ char *e = NULL;
197 e = sd_bus_label_escape(m->name);
201 return strappend("/org/freedesktop/machine1/machine/", e);
204 int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
205 _cleanup_strv_free_ char **l = NULL;
206 Machine *machine = NULL;
207 Manager *m = userdata;
215 HASHMAP_FOREACH(machine, m->machines, i) {
218 p = machine_bus_path(machine);
222 r = strv_push(&l, p);
235 int machine_send_signal(Machine *m, bool new_machine) {
236 _cleanup_free_ char *p = NULL;
240 p = machine_bus_path(m);
244 return sd_bus_emit_signal(
246 "/org/freedesktop/machine1",
247 "org.freedesktop.machine1.Manager",
248 new_machine ? "MachineNew" : "MachineRemoved",
252 int machine_send_create_reply(Machine *m, sd_bus_error *error) {
253 _cleanup_bus_message_unref_ sd_bus_message *c = NULL;
254 _cleanup_free_ char *p = NULL;
258 if (!m->create_message)
261 c = m->create_message;
262 m->create_message = NULL;
265 return sd_bus_reply_method_error(c, error);
267 /* Update the machine state file before we notify the client
268 * about the result. */
271 p = machine_bus_path(m);
275 return sd_bus_reply_method_return(c, "o", p);