shutdown: Bump sysctl kernel.printk log level in order to see info msg

This commit is contained in:
Benjamin Robin 2019-04-03 21:00:01 +02:00
parent a012f9f7cf
commit 827156b330

View file

@ -32,6 +32,7 @@
#include "signal-util.h"
#include "string-util.h"
#include "switch-root.h"
#include "sysctl-util.h"
#include "terminal-util.h"
#include "umount.h"
#include "util.h"
@ -255,6 +256,42 @@ static void sync_with_progress(void) {
(void) kill(pid, SIGKILL);
}
static int read_current_sysctl_printk_log_level(void) {
_cleanup_free_ char *sysctl_printk_vals = NULL, *sysctl_printk_curr = NULL;
unsigned current_lvl = 0;
const char *p;
int r;
r = sysctl_read("kernel/printk", &sysctl_printk_vals);
if (r < 0)
return log_debug_errno(r, "Cannot read sysctl kernel.printk: %m");
p = sysctl_printk_vals;
r = extract_first_word(&p, &sysctl_printk_curr, NULL, 0);
if (r > 0)
r = safe_atou(sysctl_printk_curr, &current_lvl);
else if (r == 0)
r = -EINVAL;
if (r < 0)
return log_debug_errno(r, "Unexpected sysctl kernel.printk content: %s", sysctl_printk_vals);
return current_lvl;
}
static void bump_sysctl_printk_log_level(int min_level) {
/* Set the logging level to be able to see messages with log level smaller or equal to min_level */
int current_lvl = read_current_sysctl_printk_log_level();
if (current_lvl >= 0 && current_lvl <= min_level) {
char buf[DECIMAL_STR_MAX(int)];
xsprintf(buf, "%d", min_level + 1);
int r = sysctl_write("kernel/printk", buf);
if (r < 0)
log_debug_errno(r, "Failed to bump kernel.printk to %s: %m", buf);
}
}
int main(int argc, char *argv[]) {
bool need_umount, need_swapoff, need_loop_detach, need_dm_detach;
bool in_container, use_watchdog = false, can_initrd;
@ -305,6 +342,16 @@ int main(int argc, char *argv[]) {
(void) cg_get_root_path(&cgroup);
in_container = detect_container() > 0;
/* If the logging messages are going to KMSG, and if we are not running from a container,
* then try to update the sysctl kernel.printk current value in order to see "info" messages;
* This current log level is not updated if already big enough.
*/
if (!in_container && IN_SET(log_get_target(), LOG_TARGET_AUTO,
LOG_TARGET_JOURNAL_OR_KMSG,
LOG_TARGET_SYSLOG_OR_KMSG,
LOG_TARGET_KMSG))
bump_sysctl_printk_log_level(LOG_INFO);
use_watchdog = getenv("WATCHDOG_USEC");
watchdog_device = getenv("WATCHDOG_DEVICE");
if (watchdog_device) {