• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 18251268710

04 Oct 2025 09:35PM UTC coverage: 72.225% (-0.06%) from 72.28%
18251268710

push

github

web-flow
shared/bootspec: don't warn for new `loader.conf` options and correctly parse new `uki` and `profile` boot entry options (#39165)

Commit e2a3d5621 added the `uki` option
to sd-boot, and 1e9c9773b added
`profile`, but because these were not added in src/shared/bootspec,
bootctl still shows warnings like `Unknown line 'uki', ignoring.` when
parsing the config. This PR allows parsing and displaying them correctly
in `bootctl` output. It also stops it from printing a warning for any of
the new `loader.conf` options (`log-level`, `reboot-on-error`, etc.).
Note that `uki-url` is still not handled as I can't easily test it.

4 of 12 new or added lines in 2 files covered. (33.33%)

3065 existing lines in 68 files now uncovered.

303282 of 419915 relevant lines covered (72.22%)

1059441.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.06
/src/shared/parse-argument.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include "alloc-util.h"
4
#include "bus-util.h"
5
#include "format-table.h"
6
#include "hostname-util.h"
7
#include "log.h"
8
#include "parse-argument.h"
9
#include "parse-util.h"
10
#include "path-util.h"
11
#include "signal-util.h"
12
#include "string-table.h"
13
#include "string-util.h"
14

15
/* All functions in this file emit warnings. */
16

17
int parse_boolean_argument(const char *optname, const char *s, bool *ret) {
1,241✔
18
        int r;
1,241✔
19

20
        /* Returns the result through *ret and the return value. */
21

22
        if (s) {
1,241✔
23
                r = parse_boolean(s);
1,236✔
24
                if (r < 0)
1,236✔
25
                        return log_error_errno(r, "Failed to parse boolean argument to %s: %s.", optname, s);
33✔
26

27
                if (ret)
1,203✔
28
                        *ret = r;
966✔
29
                return r;
1,203✔
30
        } else {
31
                /* s may be NULL. This is controlled by getopt_long() parameters. */
32
                if (ret)
5✔
33
                        *ret = true;
5✔
34
                return true;
5✔
35
        }
36
}
37

38
int parse_tristate_argument(const char *optname, const char *s, int *ret) {
120✔
39
        int r;
120✔
40

41
        if (s) {
120✔
42
                r = parse_boolean(s);
120✔
43
                if (r < 0)
120✔
44
                        return log_error_errno(r, "Failed to parse boolean argument to %s: %s.", optname, s);
×
45

46
                if (ret)
120✔
47
                        *ret = r;
120✔
48

49
                return r;
120✔
50
        } else {
51
                if (ret)
×
52
                        *ret = -1;
×
53

54
                return 0;
×
55
        }
56
}
57

58
int parse_json_argument(const char *s, sd_json_format_flags_t *ret) {
301✔
59
        assert(s);
301✔
60
        assert(ret);
301✔
61

62
        if (streq(s, "pretty"))
301✔
63
                *ret = SD_JSON_FORMAT_PRETTY|SD_JSON_FORMAT_COLOR_AUTO;
98✔
64
        else if (streq(s, "short"))
203✔
65
                *ret = SD_JSON_FORMAT_NEWLINE;
181✔
66
        else if (streq(s, "off"))
22✔
67
                *ret = SD_JSON_FORMAT_OFF;
11✔
68
        else if (streq(s, "help")) {
11✔
69
                puts("pretty\n"
3✔
70
                     "short\n"
71
                     "off");
72
                return 0; /* 0 means → we showed a brief help, exit now */
3✔
73
        } else
74
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown argument to --json= switch: %s", s);
8✔
75

76
        return 1; /* 1 means → properly parsed */
77
}
78

79
int parse_path_argument(const char *path, bool suppress_root, char **arg) {
2,210✔
80
        char *p;
2,210✔
81
        int r;
2,210✔
82

83
        /*
84
         * This function is intended to be used in command line parsers, to handle paths that are passed
85
         * in. It makes the path absolute, and reduces it to NULL if omitted or root (the latter optionally).
86
         *
87
         * NOTE THAT THIS WILL FREE THE PREVIOUS ARGUMENT POINTER ON SUCCESS!
88
         * Hence, do not pass in uninitialized pointers.
89
         */
90

91
        if (isempty(path)) {
2,210✔
92
                *arg = mfree(*arg);
8✔
93
                return 0;
8✔
94
        }
95

96
        r = path_make_absolute_cwd(path, &p);
2,202✔
97
        if (r < 0)
2,202✔
98
                return log_error_errno(r, "Failed to parse path \"%s\" and make it absolute: %m", path);
×
99

100
        path_simplify(p);
2,202✔
101
        if (suppress_root && empty_or_root(p))
2,202✔
102
                p = mfree(p);
3✔
103

104
        return free_and_replace(*arg, p);
2,202✔
105
}
106

107
int parse_signal_argument(const char *s, int *ret) {
30✔
108
        int r;
30✔
109

110
        assert(s);
30✔
111
        assert(ret);
30✔
112

113
        if (streq(s, "help"))
30✔
114
                return DUMP_STRING_TABLE(signal, int, _NSIG);
132✔
115

116
        if (streq(s, "list")) {
28✔
117
                _cleanup_(table_unrefp) Table *table = NULL;
1✔
118

119
                table = table_new("signal", "name");
1✔
120
                if (!table)
1✔
UNCOV
121
                        return log_oom();
×
122

123
                for (int i = 1; i < _NSIG; i++) {
65✔
124
                        r = table_add_many(
64✔
125
                                        table,
126
                                        TABLE_INT, i,
127
                                        TABLE_SIGNAL, i);
128
                        if (r < 0)
64✔
UNCOV
129
                                return table_log_add_error(r);
×
130
                }
131

132
                r = table_print(table, NULL);
1✔
133
                if (r < 0)
1✔
UNCOV
134
                        return table_log_print_error(r);
×
135

136
                return 0;
137
        }
138

139
        r = signal_from_string(s);
27✔
140
        if (r < 0)
27✔
UNCOV
141
                return log_error_errno(r, "Failed to parse signal string \"%s\".", s);
×
142

143
        *ret = r;
27✔
144
        return 1; /* work to do */
27✔
145
}
146

147
int parse_machine_argument(const char *s, const char **ret_host, BusTransport *ret_transport) {
99✔
148
        int r;
99✔
149

150
        assert(s);
99✔
151
        assert(ret_host);
99✔
152

153
        r = machine_spec_valid(s);
99✔
154
        if (r < 0)
99✔
UNCOV
155
                return log_error_errno(r, "Failed to validate --machine= argument '%s': %m", s);
×
156
        if (r == 0)
99✔
157
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid --machine= specified: %s", s);
×
158

159
        *ret_host = s;
99✔
160

161
        if (ret_transport)
99✔
162
                *ret_transport = BUS_TRANSPORT_MACHINE;
99✔
163

164
        return 0;
165
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc