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

systemd / systemd / 15986406979

30 Jun 2025 05:03PM UTC coverage: 72.045% (-0.09%) from 72.13%
15986406979

push

github

bluca
man/systemd-sysext: list ephemeral/ephemeral-import in the list of options

ephemeral/ephemeral-import are described as possible '--mutable' options but
not present in the list. Note, "systemd-sysext --help" lists them correctly.

300514 of 417119 relevant lines covered (72.05%)

708586.28 hits per line

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

7.69
/src/systemctl/systemctl-sysv-compat.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <fcntl.h>
4
#include <stdlib.h>
5
#include <unistd.h>
6

7
#include "env-util.h"
8
#include "fd-util.h"
9
#include "initreq.h"
10
#include "install.h"
11
#include "io-util.h"
12
#include "log.h"
13
#include "parse-util.h"
14
#include "path-lookup.h"
15
#include "path-util.h"
16
#include "process-util.h"
17
#include "string-util.h"
18
#include "strv.h"
19
#include "systemctl.h"
20
#include "systemctl-sysv-compat.h"
21
#include "time-util.h"
22

23
int talk_initctl(char rl) {
×
24
#if HAVE_SYSV_COMPAT
25
        _cleanup_close_ int fd = -EBADF;
26
        const char *path;
27
        int r;
28

29
        /* Try to switch to the specified SysV runlevel. Returns == 0 if the operation does not apply on this
30
         * system, and > 0 on success. */
31

32
        if (rl == 0)
33
                return 0;
34

35
        FOREACH_STRING(_path, "/run/initctl", "/dev/initctl") {
36
                path = _path;
37

38
                fd = open(path, O_WRONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
39
                if (fd < 0 && errno != ENOENT)
40
                        return log_error_errno(errno, "Failed to open %s: %m", path);
41
                if (fd >= 0)
42
                        break;
43
        }
44
        if (fd < 0)
45
                return 0;
46

47
        struct init_request request = {
48
                .magic = INIT_MAGIC,
49
                .sleeptime = 0,
50
                .cmd = INIT_CMD_RUNLVL,
51
                .runlevel = rl,
52
        };
53

54
        r = loop_write(fd, &request, sizeof(request));
55
        if (r < 0)
56
                return log_error_errno(r, "Failed to write to %s: %m", path);
57

58
        return 1;
59
#else
60
        return -EOPNOTSUPP;
×
61
#endif
62
}
63

64
int parse_shutdown_time_spec(const char *t, usec_t *ret) {
×
65
        int r;
×
66

67
        assert(t);
×
68
        assert(ret);
×
69

70
        if (streq(t, "now"))
×
71
                *ret = 0;
×
72
        else if (!strchr(t, ':')) {
×
73
                uint64_t u;
×
74

75
                if (safe_atou64(t, &u) < 0)
×
76
                        return -EINVAL;
×
77

78
                *ret = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
×
79
        } else {
80
                char *e = NULL;
×
81
                long hour, minute;
×
82

83
                errno = 0;
×
84
                hour = strtol(t, &e, 10);
×
85
                if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
×
86
                        return -EINVAL;
×
87

88
                minute = strtol(e+1, &e, 10);
×
89
                if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
×
90
                        return -EINVAL;
91

92
                usec_t n = now(CLOCK_REALTIME);
×
93
                struct tm tm = {};
×
94

95
                r = localtime_or_gmtime_usec(n, /* utc= */ false, &tm);
×
96
                if (r < 0)
×
97
                        return r;
98

99
                tm.tm_hour = (int) hour;
×
100
                tm.tm_min = (int) minute;
×
101
                tm.tm_sec = 0;
×
102

103
                usec_t s;
×
104
                r = mktime_or_timegm_usec(&tm, /* utc= */ false, &s);
×
105
                if (r < 0)
×
106
                        return r;
107

108
                while (s <= n)
×
109
                        s += USEC_PER_DAY;
×
110

111
                *ret = s;
×
112
        }
113

114
        return 0;
115
}
116

117
int enable_sysv_units(const char *verb, char **args) {
479✔
118
        int r = 0;
479✔
119

120
#if HAVE_SYSV_COMPAT
121
        _cleanup_(lookup_paths_done) LookupPaths paths = {};
122
        unsigned f = 0;
123
        SysVUnitEnableState enable_state = SYSV_UNIT_NOT_FOUND;
124

125
        /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
126

127
        if (arg_runtime_scope != RUNTIME_SCOPE_SYSTEM)
128
                return 0;
129

130
        if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
131
                return 0;
132

133
        if (!STR_IN_SET(verb,
134
                        "enable",
135
                        "disable",
136
                        "is-enabled"))
137
                return 0;
138

139
        r = lookup_paths_init_or_warn(&paths, arg_runtime_scope, LOOKUP_PATHS_EXCLUDE_GENERATED, arg_root);
140
        if (r < 0)
141
                return r;
142

143
        r = 0;
144
        while (args[f]) {
145

146
                const char *argv[] = {
147
                        LIBEXECDIR "/systemd-sysv-install",
148
                        NULL, /* --root= */
149
                        NULL, /* verb */
150
                        NULL, /* service */
151
                        NULL,
152
                };
153

154
                _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL, *v = NULL, *b = NULL;
155
                bool found_native = false, found_sysv;
156
                const char *name;
157
                unsigned c = 1;
158
                pid_t pid;
159
                int j;
160

161
                name = args[f++];
162

163
                if (!endswith(name, ".service"))
164
                        continue;
165

166
                if (path_is_absolute(name))
167
                        continue;
168

169
                j = unit_file_exists(arg_runtime_scope, &paths, name);
170
                if (j < 0 && !IN_SET(j, -ELOOP, -ERFKILL, -EADDRNOTAVAIL))
171
                        return log_error_errno(j, "Failed to look up unit file state: %m");
172
                found_native = j != 0;
173

174
                /* If we have both a native unit and a SysV script, enable/disable them both (below); for
175
                 * is-enabled, prefer the native unit */
176
                if (found_native && streq(verb, "is-enabled"))
177
                        continue;
178

179
                p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
180
                if (!p)
181
                        return log_oom();
182

183
                p[strlen(p) - STRLEN(".service")] = 0;
184
                found_sysv = access(p, F_OK) >= 0;
185
                if (!found_sysv)
186
                        continue;
187

188
                if (!arg_quiet) {
189
                        if (found_native)
190
                                log_info("Synchronizing state of %s with SysV service script with %s.", name, argv[0]);
191
                        else
192
                                log_info("%s is not a native service, redirecting to systemd-sysv-install.", name);
193
                }
194

195
                if (!isempty(arg_root)) {
196
                        q = strjoin("--root=", arg_root);
197
                        if (!q)
198
                                return log_oom();
199

200
                        argv[c++] = q;
201
                }
202

203
                /* Let's copy the verb, since it's still pointing directly into the original argv[] array we
204
                 * got passed, but safe_fork() is likely going to rewrite that for the new child */
205
                v = strdup(verb);
206
                if (!v)
207
                        return log_oom();
208

209
                j = path_extract_filename(p, &b);
210
                if (j < 0)
211
                        return log_error_errno(j, "Failed to extract file name from '%s': %m", p);
212

213
                argv[c++] = v;
214
                argv[c++] = b;
215
                argv[c] = NULL;
216

217
                l = strv_join((char**)argv, " ");
218
                if (!l)
219
                        return log_oom();
220

221
                if (!arg_quiet)
222
                        log_info("Executing: %s", l);
223

224
                j = safe_fork("(sysv-install)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
225
                if (j < 0)
226
                        return j;
227
                if (j == 0) {
228
                        /* Child */
229
                        execv(argv[0], (char**) argv);
230
                        log_error_errno(errno, "Failed to execute %s: %m", argv[0]);
231
                        _exit(EXIT_FAILURE);
232
                }
233

234
                j = wait_for_terminate_and_check("sysv-install", pid, WAIT_LOG_ABNORMAL);
235
                if (j < 0)
236
                        return j;
237
                if (streq(verb, "is-enabled")) {
238
                        if (j == EXIT_SUCCESS) {
239
                                if (!arg_quiet)
240
                                        puts("enabled");
241
                                enable_state = SYSV_UNIT_ENABLED;
242
                        } else {
243
                                if (!arg_quiet)
244
                                        puts("disabled");
245
                                if (enable_state != SYSV_UNIT_ENABLED)
246
                                        enable_state = SYSV_UNIT_DISABLED;
247
                        }
248

249
                } else if (j != EXIT_SUCCESS)
250
                        return -EBADE; /* We don't warn here, under the assumption the script already showed an explanation */
251

252
                if (found_native)
253
                        continue;
254

255
                /* Remove this entry, so that we don't try enabling it as native unit */
256
                assert(f > 0);
257
                f--;
258
                assert(args[f] == name);
259
                strv_remove(args + f, name);
260
        }
261

262
        if (streq(verb, "is-enabled"))
263
                return enable_state;
264
#endif
265
        return r;
479✔
266
}
267

268
int action_to_runlevel(void) {
×
269
#if HAVE_SYSV_COMPAT
270
        static const char table[_ACTION_MAX] = {
271
                [ACTION_HALT] =      '0',
272
                [ACTION_POWEROFF] =  '0',
273
                [ACTION_REBOOT] =    '6',
274
                [ACTION_RUNLEVEL2] = '2',
275
                [ACTION_RUNLEVEL3] = '3',
276
                [ACTION_RUNLEVEL4] = '4',
277
                [ACTION_RUNLEVEL5] = '5',
278
                [ACTION_RESCUE] =    '1'
279
        };
280

281
        assert(arg_action >= 0 && arg_action < _ACTION_MAX);
282
        return table[arg_action];
283
#else
284
        return -EOPNOTSUPP;
×
285
#endif
286
}
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