]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/system-update-generator/system-update-generator.c
Merge pull request #7388 from keszybz/doc-tweak
[thirdparty/systemd.git] / src / system-update-generator / system-update-generator.c
CommitLineData
d360705f
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2012 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
20#include <errno.h>
21#include <unistd.h>
22
f4f15635 23#include "fs-util.h"
d360705f 24#include "log.h"
1cec251c 25#include "proc-cmdline.h"
075dafd2 26#include "special.h"
07630cea 27#include "string-util.h"
d360705f 28#include "util.h"
d360705f 29
399c5f96 30/*
075dafd2 31 * Implements the logic described in systemd.offline-updates(7).
399c5f96
LP
32 */
33
d360705f
LP
34static const char *arg_dest = "/tmp";
35
36static int generate_symlink(void) {
9194c8e4 37 const char *p = NULL;
d360705f 38
6b321a79 39 if (laccess("/system-update", F_OK) < 0) {
d360705f
LP
40 if (errno == ENOENT)
41 return 0;
42
56f64d95 43 log_error_errno(errno, "Failed to check for system update: %m");
d360705f
LP
44 return -EINVAL;
45 }
46
075dafd2 47 p = strjoina(arg_dest, "/" SPECIAL_DEFAULT_TARGET);
4a62c710
MS
48 if (symlink(SYSTEM_DATA_UNIT_PATH "/system-update.target", p) < 0)
49 return log_error_errno(errno, "Failed to create symlink %s: %m", p);
d360705f 50
1cec251c
ZJS
51 return 1;
52}
53
54static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
55 assert(key);
56
57 /* Check if a run level is specified on the kernel command line. The
58 * command line has higher priority than any on-disk configuration, so
59 * it'll make any symlink we create moot.
60 */
61
62 if (streq(key, "systemd.unit") && !proc_cmdline_value_missing(key, value))
63 log_warning("Offline system update overriden by kernel command line systemd.unit= setting");
64 else if (!value && runlevel_to_target(key))
65 log_warning("Offline system update overriden by runlevel \"%s\" on the kernel command line", key);
66
d360705f
LP
67 return 0;
68}
69
70int main(int argc, char *argv[]) {
1cec251c 71 int r, k;
d360705f 72
07719a21
LP
73 if (argc > 1 && argc != 4) {
74 log_error("This program takes three or no arguments.");
d360705f
LP
75 return EXIT_FAILURE;
76 }
77
78 if (argc > 1)
07719a21 79 arg_dest = argv[2];
d360705f 80
a6903061 81 log_set_target(LOG_TARGET_SAFE);
d360705f
LP
82 log_parse_environment();
83 log_open();
84
85 umask(0022);
86
87 r = generate_symlink();
88
1cec251c
ZJS
89 if (r > 0) {
90 k = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
91 if (k < 0)
92 log_warning_errno(k, "Failed to parse kernel command line, ignoring: %m");
93 }
94
d360705f
LP
95 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
96}