#include "bus-common-errors.h"
#include "mkdir.h"
#include "dropin.h"
+#include "efivars.h"
+#include "formats-util.h"
+#include "process-util.h"
static char **arg_types = NULL;
static char **arg_states = NULL;
static unsigned arg_lines = 10;
static OutputMode arg_output = OUTPUT_SHORT;
static bool arg_plain = false;
+static bool arg_firmware_setup = false;
static bool original_stdout_is_tty;
_cleanup_free_ UnitInfo *unit_infos = NULL;
if (!bus)
- return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
+ return log_error_errno(EOPNOTSUPP, "Unit name globbing without bus is not implemented.");
r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
if (r < 0)
if (!sv)
return log_oom();
+ if ((pid_t) pid < 0)
+ return log_error_errno(ERANGE, "Bad PID %"PRIu32": %m", pid);
+
if (!strv_contains(sv,
a == ACTION_HALT ||
a == ACTION_POWEROFF ||
user = uid_to_name(uid);
log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
- who, pid, strna(comm), strna(user), why);
+ who, (pid_t) pid, strna(comm), strna(user), why);
c++;
}
#endif
}
+static int prepare_firmware_setup(sd_bus *bus) {
+#ifdef HAVE_LOGIND
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+#endif
+ int r;
+
+ if (!arg_firmware_setup)
+ return 0;
+
+ if (arg_transport == BUS_TRANSPORT_LOCAL) {
+
+ r = efi_set_reboot_to_firmware(true);
+ if (r < 0)
+ log_debug_errno(r, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
+ else
+ return r;
+ }
+
+#ifdef HAVE_LOGIND
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "SetRebootToFirmwareSetup",
+ &error,
+ NULL,
+ "b", true);
+ if (r < 0) {
+ log_error("Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error, r));
+ return r;
+ }
+
+ return 0;
+#else
+ log_error("Cannot remotely indicate to EFI to boot into setup mode.");
+ return -EINVAL;
+#endif
+}
+
static int start_special(sd_bus *bus, char **args) {
enum action a;
int r;
return -EPERM;
}
+ r = prepare_firmware_setup(bus);
+ if (r < 0)
+ return r;
+
if (a == ACTION_REBOOT && args[1]) {
r = update_reboot_param_file(args[1]);
if (r < 0)
a == ACTION_HIBERNATE ||
a == ACTION_HYBRID_SLEEP)) {
r = reboot_with_logind(bus, a);
- if (r >= 0 || IN_SET(r, -ENOTSUP, -EINPROGRESS))
+ if (r >= 0 || IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
return r;
}
/* CGroup */
uint64_t memory_current;
uint64_t memory_limit;
+ uint64_t cpu_usage_nsec;
LIST_HEAD(ExecStatusInfo, exec);
} UnitStatusInfo;
printf("\n");
}
+ if (i->cpu_usage_nsec != (uint64_t) -1) {
+ char buf[FORMAT_TIMESPAN_MAX];
+ printf(" CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
+ }
+
if (i->control_group &&
(i->main_pid > 0 || i->control_pid > 0 ||
((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
i->memory_current = u;
else if (streq(name, "MemoryLimit"))
i->memory_limit = u;
+ else if (streq(name, "CPUUsageNSec"))
+ i->cpu_usage_nsec = u;
break;
}
UnitStatusInfo info = {
.memory_current = (uint64_t) -1,
.memory_limit = (uint64_t) -1,
+ .cpu_usage_nsec = (uint64_t) -1,
};
ExecStatusInfo *p;
int r;
return 0;
}
+static int cat_file(const char *filename, bool newline) {
+ _cleanup_close_ int fd;
+
+ fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0)
+ return -errno;
+
+ printf("%s%s# %s%s\n",
+ newline ? "\n" : "",
+ ansi_highlight_blue(),
+ filename,
+ ansi_highlight_off());
+ fflush(stdout);
+
+ return copy_bytes(fd, STDOUT_FILENO, (off_t) -1, false);
+}
+
static int cat(sd_bus *bus, char **args) {
_cleanup_free_ char *user_home = NULL;
_cleanup_free_ char *user_runtime = NULL;
_cleanup_strv_free_ char **names = NULL;
char **name;
bool first = true, avoid_bus_cache;
- int r = 0;
+ int r;
assert(args);
puts("");
if (fragment_path) {
- printf("%s# %s%s\n",
- ansi_highlight_blue(),
- fragment_path,
- ansi_highlight_off());
- fflush(stdout);
-
- r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
- if (r < 0) {
- log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
- continue;
- }
+ r = cat_file(fragment_path, false);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
}
STRV_FOREACH(path, dropin_paths) {
- printf("%s%s# %s%s\n",
- isempty(fragment_path) && path == dropin_paths ? "" : "\n",
- ansi_highlight_blue(),
- *path,
- ansi_highlight_off());
- fflush(stdout);
-
- r = copy_file_fd(*path, STDOUT_FILENO, false);
- if (r < 0) {
- log_warning_errno(r, "Failed to cat %s: %m", *path);
- continue;
- }
+ r = cat_file(*path, path == dropin_paths);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to cat %s: %m", *path);
}
}
- return r < 0 ? r : 0;
+ return 0;
}
static int set_property(sd_bus *bus, char **args) {
" -o --output=STRING Change journal output mode (short, short-iso,\n"
" short-precise, short-monotonic, verbose,\n"
" export, json, json-pretty, json-sse, cat)\n"
+ " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
" --plain Print unit dependencies as a list instead of a tree\n\n"
"Unit Commands:\n"
" list-units [PATTERN...] List loaded units\n"
ARG_STATE,
ARG_JOB_MODE,
ARG_PRESET_MODE,
+ ARG_FIRMWARE_SETUP,
};
static const struct option options[] = {
{ "state", required_argument, NULL, ARG_STATE },
{ "recursive", no_argument, NULL, 'r' },
{ "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
+ { "firmware-setup", no_argument, NULL, ARG_FIRMWARE_SETUP },
{}
};
arg_plain = true;
break;
+ case ARG_FIRMWARE_SETUP:
+ arg_firmware_setup = true;
+ break;
+
case ARG_STATE: {
const char *word, *state;
size_t size;
}
}
+ /* Increase max number of open files to 16K if we can, we
+ * might needs this when browsing journal files, which might
+ * be split up into many files. */
+ setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
+
return verb->dispatch(bus, argv + optind);
}
goto finish;
}
- /* Increase max number of open files to 16K if we can, we
- * might needs this when browsing journal files, which might
- * be split up into many files. */
- setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
-
if (!avoid_bus())
r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);