+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <arpa/inet.h>
#include "path-util.h"
#include "process-util.h"
#include "ptyfwd.h"
+#include "sigbus.h"
#include "signal-util.h"
#include "spawn-polkit-agent.h"
+#include "stdio-util.h"
#include "strv.h"
#include "terminal-util.h"
#include "unit-name.h"
#include "util.h"
#include "verbs.h"
#include "web-util.h"
-#include "stdio-util.h"
#define ALL_IP_ADDRESSES -1
static int print_addresses(sd_bus *bus, const char *name, int, const char *pr1, const char *pr2, int n_addr);
-static void polkit_agent_open_if_enabled(void) {
-
- /* Open the polkit agent as a child process if necessary */
-
- if (!arg_ask_password)
- return;
-
- if (arg_transport != BUS_TRANSPORT_LOCAL)
- return;
-
- polkit_agent_open();
-}
-
static OutputFlags get_output_flags(void) {
return
arg_all * OUTPUT_SHOW_ALL |
- arg_full * OUTPUT_FULL_WIDTH |
- (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
+ (arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
colors_enabled() * OUTPUT_COLOR |
!arg_quiet * OUTPUT_WARN_CUTOFF;
}
static int list_machines(int argc, char *argv[], void *userdata) {
- size_t max_name = strlen("MACHINE"), max_class = strlen("CLASS"),
- max_service = strlen("SERVICE"), max_os = strlen("OS"), max_version_id = strlen("VERSION");
+ size_t max_name = STRLEN("MACHINE"), max_class = STRLEN("CLASS"),
+ max_service = STRLEN("SERVICE"), max_os = STRLEN("OS"), max_version_id = STRLEN("VERSION");
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *prefix = NULL;
assert(bus);
- pager_open(arg_no_pager, false);
+ (void) pager_open(arg_no_pager, false);
r = sd_bus_call_method(bus,
"org.freedesktop.machine1",
qsort_safe(machines, n_machines, sizeof(MachineInfo), compare_machine_info);
- /* Allocate for prefix max characters for all fields + spaces between them + strlen(",\n") */
+ /* Allocate for prefix max characters for all fields + spaces between them + STRLEN(",\n") */
r = asprintf(&prefix, "%-*s",
(int) (max_name +
max_class +
max_service +
max_os +
- max_version_id + 5 + strlen(",\n")),
+ max_version_id + 5 + STRLEN(",\n")),
",\n");
if (r < 0) {
r = log_oom();
static int list_images(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- size_t max_name = strlen("NAME"), max_type = strlen("TYPE"), max_size = strlen("USAGE"), max_crtime = strlen("CREATED"), max_mtime = strlen("MODIFIED");
+ size_t max_name = STRLEN("NAME"), max_type = STRLEN("TYPE"), max_size = STRLEN("USAGE"), max_crtime = STRLEN("CREATED"), max_mtime = STRLEN("MODIFIED");
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ ImageInfo *images = NULL;
size_t n_images = 0, n_allocated = 0, j;
assert(bus);
- pager_open(arg_no_pager, false);
+ (void) pager_open(arg_no_pager, false);
r = sd_bus_call_method(bus,
"org.freedesktop.machine1",
}
typedef struct MachineStatusInfo {
- char *name;
+ const char *name;
sd_id128_t id;
- char *class;
- char *service;
- char *unit;
- char *root_directory;
+ const char *class;
+ const char *service;
+ const char *unit;
+ const char *root_directory;
pid_t leader;
struct dual_timestamp timestamp;
int *netif;
static void machine_status_info_clear(MachineStatusInfo *info) {
if (info) {
- free(info->name);
- free(info->class);
- free(info->service);
- free(info->unit);
- free(info->root_directory);
free(info->netif);
zero(*info);
}
};
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
_cleanup_(machine_status_info_clear) MachineStatusInfo info = {};
int r;
"org.freedesktop.machine1",
path,
map,
+ 0,
&error,
+ &m,
&info);
if (r < 0)
return log_error_errno(r, "Could not get properties: %s", bus_error_message(&error, r));
*new_line = true;
- r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_value, arg_all);
+ r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, NULL, arg_property, arg_value, arg_all, NULL);
if (r < 0)
log_error_errno(r, "Could not get properties: %m");
properties = !strstr(argv[0], "status");
- pager_open(arg_no_pager, false);
+ (void) pager_open(arg_no_pager, false);
if (properties && argc <= 1) {
return r;
}
+static int print_image_hostname(sd_bus *bus, const char *name) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ const char *hn;
+ int r;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "GetImageHostname",
+ NULL, &reply, "s", name);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read(reply, "s", &hn);
+ if (r < 0)
+ return r;
+
+ if (!isempty(hn))
+ printf("\tHostname: %s\n", hn);
+
+ return 0;
+}
+
+static int print_image_machine_id(sd_bus *bus, const char *name) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ sd_id128_t id = SD_ID128_NULL;
+ const void *p;
+ size_t size;
+ int r;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "GetImageMachineID",
+ NULL, &reply, "s", name);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read_array(reply, 'y', &p, &size);
+ if (r < 0)
+ return r;
+
+ if (size == sizeof(sd_id128_t))
+ memcpy(&id, p, size);
+
+ if (!sd_id128_is_null(id))
+ printf(" Machine ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(id));
+
+ return 0;
+}
+
+static int print_image_machine_info(sd_bus *bus, const char *name) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ int r;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "GetImageMachineInfo",
+ NULL, &reply, "s", name);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_enter_container(reply, 'a', "{ss}");
+ if (r < 0)
+ return r;
+
+ for (;;) {
+ const char *p, *q;
+
+ r = sd_bus_message_read(reply, "{ss}", &p, &q);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ if (streq(p, "DEPLOYMENT"))
+ printf(" Deployment: %s\n", q);
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
typedef struct ImageStatusInfo {
- char *name;
- char *path;
- char *type;
- int read_only;
+ const char *name;
+ const char *path;
+ const char *type;
+ bool read_only;
usec_t crtime;
usec_t mtime;
uint64_t usage;
uint64_t limit_exclusive;
} ImageStatusInfo;
-static void image_status_info_clear(ImageStatusInfo *info) {
- if (info) {
- free(info->name);
- free(info->path);
- free(info->type);
- zero(*info);
- }
-}
-
static void print_image_status_info(sd_bus *bus, ImageStatusInfo *i) {
char ts_relative[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
char ts_absolute[FORMAT_TIMESTAMP_MAX], *s2;
if (i->path)
printf("\t Path: %s\n", i->path);
+ (void) print_image_hostname(bus, i->name);
+ (void) print_image_machine_id(bus, i->name);
+ (void) print_image_machine_info(bus, i->name);
+
print_os_release(bus, "GetImageOSRelease", i->name, "\t OS: ");
printf("\t RO: %s%s%s\n",
};
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(image_status_info_clear) ImageStatusInfo info = {};
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+ ImageStatusInfo info = {};
int r;
assert(bus);
"org.freedesktop.machine1",
path,
map,
+ BUS_MAP_BOOLEAN_AS_BOOL,
&error,
+ &m,
&info);
if (r < 0)
return log_error_errno(r, "Could not get properties: %s", bus_error_message(&error, r));
}
typedef struct PoolStatusInfo {
- char *path;
+ const char *path;
uint64_t usage;
uint64_t limit;
} PoolStatusInfo;
-static void pool_status_info_clear(PoolStatusInfo *info) {
- if (info) {
- free(info->path);
- zero(*info);
- info->usage = -1;
- info->limit = -1;
- }
-}
-
static void print_pool_status_info(sd_bus *bus, PoolStatusInfo *i) {
char bs[FORMAT_BYTES_MAX], *s;
{}
};
- _cleanup_(pool_status_info_clear) PoolStatusInfo info = {
+ PoolStatusInfo info = {
.usage = (uint64_t) -1,
.limit = (uint64_t) -1,
};
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
int r;
assert(bus);
"org.freedesktop.machine1",
"/org/freedesktop/machine1",
map,
+ 0,
&error,
+ &m,
&info);
if (r < 0)
return log_error_errno(r, "Could not get properties: %s", bus_error_message(&error, r));
*new_line = true;
- r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_value, arg_all);
+ r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, NULL, arg_property, arg_value, arg_all, NULL);
if (r < 0)
log_error_errno(r, "Could not get properties: %m");
properties = !strstr(argv[0], "status");
- pager_open(arg_no_pager, false);
+ (void) pager_open(arg_no_pager, false);
if (argc <= 1) {
assert(bus);
- polkit_agent_open_if_enabled();
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
if (!arg_kill_who)
arg_kill_who = "all";
assert(bus);
- polkit_agent_open_if_enabled();
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
for (i = 1; i < argc; i++) {
r = sd_bus_call_method(
assert(bus);
- polkit_agent_open_if_enabled();
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
copy_from = streq(argv[0], "copy-from");
dest = argv[3] ?: argv[2];
assert(bus);
- polkit_agent_open_if_enabled();
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
r = sd_bus_call_method(
bus,
return -EOPNOTSUPP;
}
- polkit_agent_open_if_enabled();
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
r = sd_event_default(&event);
if (r < 0)
"member='MachineRemoved',"
"arg0='", machine, "'");
- r = sd_bus_add_match(bus, &slot, match, on_machine_removed, &forward);
+ r = sd_bus_add_match_async(bus, &slot, match, on_machine_removed, NULL, &forward);
if (r < 0)
- return log_error_errno(r, "Failed to add machine removal match: %m");
+ return log_error_errno(r, "Failed to request machine removal match: %m");
r = sd_bus_call_method(
bus,
}
}
- polkit_agent_open_if_enabled();
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
r = sd_event_default(&event);
if (r < 0)
"member='MachineRemoved',"
"arg0='", machine, "'");
- r = sd_bus_add_match(bus, &slot, match, on_machine_removed, &forward);
+ r = sd_bus_add_match_async(bus, &slot, match, on_machine_removed, NULL, &forward);
if (r < 0)
- return log_error_errno(r, "Failed to add machine removal match: %m");
+ return log_error_errno(r, "Failed to request machine removal match: %m");
r = sd_bus_message_new_method_call(
bus,
assert(bus);
- polkit_agent_open_if_enabled();
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
for (i = 1; i < argc; i++) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus = userdata;
int r;
- polkit_agent_open_if_enabled();
+ assert(bus);
+
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
r = sd_bus_call_method(
bus,
sd_bus *bus = userdata;
int r;
- polkit_agent_open_if_enabled();
+ assert(bus);
+
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
r = sd_bus_message_new_method_call(
bus,
sd_bus *bus = userdata;
int b = true, r;
+ assert(bus);
+
if (argc > 2) {
b = parse_boolean(argv[2]);
if (b < 0) {
}
}
- polkit_agent_open_if_enabled();
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
r = sd_bus_call_method(
bus,
assert(bus);
- polkit_agent_open_if_enabled();
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
r = bus_wait_for_jobs_new(bus, &w);
if (r < 0)
assert(bus);
- polkit_agent_open_if_enabled();
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
method = streq(argv[0], "enable") ? "EnableUnitFiles" : "DisableUnitFiles";
assert(bus);
assert(m);
- polkit_agent_open_if_enabled();
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
r = sd_event_default(&event);
if (r < 0)
if (r < 0)
return log_error_errno(r, "Failed to attach bus to event loop: %m");
- r = sd_bus_add_match(
+ r = sd_bus_match_signal_async(
bus,
&slot_job_removed,
- "type='signal',"
- "sender='org.freedesktop.import1',"
- "interface='org.freedesktop.import1.Manager',"
- "member='TransferRemoved',"
- "path='/org/freedesktop/import1'",
- match_transfer_removed, &path);
+ "org.freedesktop.import1",
+ "/org/freedesktop/import1",
+ "org.freedesktop.import1.Manager",
+ "TransferRemoved",
+ match_transfer_removed, NULL, &path);
if (r < 0)
- return log_error_errno(r, "Failed to install match: %m");
+ return log_error_errno(r, "Failed to request match: %m");
- r = sd_bus_add_match(
+ r = sd_bus_match_signal_async(
bus,
&slot_log_message,
- "type='signal',"
- "sender='org.freedesktop.import1',"
- "interface='org.freedesktop.import1.Transfer',"
- "member='LogMessage'",
- match_log_message, &path);
+ "org.freedesktop.import1",
+ NULL,
+ "org.freedesktop.import1.Transfer",
+ "LogMessage",
+ match_log_message, NULL, &path);
if (r < 0)
- return log_error_errno(r, "Failed to install match: %m");
+ return log_error_errno(r, "Failed to request match: %m");
r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) {
}
static int list_transfers(int argc, char *argv[], void *userdata) {
- size_t max_type = strlen("TYPE"), max_local = strlen("LOCAL"), max_remote = strlen("REMOTE");
+ size_t max_type = STRLEN("TYPE"), max_local = STRLEN("LOCAL"), max_remote = STRLEN("REMOTE");
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ TransferInfo *transfers = NULL;
double progress;
int r;
- pager_open(arg_no_pager, false);
+ (void) pager_open(arg_no_pager, false);
r = sd_bus_call_method(bus,
"org.freedesktop.import1",
assert(bus);
- polkit_agent_open_if_enabled();
+ polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
for (i = 1; i < argc; i++) {
uint32_t id;
}
static int help(int argc, char *argv[], void *userdata) {
- pager_open(arg_no_pager, false);
+ (void) pager_open(arg_no_pager, false);
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
"Send control commands to or query the virtual machine and container\n"
setlocale(LC_ALL, "");
log_parse_environment();
log_open();
+ sigbus_install();
r = parse_argv(argc, argv);
if (r <= 0)
r = machinectl_main(argc, argv, bus);
finish:
+ /* make sure we terminate the bus connection first, and then close the
+ * pager, see issue #3543 for the details. */
sd_bus_flush_close_unref(bus);
pager_close();
polkit_agent_close();