]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/debug-generator/debug-generator.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2014 Lennart Poettering
8 #include "alloc-util.h"
10 #include "parse-util.h"
11 #include "proc-cmdline.h"
13 #include "string-util.h"
15 #include "unit-name.h"
18 static char *arg_default_unit
= NULL
;
19 static const char *arg_dest
= "/tmp";
20 static char **arg_mask
= NULL
;
21 static char **arg_wants
= NULL
;
22 static bool arg_debug_shell
= false;
24 static int parse_proc_cmdline_item(const char *key
, const char *value
, void *data
) {
29 if (streq(key
, "systemd.mask")) {
32 if (proc_cmdline_value_missing(key
, value
))
35 r
= unit_name_mangle(value
, UNIT_NAME_MANGLE_WARN
, &n
);
37 return log_error_errno(r
, "Failed to glob unit name: %m");
39 r
= strv_consume(&arg_mask
, n
);
43 } else if (streq(key
, "systemd.wants")) {
46 if (proc_cmdline_value_missing(key
, value
))
49 r
= unit_name_mangle(value
, UNIT_NAME_MANGLE_WARN
, &n
);
51 return log_error_errno(r
, "Failed to glob unit name: %m");
53 r
= strv_consume(&arg_wants
, n
);
57 } else if (proc_cmdline_key_streq(key
, "systemd.debug_shell")) {
60 r
= parse_boolean(value
);
62 log_error("Failed to parse systemd.debug_shell= argument '%s', ignoring.", value
);
66 arg_debug_shell
= true;
68 } else if (streq(key
, "systemd.unit")) {
70 if (proc_cmdline_value_missing(key
, value
))
73 r
= free_and_strdup(&arg_default_unit
, value
);
75 return log_error_errno(r
, "Failed to set default unit %s: %m", value
);
80 target
= runlevel_to_target(key
);
82 r
= free_and_strdup(&arg_default_unit
, target
);
84 return log_error_errno(r
, "Failed to set default unit %s: %m", target
);
91 static int generate_mask_symlinks(void) {
95 if (strv_isempty(arg_mask
))
98 STRV_FOREACH(u
, arg_mask
) {
99 _cleanup_free_
char *p
= NULL
;
101 p
= strjoin(arg_dest
, "/", *u
);
105 if (symlink("/dev/null", p
) < 0)
106 r
= log_error_errno(errno
,
107 "Failed to create mask symlink %s: %m",
114 static int generate_wants_symlinks(void) {
118 if (strv_isempty(arg_wants
))
121 STRV_FOREACH(u
, arg_wants
) {
122 _cleanup_free_
char *p
= NULL
, *f
= NULL
;
123 const char *target
= arg_default_unit
?: SPECIAL_DEFAULT_TARGET
;
125 p
= strjoin(arg_dest
, "/", target
, ".wants/", *u
);
129 f
= strappend(SYSTEM_DATA_UNIT_PATH
"/", *u
);
133 mkdir_parents_label(p
, 0755);
135 if (symlink(f
, p
) < 0)
136 r
= log_error_errno(errno
,
137 "Failed to create wants symlink %s: %m",
144 int main(int argc
, char *argv
[]) {
147 if (argc
> 1 && argc
!= 4) {
148 log_error("This program takes three or no arguments.");
155 log_set_prohibit_ipc(true);
156 log_set_target(LOG_TARGET_AUTO
);
157 log_parse_environment();
162 r
= proc_cmdline_parse(parse_proc_cmdline_item
, NULL
, 0);
164 log_warning_errno(r
, "Failed to parse kernel command line, ignoring: %m");
166 if (arg_debug_shell
) {
167 r
= strv_extend(&arg_wants
, "debug-shell.service");
174 r
= generate_mask_symlinks();
176 q
= generate_wants_symlinks();
181 arg_default_unit
= mfree(arg_default_unit
);
183 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;