Systemd/src/hibernate-resume/hibernate-resume-generator.c
Zbigniew Jędrzejewski-Szmek ca78ad1de9 headers: remove unneeded includes from util.h
This means we need to include many more headers in various files that simply
included util.h before, but it seems cleaner to do it this way.
2019-03-27 11:53:12 +01:00

103 lines
2.8 KiB
C

/* SPDX-License-Identifier: LGPL-2.1+ */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include "alloc-util.h"
#include "fstab-util.h"
#include "generator.h"
#include "log.h"
#include "main-func.h"
#include "mkdir.h"
#include "proc-cmdline.h"
#include "special.h"
#include "string-util.h"
#include "unit-name.h"
static const char *arg_dest = "/tmp";
static char *arg_resume_device = NULL;
static bool arg_noresume = false;
STATIC_DESTRUCTOR_REGISTER(arg_resume_device, freep);
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
if (streq(key, "resume")) {
char *s;
if (proc_cmdline_value_missing(key, value))
return 0;
s = fstab_node_to_udev_node(value);
if (!s)
return log_oom();
free_and_replace(arg_resume_device, s);
} else if (streq(key, "noresume")) {
if (value) {
log_warning("\"noresume\" kernel command line switch specified with an argument, ignoring.");
return 0;
}
arg_noresume = true;
}
return 0;
}
static int process_resume(void) {
_cleanup_free_ char *name = NULL, *lnk = NULL;
int r;
if (!arg_resume_device)
return 0;
r = unit_name_from_path_instance("systemd-hibernate-resume", arg_resume_device, ".service", &name);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
lnk = strjoin(arg_dest, "/" SPECIAL_SYSINIT_TARGET ".wants/", name);
if (!lnk)
return log_oom();
mkdir_parents_label(lnk, 0755);
if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-hibernate-resume@.service", lnk) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
return 0;
}
static int run(int argc, char *argv[]) {
int r = 0;
log_setup_generator();
if (argc > 1 && argc != 4)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"This program takes three or no arguments.");
if (argc > 1)
arg_dest = argv[1];
/* Don't even consider resuming outside of initramfs. */
if (!in_initrd()) {
log_debug("Not running in an initrd, quitting.");
return 0;
}
r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
if (arg_noresume) {
log_notice("Found \"noresume\" on the kernel command line, quitting.");
return 0;
}
return process_resume();
}
DEFINE_MAIN_FUNCTION(run);