]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/debug-generator/debug-generator.c
2 This file is part of systemd.
4 Copyright 2014 Lennart Poettering
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.
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.
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/>.
20 #include "alloc-util.h"
22 #include "parse-util.h"
23 #include "proc-cmdline.h"
25 #include "string-util.h"
27 #include "unit-name.h"
30 static char *arg_default_unit
= NULL
;
31 static const char *arg_dest
= "/tmp";
32 static char **arg_mask
= NULL
;
33 static char **arg_wants
= NULL
;
34 static bool arg_debug_shell
= false;
36 static int parse_proc_cmdline_item(const char *key
, const char *value
, void *data
) {
41 if (streq(key
, "systemd.mask")) {
44 if (proc_cmdline_value_missing(key
, value
))
47 r
= unit_name_mangle(value
, UNIT_NAME_NOGLOB
, &n
);
49 return log_error_errno(r
, "Failed to glob unit name: %m");
51 r
= strv_consume(&arg_mask
, n
);
55 } else if (streq(key
, "systemd.wants")) {
58 if (proc_cmdline_value_missing(key
, value
))
61 r
= unit_name_mangle(value
, UNIT_NAME_NOGLOB
, &n
);
63 return log_error_errno(r
, "Failed to glob unit name: %m");
65 r
= strv_consume(&arg_wants
, n
);
69 } else if (proc_cmdline_key_streq(key
, "systemd.debug_shell")) {
72 r
= parse_boolean(value
);
74 log_error("Failed to parse systemd.debug_shell= argument '%s', ignoring.", value
);
78 arg_debug_shell
= true;
80 } else if (streq(key
, "systemd.unit")) {
82 if (proc_cmdline_value_missing(key
, value
))
85 r
= free_and_strdup(&arg_default_unit
, value
);
87 return log_error_errno(r
, "Failed to set default unit %s: %m", value
);
92 target
= runlevel_to_target(key
);
94 r
= free_and_strdup(&arg_default_unit
, target
);
96 return log_error_errno(r
, "Failed to set default unit %s: %m", target
);
103 static int generate_mask_symlinks(void) {
107 if (strv_isempty(arg_mask
))
110 STRV_FOREACH(u
, arg_mask
) {
111 _cleanup_free_
char *p
= NULL
;
113 p
= strjoin(arg_dest
, "/", *u
);
117 if (symlink("/dev/null", p
) < 0)
118 r
= log_error_errno(errno
,
119 "Failed to create mask symlink %s: %m",
126 static int generate_wants_symlinks(void) {
130 if (strv_isempty(arg_wants
))
133 STRV_FOREACH(u
, arg_wants
) {
134 _cleanup_free_
char *p
= NULL
, *f
= NULL
;
135 const char *target
= arg_default_unit
?: SPECIAL_DEFAULT_TARGET
;
137 p
= strjoin(arg_dest
, "/", target
, ".wants/", *u
);
141 f
= strappend(SYSTEM_DATA_UNIT_PATH
"/", *u
);
145 mkdir_parents_label(p
, 0755);
147 if (symlink(f
, p
) < 0)
148 r
= log_error_errno(errno
,
149 "Failed to create wants symlink %s: %m",
156 int main(int argc
, char *argv
[]) {
159 if (argc
> 1 && argc
!= 4) {
160 log_error("This program takes three or no arguments.");
167 log_set_target(LOG_TARGET_SAFE
);
168 log_parse_environment();
173 r
= proc_cmdline_parse(parse_proc_cmdline_item
, NULL
, 0);
175 log_warning_errno(r
, "Failed to parse kernel command line, ignoring: %m");
177 if (arg_debug_shell
) {
178 r
= strv_extend(&arg_wants
, "debug-shell.service");
185 r
= generate_mask_symlinks();
187 q
= generate_wants_symlinks();
192 arg_default_unit
= mfree(arg_default_unit
);
194 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;