]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/hibernate-resume/hibernate-resume.c
hibernate-resume: EINVAL -> ENOTBLK where appropriate
[thirdparty/systemd.git] / src / hibernate-resume / hibernate-resume.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
42483a74 2
42483a74 3#include <errno.h>
42483a74 4#include <sys/stat.h>
42483a74 5
ec61371f 6#include "devnum-util.h"
a628d933 7#include "hibernate-resume-config.h"
54d7fcc6 8#include "hibernate-util.h"
baa6a42d 9#include "initrd-util.h"
42483a74 10#include "log.h"
760e99bb
MY
11#include "main-func.h"
12#include "parse-util.h"
a628d933 13#include "static-destruct.h"
42483a74 14
a3f7047f 15static HibernateInfo arg_info = {};
a628d933
MY
16
17STATIC_DESTRUCTOR_REGISTER(arg_info, hibernate_info_done);
18
19static int setup_hibernate_info_and_warn(void) {
20 int r;
21
22 r = acquire_hibernate_info(&arg_info);
23 if (r == -ENODEV) {
24 log_info_errno(r, "No resume device found, exiting.");
25 return 0;
26 }
27 if (r < 0)
28 return r;
29
30 compare_hibernate_location_and_warn(&arg_info);
31
32 return 1;
33}
760e99bb
MY
34
35static int run(int argc, char *argv[]) {
42483a74 36 struct stat st;
42483a74
IS
37 int r;
38
d2acb93d 39 log_setup();
42483a74 40
a628d933
MY
41 if (argc < 1 || argc > 3)
42 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program expects zero, one, or two arguments.");
760e99bb 43
42483a74
IS
44 umask(0022);
45
ac528e3e 46 if (!in_initrd())
760e99bb 47 return 0;
ac528e3e 48
a628d933
MY
49 if (argc > 1) {
50 arg_info.device = argv[1];
51
52 if (argc == 3) {
53 r = safe_atou64(argv[2], &arg_info.offset);
54 if (r < 0)
55 return log_error_errno(r, "Failed to parse resume offset %s: %m", argv[2]);
56 }
57 } else {
58 r = setup_hibernate_info_and_warn();
59 if (r <= 0)
60 return r;
42483a74 61
24ab77c3 62 if (arg_info.efi)
fbc88824 63 (void) clear_efi_hibernate_location_and_warn();
42483a74
IS
64 }
65
a628d933
MY
66 if (stat(arg_info.device, &st) < 0)
67 return log_error_errno(errno, "Failed to stat resume device '%s': %m", arg_info.device);
42483a74 68
760e99bb 69 if (!S_ISBLK(st.st_mode))
667b0c48 70 return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK),
a628d933 71 "Resume device '%s' is not a block device.", arg_info.device);
42483a74 72
760e99bb 73 /* The write shall not return if a resume takes place. */
a628d933 74 r = write_resume_config(st.st_rdev, arg_info.offset, arg_info.device);
760e99bb
MY
75 log_full_errno(r < 0 ? LOG_ERR : LOG_DEBUG,
76 r < 0 ? r : SYNTHETIC_ERRNO(ENOENT),
77 "Unable to resume from device '%s' (" DEVNUM_FORMAT_STR ") offset %" PRIu64 ", continuing boot process.",
a628d933 78 arg_info.device, DEVNUM_FORMAT_VAL(st.st_rdev), arg_info.offset);
42483a74 79
760e99bb 80 return r;
42483a74 81}
760e99bb
MY
82
83DEFINE_MAIN_FUNCTION(run);