machine-dbus.c revision 9d485985338a46b8cb1acdf1af6c1eb2e88acfee
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen/***
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen This file is part of systemd.
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Copyright 2011 Lennart Poettering
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen systemd is free software; you can redistribute it and/or modify it
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen under the terms of the GNU Lesser General Public License as published by
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen (at your option) any later version.
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen systemd is distributed in the hope that it will be useful, but
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Lesser General Public License for more details.
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen You should have received a copy of the GNU Lesser General Public License
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen***/
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include <errno.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <string.h>
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include <sys/capability.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <arpa/inet.h>
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "bus-util.h"
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include "bus-label.h"
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include "strv.h"
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include "bus-errors.h"
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include "copy.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "fileio.h"
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include "in-addr-util.h"
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include "local-addresses.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "machine.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic int property_get_id(
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_bus *bus,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *path,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *interface,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *property,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_bus_message *reply,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen void *userdata,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_bus_error *error) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Machine *m = userdata;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(bus);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(reply);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(m);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_append_array(reply, 'y', &m->id, 16);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return 1;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenstatic int property_get_state(
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_bus *bus,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *path,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *interface,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *property,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_bus_message *reply,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen void *userdata,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_bus_error *error) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Machine *m = userdata;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *state;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(bus);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(reply);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(m);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen state = machine_state_to_string(machine_get_state(m));
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_append_basic(reply, 's', state);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
52efd56a6369e19c2400a42981a197cd2eef924aLennart Poettering return 1;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenstatic int property_get_netif(
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_bus *bus,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *path,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *interface,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *property,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_bus_message *reply,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen void *userdata,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_bus_error *error) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Machine *m = userdata;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(bus);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(reply);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(m);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert_cc(sizeof(int) == sizeof(int32_t));
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_append_array(reply, 'i', m->netif, m->n_netif * sizeof(int));
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return 1;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenstatic BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenint bus_machine_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Machine *m = userdata;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(bus);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(message);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(m);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = machine_stop(m);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_reply_method_return(message, NULL);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenint bus_machine_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Machine *m = userdata;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *swho;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int32_t signo;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen KillWho who;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(bus);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(message);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(m);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_read(message, "si", &swho, &signo);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (isempty(swho))
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen who = KILL_ALL;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen else {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen who = kill_who_from_string(swho);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (who < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (signo <= 0 || signo >= _NSIG)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = machine_kill(m, who, signo);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_reply_method_return(message, NULL);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenint bus_machine_method_get_addresses(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_close_pair_ int pair[2] = { -1, -1 };
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_free_ char *us = NULL, *them = NULL;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_close_ int netns_fd = -1;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Machine *m = userdata;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *p;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen siginfo_t si;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pid_t child;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(bus);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(message);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(m);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = readlink_malloc("/proc/self/ns/net", &us);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen p = procfs_file_alloca(m->leader, "ns/net");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = readlink_malloc(p, &them);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (streq(us, them))
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_setf(error, BUS_ERROR_NO_PRIVATE_NETWORKING, "Machine %s does not use private networking", m->name);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = namespace_open(m->leader, NULL, NULL, &netns_fd, NULL);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, -errno);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen child = fork();
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (child < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, -errno);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (child == 0) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_free_ struct local_address *addresses = NULL;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen struct local_address *a;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int i, n;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pair[0] = safe_close(pair[0]);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = namespace_enter(-1, -1, netns_fd, -1);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _exit(EXIT_FAILURE);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen n = local_addresses(&addresses);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (n < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _exit(EXIT_FAILURE);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen for (a = addresses, i = 0; i < n; a++, i++) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen struct iovec iov[2] = {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen { .iov_base = &a->family, .iov_len = sizeof(a->family) },
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen { .iov_base = &a->address, .iov_len = FAMILY_ADDRESS_SIZE(a->family) },
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen };
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = writev(pair[1], iov, 2);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _exit(EXIT_FAILURE);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pair[1] = safe_close(pair[1]);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _exit(EXIT_SUCCESS);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pair[1] = safe_close(pair[1]);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_new_method_return(message, &reply);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_open_container(reply, 'a', "(yay)");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen for (;;) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen unsigned char family;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen ssize_t n;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen union in_addr_union in_addr;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen struct iovec iov[2];
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen struct msghdr mh = {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen .msg_iov = iov,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen .msg_iovlen = 2,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen };
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen iov[0] = (struct iovec) { .iov_base = &family, .iov_len = sizeof(family) };
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen iov[1] = (struct iovec) { .iov_base = &in_addr, .iov_len = sizeof(in_addr) };
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen n = recvmsg(pair[0], &mh, 0);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (n < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, -errno);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if ((size_t) n < sizeof(family))
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen break;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_open_container(reply, 'r', "yay");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_append(reply, "y", family);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen switch (family) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen case AF_INET:
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (n != sizeof(struct in_addr) + sizeof(family))
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, EIO);
52efd56a6369e19c2400a42981a197cd2eef924aLennart Poettering
52efd56a6369e19c2400a42981a197cd2eef924aLennart Poettering r = sd_bus_message_append_array(reply, 'y', &in_addr.in, sizeof(in_addr.in));
52efd56a6369e19c2400a42981a197cd2eef924aLennart Poettering break;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
52efd56a6369e19c2400a42981a197cd2eef924aLennart Poettering case AF_INET6:
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (n != sizeof(struct in6_addr) + sizeof(family))
52efd56a6369e19c2400a42981a197cd2eef924aLennart Poettering return sd_bus_error_set_errno(error, EIO);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_append_array(reply, 'y', &in_addr.in6, sizeof(in_addr.in6));
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen break;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_close_container(reply);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = wait_for_terminate(child, &si);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, EIO);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_close_container(reply);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_send(bus, reply, NULL);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenint bus_machine_method_get_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_close_ int mntns_fd = -1, root_fd = -1;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_close_pair_ int pair[2] = { -1, -1 };
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_strv_free_ char **l = NULL;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_fclose_ FILE *f = NULL;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Machine *m = userdata;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen char **k, **v;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen siginfo_t si;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pid_t child;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(bus);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(message);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(m);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
7e518afab9fb55b8052f68888210927259275560Thomas Hindoe Paaboel Andersen r = namespace_open(m->leader, NULL, &mntns_fd, NULL, &root_fd);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
1fa2f38f0f011010bf57522b42fcc168856a7003Zbigniew Jędrzejewski-Szmek return sd_bus_error_set_errno(error, -errno);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen child = fork();
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (child < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, -errno);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (child == 0) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_close_ int fd = -1;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pair[0] = safe_close(pair[0]);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = namespace_enter(-1, mntns_fd, -1, root_fd);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _exit(EXIT_FAILURE);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (fd < 0) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (fd < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _exit(EXIT_FAILURE);
f0c4b1c3fd827b429ba36aa45fd39e0a023cbf2cTom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = copy_bytes(fd, pair[1], (off_t) -1);
74ca738f6a01fb5fc19c5c3899f5cb1fdc1d7f68Lennart Poettering if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _exit(EXIT_FAILURE);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _exit(EXIT_SUCCESS);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pair[1] = safe_close(pair[1]);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen f = fdopen(pair[0], "re");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (!f)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, -errno);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pair[0] = -1;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = load_env_file_pairs(f, "/etc/os-release", NULL, &l);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = wait_for_terminate(child, &si);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, EIO);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_new_method_return(message, &reply);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_open_container(reply, 'a', "{ss}");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen STRV_FOREACH_PAIR(k, v, l) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_append(reply, "{ss}", *k, *v);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_message_close_container(reply);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_error_set_errno(error, r);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return sd_bus_send(bus, reply, NULL);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenconst sd_bus_vtable machine_vtable[] = {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_VTABLE_START(0),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), SD_BUS_VTABLE_PROPERTY_CONST),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_PROPERTY("Id", "ay", property_get_id, 0, SD_BUS_VTABLE_PROPERTY_CONST),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Machine, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Machine, service), SD_BUS_VTABLE_PROPERTY_CONST),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_PROPERTY("Unit", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader), SD_BUS_VTABLE_PROPERTY_CONST),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Machine, class), SD_BUS_VTABLE_PROPERTY_CONST),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(Machine, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_PROPERTY("NetworkInterfaces", "ai", property_get_netif, 0, SD_BUS_VTABLE_PROPERTY_CONST),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_METHOD("Terminate", NULL, NULL, bus_machine_method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_METHOD("Kill", "si", NULL, bus_machine_method_kill, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_METHOD("GetAddresses", NULL, "a(yay)", bus_machine_method_get_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_machine_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen SD_BUS_VTABLE_END
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen};
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenint machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Manager *m = userdata;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Machine *machine;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(bus);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(path);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(interface);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(found);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(m);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (streq(path, "/org/freedesktop/machine1/machine/self")) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_bus_message *message;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pid_t pid;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen message = sd_bus_get_current_message(bus);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (!message)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return 0;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_bus_creds_get_pid(creds, &pid);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = manager_get_machine_by_pid(m, pid, &machine);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r <= 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return 0;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } else {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_free_ char *e = NULL;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *p;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen p = startswith(path, "/org/freedesktop/machine1/machine/");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (!p)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return 0;
8927b1dad2d4a7330174cb924090b4635a2547fbDavid Herrmann
8927b1dad2d4a7330174cb924090b4635a2547fbDavid Herrmann e = bus_label_unescape(p);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (!e)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return -ENOMEM;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen machine = hashmap_get(m->machines, e);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (!machine)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return 0;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
8927b1dad2d4a7330174cb924090b4635a2547fbDavid Herrmann *found = machine;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return 1;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenchar *machine_bus_path(Machine *m) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen _cleanup_free_ char *e = NULL;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(m);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
e = bus_label_escape(m->name);
if (!e)
return NULL;
return strappend("/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 = l;
l = NULL;
return 1;
}
int machine_send_signal(Machine *m, bool new_machine) {
_cleanup_free_ char *p = NULL;
assert(m);
p = machine_bus_path(m);
if (!p)
return -ENOMEM;
return sd_bus_emit_signal(
m->manager->bus,
"/org/freedesktop/machine1",
"org.freedesktop.machine1.Manager",
new_machine ? "MachineNew" : "MachineRemoved",
"so", m->name, p);
}
int machine_send_create_reply(Machine *m, sd_bus_error *error) {
_cleanup_bus_message_unref_ sd_bus_message *c = NULL;
_cleanup_free_ char *p = NULL;
assert(m);
if (!m->create_message)
return 0;
c = m->create_message;
m->create_message = NULL;
if (error)
return sd_bus_reply_method_error(c, error);
/* Update the machine state file before we notify the client
* about the result. */
machine_save(m);
p = machine_bus_path(m);
if (!p)
return -ENOMEM;
return sd_bus_reply_method_return(c, "o", p);
}