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

systemd / systemd / 17364093579

31 Aug 2025 06:05PM UTC coverage: 72.187% (-0.03%) from 72.216%
17364093579

push

github

yuwata
po: Translated using Weblate (Russian)

Currently translated at 99.2% (262 of 264 strings)

Co-authored-by: Sergey A <Ser82-png@yandex.ru>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/ru/
Translation: systemd/main

302323 of 418806 relevant lines covered (72.19%)

639709.41 hits per line

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

55.61
/src/systemctl/systemctl-logind.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <unistd.h>
4

5
#include "sd-bus.h"
6
#include "sd-login.h"
7

8
#include "bus-error.h"
9
#include "bus-locator.h"
10
#include "bus-util.h"
11
#include "env-util.h"
12
#include "errno-util.h"
13
#include "format-util.h"
14
#include "log.h"
15
#include "login-util.h"
16
#include "mountpoint-util.h"
17
#include "process-util.h"
18
#include "runtime-scope.h"
19
#include "string-util.h"
20
#include "strv.h"
21
#include "systemctl.h"
22
#include "systemctl-logind.h"
23
#include "systemctl-start-unit.h"
24
#include "systemctl-util.h"
25
#include "terminal-util.h"
26
#include "time-util.h"
27
#include "user-util.h"
28

29
static int logind_set_wall_message(sd_bus *bus) {
39✔
30
#if ENABLE_LOGIND
31
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
32
        _cleanup_free_ char *m = NULL;
39✔
33
        int r;
39✔
34

35
        assert(bus);
39✔
36

37
        m = strv_join(arg_wall, " ");
39✔
38
        if (!m)
39✔
39
                return log_oom();
×
40

41
        log_debug("%s wall message \"%s\".", arg_dry_run ? "Would set" : "Setting", m);
45✔
42
        if (arg_dry_run)
39✔
43
                return 0;
44

45
        r = bus_call_method(bus, bus_login_mgr, "SetWallMessage", &error, NULL, "sb", m, !arg_no_wall);
26✔
46
        if (r < 0)
26✔
47
                return log_warning_errno(r, "Failed to set wall message, ignoring: %s", bus_error_message(&error, r));
×
48
#endif
49
        return 0;
50
}
51

52
/* Ask systemd-logind, which might grant access to unprivileged users through polkit */
53
int logind_reboot(enum action a) {
33✔
54
#if ENABLE_LOGIND
55
        static const char* actions[_ACTION_MAX] = {
33✔
56
                [ACTION_POWEROFF]               = "PowerOff",
57
                [ACTION_REBOOT]                 = "Reboot",
58
                [ACTION_KEXEC]                  = "Reboot",
59
                [ACTION_SOFT_REBOOT]            = "Reboot",
60
                [ACTION_HALT]                   = "Halt",
61
                [ACTION_SUSPEND]                = "Suspend",
62
                [ACTION_HIBERNATE]              = "Hibernate",
63
                [ACTION_HYBRID_SLEEP]           = "HybridSleep",
64
                [ACTION_SUSPEND_THEN_HIBERNATE] = "SuspendThenHibernate",
65
                [ACTION_SLEEP]                  = "Sleep",
66
        };
67

68
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
33✔
69
        uint64_t flags = 0;
33✔
70
        sd_bus *bus;
33✔
71
        int r;
33✔
72

73
        assert(a >= 0);
33✔
74
        assert(a < _ACTION_MAX);
33✔
75

76
        if (!actions[a])
33✔
77
                return -EINVAL;
78

79
        r = acquire_bus_full(BUS_FULL, /* graceful = */ true, &bus);
33✔
80
        if (r < 0)
33✔
81
                return r;
82

83
        polkit_agent_open_maybe();
33✔
84
        (void) logind_set_wall_message(bus);
33✔
85

86
        const char *method_with_flags = a == ACTION_SLEEP ? actions[a] : strjoina(actions[a], "WithFlags");
165✔
87

88
        log_debug("%s org.freedesktop.login1.Manager %s dbus call.",
39✔
89
                  arg_dry_run ? "Would execute" : "Executing", method_with_flags);
90

91
        if (arg_dry_run)
33✔
92
                return 0;
93

94
        SET_FLAG(flags, SD_LOGIND_ROOT_CHECK_INHIBITORS, arg_check_inhibitors > 0);
20✔
95
        SET_FLAG(flags, SD_LOGIND_SKIP_INHIBITORS, arg_check_inhibitors == 0);
20✔
96
        SET_FLAG(flags,
20✔
97
                 SD_LOGIND_REBOOT_VIA_KEXEC,
98
                 a == ACTION_KEXEC || (a == ACTION_REBOOT && getenv_bool("SYSTEMCTL_SKIP_AUTO_KEXEC") <= 0));
99
        /* Try to soft-reboot if /run/nextroot/ is a valid OS tree, but only if it's also a mount point.
100
         * Otherwise, if people store new rootfs directly on /run/ tmpfs, 'systemctl reboot' would always
101
         * soft-reboot, as /run/nextroot/ can never go away. */
102
        SET_FLAG(flags,
25✔
103
                 SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP,
104
                 a == ACTION_REBOOT && getenv_bool("SYSTEMCTL_SKIP_AUTO_SOFT_REBOOT") <= 0 && path_is_mount_point("/run/nextroot") > 0);
105
        SET_FLAG(flags, SD_LOGIND_SOFT_REBOOT, a == ACTION_SOFT_REBOOT);
20✔
106

107
        r = bus_call_method(bus, bus_login_mgr, method_with_flags, &error, NULL, "t", flags);
20✔
108
        if (r < 0 && FLAGS_SET(flags, SD_LOGIND_SKIP_INHIBITORS) &&
20✔
109
                        sd_bus_error_has_name(&error, SD_BUS_ERROR_INVALID_ARGS)) {
×
110
                sd_bus_error_free(&error);
×
111
                flags &= ~SD_LOGIND_SKIP_INHIBITORS;
×
112
                r = bus_call_method(bus, bus_login_mgr, method_with_flags, &error, NULL, "t", flags);
×
113
        }
114
        if (r < 0 && FLAGS_SET(flags, SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP) &&
×
115
                        sd_bus_error_has_name(&error, SD_BUS_ERROR_INVALID_ARGS)) {
×
116
                sd_bus_error_free(&error);
×
117
                flags &= ~SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP;
×
118
                r = bus_call_method(bus, bus_login_mgr, method_with_flags, &error, NULL, "t", flags);
×
119
        }
120
        if (r >= 0)
×
121
                return 0;
20✔
122
        if (geteuid() == 0 && sd_bus_error_has_name(&error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED))
×
123
                return log_error_errno(r,
×
124
                                       "The current polkit policy does not allow root to ignore inhibitors without authentication in order to %s.\n"
125
                                       "To allow this action, a new polkit rule is needed.\n"
126
                                       "See " POLKIT_RULES_DIR "/10-systemd-logind-root-ignore-inhibitors.rules.example.",
127
                                       action_table[a].verb);
128
        if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD) || a == ACTION_SLEEP)
×
129
                return log_error_errno(r, "Call to %s failed: %s", actions[a], bus_error_message(&error, r));
×
130

131
        /* Fall back to original methods in case there is an older version of systemd-logind */
132
        log_debug("Method %s not available: %s. Falling back to %s", method_with_flags, bus_error_message(&error, r), actions[a]);
×
133
        sd_bus_error_free(&error);
×
134

135
        r = bus_call_method(bus, bus_login_mgr, actions[a], &error, NULL, "b", arg_ask_password);
×
136
        if (r < 0)
×
137
                return log_error_errno(r, "Call to %s failed: %s", actions[a], bus_error_message(&error, r));
×
138

139
        return 0;
140
#else
141
        return -ENOSYS;
142
#endif
143
}
144

145
int logind_check_inhibitors(enum action a) {
43✔
146
#if ENABLE_LOGIND
147
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
43✔
148
        _cleanup_strv_free_ char **sessions = NULL;
43✔
149
        const char *what, *who, *why, *mode;
43✔
150
        uint32_t uid, pid;
43✔
151
        sd_bus *bus;
43✔
152
        unsigned c = 0;
43✔
153
        int r;
43✔
154

155
        assert(a >= 0);
43✔
156
        assert(a < _ACTION_MAX);
43✔
157

158
        if (arg_check_inhibitors == 0 || arg_force > 0)
43✔
159
                return 0;
160

161
        if (arg_when > 0)
37✔
162
                return 0;
163

164
        if (arg_check_inhibitors < 0 && !on_tty())
37✔
165
                return 0;
166

167
        if (arg_transport != BUS_TRANSPORT_LOCAL)
1✔
168
                return 0;
169

170
        r = acquire_bus_full(BUS_FULL, /* graceful = */ true, &bus);
1✔
171
        if ((ERRNO_IS_NEG_DISCONNECT(r) || r == -ENOENT) && geteuid() == 0)
1✔
172
                return 0; /* When D-Bus is not running (ECONNREFUSED) or D-Bus socket is not created (ENOENT),
173
                           * allow root to force a shutdown. E.g. when running at the emergency console. */
174
        if (r < 0)
1✔
175
                return r;
176

177
        r = bus_call_method(bus, bus_login_mgr, "ListInhibitors", NULL, &reply, NULL);
1✔
178
        if (r < 0)
1✔
179
                /* If logind is not around, then there are no inhibitors... */
180
                return 0;
181

182
        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
1✔
183
        if (r < 0)
1✔
184
                return bus_log_parse_error(r);
×
185

186
        while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2✔
187
                _cleanup_free_ char *comm = NULL, *user = NULL;
1✔
188
                _cleanup_strv_free_ char **sv = NULL;
1✔
189

190
                if (!STR_IN_SET(mode, "block", "block-weak"))
1✔
191
                        continue;
1✔
192

193
                if (streq(mode, "block-weak") && (geteuid() == 0 || geteuid() == uid || !on_tty()))
×
194
                        continue;
×
195

196
                sv = strv_split(what, ":");
×
197
                if (!sv)
×
198
                        return log_oom();
×
199

200
                if (!pid_is_valid((pid_t) pid))
×
201
                        return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Invalid PID "PID_FMT".", (pid_t) pid);
×
202

203
                if (!strv_contains(sv,
×
204
                                   IN_SET(a,
205
                                          ACTION_HALT,
206
                                          ACTION_POWEROFF,
207
                                          ACTION_REBOOT,
208
                                          ACTION_KEXEC) ? "shutdown" : "sleep"))
209
                        continue;
×
210

211
                (void) pid_get_comm(pid, &comm);
×
212
                user = uid_to_name(uid);
×
213

214
                log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
×
215
                            who, (pid_t) pid, strna(comm), strna(user), why);
216

217
                c++;
×
218
        }
219
        if (r < 0)
1✔
220
                return bus_log_parse_error(r);
×
221

222
        r = sd_bus_message_exit_container(reply);
1✔
223
        if (r < 0)
1✔
224
                return bus_log_parse_error(r);
×
225

226
        /* root respects inhibitors since v257 but keeps ignoring sessions by default */
227
        if (arg_check_inhibitors < 0 && c == 0 && geteuid() == 0)
1✔
228
                return 0;
229

230
        /* Check for current sessions */
231
        sd_get_sessions(&sessions);
1✔
232
        STRV_FOREACH(s, sessions) {
2✔
233
                _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
1✔
234

235
                if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
1✔
236
                        continue;
×
237

238
                if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
1✔
239
                        continue;
1✔
240

241
                if (sd_session_get_type(*s, &type) < 0 || !STR_IN_SET(type, "x11", "wayland", "tty", "mir"))
×
242
                        continue;
×
243

244
                sd_session_get_tty(*s, &tty);
×
245
                sd_session_get_seat(*s, &seat);
×
246
                sd_session_get_service(*s, &service);
×
247
                user = uid_to_name(uid);
×
248

249
                log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
×
250
                c++;
×
251
        }
252

253
        if (c <= 0)
1✔
254
                return 0;
255

256
        return log_error_errno(SYNTHETIC_ERRNO(EPERM),
×
257
                               "Please retry operation after closing inhibitors and logging out other users.\n"
258
                               "'systemd-inhibit' can be used to list active inhibitors.\n"
259
                               "Alternatively, ignore inhibitors and users with 'systemctl %s -i'.",
260
                               action_table[a].verb);
261
#else
262
        return 0;
263
#endif
264
}
265

266
int prepare_firmware_setup(void) {
29✔
267

268
        if (!arg_firmware_setup)
29✔
269
                return 0;
29✔
270

271
#if ENABLE_LOGIND
272
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
273
        sd_bus *bus;
×
274
        int r;
×
275

276
        r = acquire_bus(BUS_FULL, &bus);
×
277
        if (r < 0)
×
278
                return r;
279

280
        r = bus_call_method(bus, bus_login_mgr, "SetRebootToFirmwareSetup", &error, NULL, "b", true);
×
281
        if (r < 0)
×
282
                return log_error_errno(r, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error, r));
×
283

284
        return 0;
285
#else
286
        return log_error_errno(SYNTHETIC_ERRNO(ENOSYS),
287
                               "Booting into firmware setup not supported.");
288
#endif
289
}
290

291
int prepare_boot_loader_menu(void) {
29✔
292

293
        if (arg_boot_loader_menu == USEC_INFINITY)
29✔
294
                return 0;
29✔
295

296
#if ENABLE_LOGIND
297
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
298
        sd_bus *bus;
×
299
        int r;
×
300

301
        r = acquire_bus(BUS_FULL, &bus);
×
302
        if (r < 0)
×
303
                return r;
304

305
        r = bus_call_method(bus, bus_login_mgr, "SetRebootToBootLoaderMenu", &error, NULL, "t", arg_boot_loader_menu);
×
306
        if (r < 0)
×
307
                return log_error_errno(r, "Cannot indicate to boot loader to enter boot loader entry menu: %s", bus_error_message(&error, r));
×
308

309
        return 0;
310
#else
311
        return log_error_errno(SYNTHETIC_ERRNO(ENOSYS),
312
                               "Booting into boot loader menu not supported.");
313
#endif
314
}
315

316
int prepare_boot_loader_entry(void) {
29✔
317

318
        if (!arg_boot_loader_entry)
29✔
319
                return 0;
29✔
320

321
#if ENABLE_LOGIND
322
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
323
        sd_bus *bus;
×
324
        int r;
×
325

326
        r = acquire_bus(BUS_FULL, &bus);
×
327
        if (r < 0)
×
328
                return r;
329

330
        r = bus_call_method(bus, bus_login_mgr, "SetRebootToBootLoaderEntry", &error, NULL, "s", arg_boot_loader_entry);
×
331
        if (r < 0)
×
332
                return log_error_errno(r, "Cannot set boot into loader entry '%s': %s", arg_boot_loader_entry, bus_error_message(&error, r));
×
333

334
        return 0;
335
#else
336
        return log_error_errno(SYNTHETIC_ERRNO(ENOSYS),
337
                               "Booting into boot loader entry not supported.");
338
#endif
339
}
340

341
int logind_schedule_shutdown(enum action a) {
3✔
342
#if ENABLE_LOGIND
343
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3✔
344
        const char *action;
3✔
345
        sd_bus *bus;
3✔
346
        int r;
3✔
347

348
        assert(a >= 0);
3✔
349
        assert(a < _ACTION_MAX);
3✔
350

351
        r = acquire_bus(BUS_FULL, &bus);
3✔
352
        if (r < 0)
3✔
353
                return r;
354

355
        action = action_table[a].verb;
3✔
356
        if (!action)
3✔
357
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Scheduling not supported for this action.");
×
358

359
        if (arg_dry_run)
3✔
360
                action = strjoina("dry-", action);
×
361

362
        (void) logind_set_wall_message(bus);
3✔
363

364
        r = bus_call_method(bus, bus_login_mgr, "ScheduleShutdown", &error, NULL, "st", action, arg_when);
3✔
365
        if (r < 0)
3✔
366
                return log_warning_errno(r, "Failed to schedule shutdown: %s", bus_error_message(&error, r));
×
367

368
        if (!arg_quiet)
3✔
369
                logind_show_shutdown();
3✔
370

371
        return 0;
372
#else
373
        return log_error_errno(SYNTHETIC_ERRNO(ENOSYS),
374
                               "Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
375
#endif
376
}
377

378
int logind_cancel_shutdown(void) {
3✔
379
#if ENABLE_LOGIND
380
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
3✔
381
        sd_bus *bus;
3✔
382
        int r;
3✔
383

384
        r = acquire_bus(BUS_FULL, &bus);
3✔
385
        if (r < 0)
3✔
386
                return r;
387

388
        (void) logind_set_wall_message(bus);
3✔
389

390
        r = bus_call_method(bus, bus_login_mgr, "CancelScheduledShutdown", &error, NULL, NULL);
3✔
391
        if (r < 0)
3✔
392
                return log_warning_errno(r, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error, r));
×
393

394
        return 0;
395
#else
396
        return log_error_errno(SYNTHETIC_ERRNO(ENOSYS),
397
                               "Not compiled with logind support, cannot cancel scheduled shutdowns.");
398
#endif
399
}
400

401
int logind_show_shutdown(void) {
4✔
402
#if ENABLE_LOGIND
403
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
404
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
4✔
405
        sd_bus *bus;
4✔
406
        const char *action, *pretty_action;
4✔
407
        uint64_t elapse;
4✔
408
        int r;
4✔
409

410
        r = acquire_bus(BUS_FULL, &bus);
4✔
411
        if (r < 0)
4✔
412
                return r;
413

414
        r = bus_get_property(bus, bus_login_mgr, "ScheduledShutdown", &error, &reply, "(st)");
4✔
415
        if (r < 0)
4✔
416
                return log_error_errno(r, "Failed to query scheduled shutdown: %s", bus_error_message(&error, r));
×
417

418
        r = sd_bus_message_read(reply, "(st)", &action, &elapse);
4✔
419
        if (r < 0)
4✔
420
                return r;
421

422
        if (isempty(action))
4✔
423
                return log_full_errno(arg_quiet ? LOG_DEBUG : LOG_ERR, SYNTHETIC_ERRNO(ENODATA), "No scheduled shutdown.");
×
424

425
        if (STR_IN_SET(action, "halt", "poweroff", "exit"))
4✔
426
                pretty_action = "Shutdown";
427
        else if (streq(action, "kexec"))
2✔
428
                pretty_action = "Reboot via kexec";
429
        else if (streq(action, "reboot"))
2✔
430
                pretty_action = "Reboot";
431
        else /* If we don't recognize the action string, we'll show it as-is */
432
                pretty_action = action;
×
433

434
        if (IN_SET(arg_action, ACTION_SYSTEMCTL, ACTION_SYSTEMCTL_SHOW_SHUTDOWN))
4✔
435
                log_info("%s scheduled for %s, use 'systemctl %s --when=cancel' to cancel.",
×
436
                         pretty_action,
437
                         FORMAT_TIMESTAMP_STYLE(elapse, arg_timestamp_style),
438
                         action);
439
        else
440
                log_info("%s scheduled for %s, use 'shutdown -c' to cancel.",
4✔
441
                         pretty_action,
442
                         FORMAT_TIMESTAMP_STYLE(elapse, arg_timestamp_style));
443

444
        return 0;
445
#else
446
        return log_error_errno(SYNTHETIC_ERRNO(ENOSYS),
447
                               "Not compiled with logind support, cannot show scheduled shutdowns.");
448
#endif
449
}
450

451
int help_boot_loader_entry(void) {
×
452
#if ENABLE_LOGIND
453
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
454
        _cleanup_strv_free_ char **l = NULL;
×
455
        sd_bus *bus;
×
456
        int r;
×
457

458
        /* This is called without checking runtime scope and bus transport like we do in parse_argv().
459
         * Loading boot entries is only supported by system scope. Let's gracefully adjust them. */
460
        arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
×
461
        if (arg_transport == BUS_TRANSPORT_CAPSULE) {
×
462
                arg_host = NULL;
×
463
                arg_transport = BUS_TRANSPORT_LOCAL;
×
464
        }
465

466
        r = acquire_bus(BUS_FULL, &bus);
×
467
        if (r < 0)
×
468
                return r;
469

470
        r = bus_get_property_strv(bus, bus_login_mgr, "BootLoaderEntries", &error, &l);
×
471
        if (r < 0)
×
472
                return log_error_errno(r, "Failed to enumerate boot loader entries: %s", bus_error_message(&error, r));
×
473

474
        if (strv_isempty(l))
×
475
                return log_error_errno(SYNTHETIC_ERRNO(ENODATA), "No boot loader entries discovered.");
×
476

477
        STRV_FOREACH(i, l)
×
478
                puts(*i);
×
479

480
        return 0;
481
#else
482
        return log_error_errno(SYNTHETIC_ERRNO(ENOSYS),
483
                               "Not compiled with logind support, cannot display boot loader entries.");
484
#endif
485
}
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