]> git.ipfire.org Git - thirdparty/systemd.git/blob - 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
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
23 #include "fs-util.h"
24 #include "log.h"
25 #include "proc-cmdline.h"
26 #include "special.h"
27 #include "string-util.h"
28 #include "util.h"
29
30 /*
31 * Implements the logic described in systemd.offline-updates(7).
32 */
33
34 static const char *arg_dest = "/tmp";
35
36 static int generate_symlink(void) {
37 const char *p = NULL;
38
39 if (laccess("/system-update", F_OK) < 0) {
40 if (errno == ENOENT)
41 return 0;
42
43 log_error_errno(errno, "Failed to check for system update: %m");
44 return -EINVAL;
45 }
46
47 p = strjoina(arg_dest, "/" SPECIAL_DEFAULT_TARGET);
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);
50
51 return 1;
52 }
53
54 static 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
67 return 0;
68 }
69
70 int main(int argc, char *argv[]) {
71 int r, k;
72
73 if (argc > 1 && argc != 4) {
74 log_error("This program takes three or no arguments.");
75 return EXIT_FAILURE;
76 }
77
78 if (argc > 1)
79 arg_dest = argv[2];
80
81 log_set_target(LOG_TARGET_SAFE);
82 log_parse_environment();
83 log_open();
84
85 umask(0022);
86
87 r = generate_symlink();
88
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
95 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
96 }