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

systemd / systemd / 15057632786

15 May 2025 09:01PM UTC coverage: 72.267% (+0.02%) from 72.244%
15057632786

push

github

bluca
man: document how to hook stuff into system wakeup

Fixes: #6364

298523 of 413084 relevant lines covered (72.27%)

738132.88 hits per line

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

71.66
/src/core/mount.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <errno.h>
4
#include <signal.h>
5
#include <stdio.h>
6
#include <sys/epoll.h>
7

8
#include "sd-messages.h"
9

10
#include "alloc-util.h"
11
#include "chase.h"
12
#include "dbus-mount.h"
13
#include "dbus-unit.h"
14
#include "device.h"
15
#include "exec-credential.h"
16
#include "exit-status.h"
17
#include "fd-util.h"
18
#include "format-util.h"
19
#include "fs-util.h"
20
#include "fstab-util.h"
21
#include "initrd-util.h"
22
#include "libmount-util.h"
23
#include "log.h"
24
#include "manager.h"
25
#include "mkdir-label.h"
26
#include "mount.h"
27
#include "mount-setup.h"
28
#include "mountpoint-util.h"
29
#include "parse-util.h"
30
#include "path-util.h"
31
#include "process-util.h"
32
#include "serialize.h"
33
#include "special.h"
34
#include "stat-util.h"
35
#include "string-table.h"
36
#include "string-util.h"
37
#include "strv.h"
38
#include "unit.h"
39
#include "unit-name.h"
40
#include "utf8.h"
41

42
#define RETRY_UMOUNT_MAX 32
43

44
static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
45
        [MOUNT_DEAD]               = UNIT_INACTIVE,
46
        [MOUNT_MOUNTING]           = UNIT_ACTIVATING,
47
        [MOUNT_MOUNTING_DONE]      = UNIT_ACTIVATING,
48
        [MOUNT_MOUNTED]            = UNIT_ACTIVE,
49
        [MOUNT_REMOUNTING]         = UNIT_RELOADING,
50
        [MOUNT_REMOUNTING_SIGTERM] = UNIT_RELOADING,
51
        [MOUNT_REMOUNTING_SIGKILL] = UNIT_RELOADING,
52
        [MOUNT_UNMOUNTING]         = UNIT_DEACTIVATING,
53
        [MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING,
54
        [MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING,
55
        [MOUNT_FAILED]             = UNIT_FAILED,
56
        [MOUNT_CLEANING]           = UNIT_MAINTENANCE,
57
};
58

59
static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
60
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
61
static void mount_enter_dead(Mount *m, MountResult f, bool flush_result);
62
static void mount_enter_mounted(Mount *m, MountResult f);
63
static void mount_cycle_clear(Mount *m);
64
static int mount_process_proc_self_mountinfo(Manager *m);
65

66
static bool MOUNT_STATE_WITH_PROCESS(MountState state) {
8,545✔
67
        return IN_SET(state,
8,545✔
68
                      MOUNT_MOUNTING,
69
                      MOUNT_MOUNTING_DONE,
70
                      MOUNT_REMOUNTING,
71
                      MOUNT_REMOUNTING_SIGTERM,
72
                      MOUNT_REMOUNTING_SIGKILL,
73
                      MOUNT_UNMOUNTING,
74
                      MOUNT_UNMOUNTING_SIGTERM,
75
                      MOUNT_UNMOUNTING_SIGKILL,
76
                      MOUNT_CLEANING);
77
}
78

79
static MountParameters* get_mount_parameters_fragment(Mount *m) {
20,696✔
80
        assert(m);
20,696✔
81

82
        if (m->from_fragment)
20,696✔
83
                return &m->parameters_fragment;
4,598✔
84

85
        return NULL;
86
}
87

88
static MountParameters* get_mount_parameters(Mount *m) {
13,369✔
89
        assert(m);
13,369✔
90

91
        if (m->from_proc_self_mountinfo)
13,369✔
92
                return &m->parameters_proc_self_mountinfo;
9,573✔
93

94
        return get_mount_parameters_fragment(m);
3,796✔
95
}
96

97
static bool mount_is_network(const MountParameters *p) {
900✔
98
        assert(p);
900✔
99

100
        if (fstab_test_option(p->options, "_netdev\0"))
900✔
101
                return true;
102

103
        if (p->fstype && fstype_is_network(p->fstype))
900✔
104
                return true;
×
105

106
        return false;
107
}
108

109
static bool mount_is_nofail(const Mount *m) {
432✔
110
        assert(m);
432✔
111

112
        if (!m->from_fragment)
432✔
113
                return false;
114

115
        return fstab_test_yes_no_option(m->parameters_fragment.options, "nofail\0" "fail\0");
229✔
116
}
117

118
static bool mount_is_loop(const MountParameters *p) {
173✔
119
        assert(p);
173✔
120

121
        if (fstab_test_option(p->options, "loop\0"))
173✔
122
                return true;
119✔
123

124
        return false;
125
}
126

127
static bool mount_is_bind(const MountParameters *p) {
7,941✔
128
        assert(p);
7,941✔
129
        return fstab_is_bind(p->options, p->fstype);
7,941✔
130
}
131

132
static int mount_is_bound_to_device(Mount *m) {
492✔
133
        _cleanup_free_ char *value = NULL;
492✔
134
        const MountParameters *p;
492✔
135
        int r;
492✔
136

137
        assert(m);
492✔
138

139
        /* Determines whether to place a Requires= or BindsTo= dependency on the backing device unit. We do
140
         * this by checking for the x-systemd.device-bound= mount option. If it is enabled we use BindsTo=,
141
         * otherwise Requires=. But note that we might combine the latter with StopPropagatedFrom=, see
142
         * below. */
143

144
        p = get_mount_parameters(m);
492✔
145
        if (!p)
492✔
146
                return false;
147

148
        r = fstab_filter_options(p->options, "x-systemd.device-bound\0", NULL, &value, NULL, NULL);
492✔
149
        if (r < 0)
492✔
150
                return r;
151
        if (r == 0)
492✔
152
                return -EIDRM; /* If unspecified at all, return recognizable error */
153

154
        if (isempty(value))
492✔
155
                return true;
156

157
        return parse_boolean(value);
×
158
}
159

160
static bool mount_propagate_stop(Mount *m) {
246✔
161
        int r;
246✔
162

163
        assert(m);
246✔
164

165
        r = mount_is_bound_to_device(m);
246✔
166
        if (r >= 0)
246✔
167
                /* If x-systemd.device-bound=no is explicitly requested by user, don't try to set StopPropagatedFrom=.
168
                 * Also don't bother if true, since with BindsTo= the stop propagation is implicit. */
169
                return false;
170
        if (r != -EIDRM)
246✔
171
                log_debug_errno(r, "Failed to get x-systemd.device-bound= option, ignoring: %m");
×
172

173
        return m->from_fragment; /* let's propagate stop whenever this is an explicitly configured unit,
246✔
174
                                  * otherwise let's not bother. */
175
}
176

177
static void mount_init(Unit *u) {
27,789✔
178
        Mount *m = ASSERT_PTR(MOUNT(u));
27,789✔
179

180
        assert(u->load_state == UNIT_STUB);
27,789✔
181

182
        m->timeout_usec = u->manager->defaults.timeout_start_usec;
27,789✔
183

184
        m->exec_context.std_output = u->manager->defaults.std_output;
27,789✔
185
        m->exec_context.std_error = u->manager->defaults.std_error;
27,789✔
186

187
        m->directory_mode = 0755;
27,789✔
188

189
        /* We need to make sure that /usr/bin/mount is always called
190
         * in the same process group as us, so that the autofs kernel
191
         * side doesn't send us another mount request while we are
192
         * already trying to comply its last one. */
193
        m->exec_context.same_pgrp = true;
27,789✔
194

195
        m->control_pid = PIDREF_NULL;
27,789✔
196
        m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
27,789✔
197

198
        u->ignore_on_isolate = true;
27,789✔
199
}
27,789✔
200

201
static int mount_arm_timer(Mount *m, bool relative, usec_t usec) {
180✔
202
        assert(m);
180✔
203

204
        return unit_arm_timer(UNIT(m), &m->timer_event_source, relative, usec, mount_dispatch_timer);
180✔
205
}
206

207
static void mount_unwatch_control_pid(Mount *m) {
36,186✔
208
        assert(m);
36,186✔
209
        unit_unwatch_pidref_done(UNIT(m), &m->control_pid);
36,186✔
210
}
36,186✔
211

212
static void mount_parameters_done(MountParameters *p) {
55,578✔
213
        assert(p);
55,578✔
214

215
        p->what = mfree(p->what);
55,578✔
216
        p->options = mfree(p->options);
55,578✔
217
        p->fstype = mfree(p->fstype);
55,578✔
218
}
55,578✔
219

220
static void mount_done(Unit *u) {
27,789✔
221
        Mount *m = ASSERT_PTR(MOUNT(u));
27,789✔
222

223
        m->where = mfree(m->where);
27,789✔
224

225
        mount_parameters_done(&m->parameters_proc_self_mountinfo);
27,789✔
226
        mount_parameters_done(&m->parameters_fragment);
27,789✔
227

228
        m->exec_runtime = exec_runtime_free(m->exec_runtime);
27,789✔
229

230
        exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
27,789✔
231
        m->control_command = NULL;
27,789✔
232

233
        mount_unwatch_control_pid(m);
27,789✔
234

235
        m->timer_event_source = sd_event_source_disable_unref(m->timer_event_source);
27,789✔
236
}
27,789✔
237

238
static int update_parameters_proc_self_mountinfo(
80,650✔
239
                Mount *m,
240
                const char *what,
241
                const char *options,
242
                const char *fstype) {
243

244
        MountParameters *p;
80,650✔
245
        int r, q, w;
80,650✔
246

247
        assert(m);
80,650✔
248

249
        p = &m->parameters_proc_self_mountinfo;
80,650✔
250

251
        r = free_and_strdup(&p->what, what);
80,650✔
252
        if (r < 0)
80,650✔
253
                return r;
254

255
        q = free_and_strdup(&p->options, options);
80,650✔
256
        if (q < 0)
80,650✔
257
                return q;
258

259
        w = free_and_strdup(&p->fstype, fstype);
80,650✔
260
        if (w < 0)
80,650✔
261
                return w;
262

263
        return r > 0 || q > 0 || w > 0;
80,650✔
264
}
265

266
static int mount_add_mount_dependencies(Mount *m) {
9,229✔
267
        MountParameters *pm;
9,229✔
268
        int r;
9,229✔
269

270
        assert(m);
9,229✔
271

272
        if (!path_equal(m->where, "/")) {
9,229✔
273
                _cleanup_free_ char *parent = NULL;
8,815✔
274

275
                /* Adds in links to other mount points that might lie further up in the hierarchy */
276

277
                r = path_extract_directory(m->where, &parent);
8,815✔
278
                if (r < 0)
8,815✔
279
                        return r;
280

281
                r = unit_add_mounts_for(UNIT(m), parent, UNIT_DEPENDENCY_IMPLICIT, UNIT_MOUNT_REQUIRES);
8,815✔
282
                if (r < 0)
8,815✔
283
                        return r;
284
        }
285

286
        /* Adds in dependencies to other mount points that might be needed for the source path (if this is a bind mount
287
         * or a loop mount) to be available. */
288
        pm = get_mount_parameters_fragment(m);
9,229✔
289
        if (pm && pm->what &&
9,229✔
290
            path_is_absolute(pm->what) &&
1,418✔
291
            (mount_is_bind(pm) || mount_is_loop(pm) || !mount_is_network(pm))) {
346✔
292

293
                r = unit_add_mounts_for(UNIT(m), pm->what, UNIT_DEPENDENCY_FILE, UNIT_MOUNT_REQUIRES);
173✔
294
                if (r < 0)
173✔
295
                        return r;
296
        }
297

298
        /* Adds in dependencies to other units that use this path or paths further down in the hierarchy */
299
        for (UnitMountDependencyType t = 0; t < _UNIT_MOUNT_DEPENDENCY_TYPE_MAX; ++t) {
27,687✔
300
                Unit *other;
18,458✔
301
                Set *s = manager_get_units_needing_mounts_for(UNIT(m)->manager, m->where, t);
18,458✔
302

303
                SET_FOREACH(other, s) {
33,022✔
304
                        if (other->load_state != UNIT_LOADED)
14,564✔
305
                                continue;
×
306

307
                        if (other == UNIT(m))
14,564✔
308
                                continue;
202✔
309

310
                        r = unit_add_dependency(
28,724✔
311
                                        other,
312
                                        UNIT_AFTER,
313
                                        UNIT(m),
14,362✔
314
                                        /* add_reference= */ true,
315
                                        UNIT_DEPENDENCY_PATH);
316
                        if (r < 0)
14,362✔
317
                                return r;
×
318

319
                        if (UNIT(m)->fragment_path) {
14,362✔
320
                                /* If we have fragment configuration, then make this dependency required/wanted */
321
                                r = unit_add_dependency(
745✔
322
                                                other,
323
                                                unit_mount_dependency_type_to_dependency_type(t),
324
                                                UNIT(m),
745✔
325
                                                /* add_reference= */ true,
326
                                                UNIT_DEPENDENCY_PATH);
327
                                if (r < 0)
745✔
328
                                        return r;
329
                        }
330
                }
331
        }
332

333
        return 0;
334
}
335

336
static int mount_add_device_dependencies(Mount *m) {
9,229✔
337
        UnitDependencyMask mask;
9,229✔
338
        MountParameters *p;
9,229✔
339
        UnitDependency dep;
9,229✔
340
        int r;
9,229✔
341

342
        assert(m);
9,229✔
343

344
        log_unit_trace(UNIT(m), "Processing implicit device dependencies");
9,229✔
345

346
        p = get_mount_parameters(m);
9,229✔
347
        if (!p) {
9,229✔
348
                log_unit_trace(UNIT(m), "Missing mount parameters, skipping implicit device dependencies");
349
                return 0;
350
        }
351

352
        if (!p->what) {
7,500✔
353
                log_unit_trace(UNIT(m), "Missing mount source, skipping implicit device dependencies");
354
                return 0;
355
        }
356

357
        if (mount_is_bind(p)) {
7,500✔
358
                log_unit_trace(UNIT(m), "Mount unit is a bind mount, skipping implicit device dependencies");
359
                return 0;
360
        }
361

362
        if (!is_device_path(p->what)) {
7,500✔
363
                log_unit_trace(UNIT(m), "Mount source is not a device path, skipping implicit device dependencies");
364
                return 0;
365
        }
366

367
        /* /dev/root is a really weird thing, it's not a real device, but just a path the kernel exports for
368
         * the root file system specified on the kernel command line. Ignore it here. */
369
        if (PATH_IN_SET(p->what, "/dev/root", "/dev/nfs")) {
350✔
370
                log_unit_trace(UNIT(m), "Mount source is in /dev/root or /dev/nfs, skipping implicit device dependencies");
×
371
                return 0;
×
372
        }
373

374
        if (path_equal(m->where, "/")) {
350✔
375
                log_unit_trace(UNIT(m), "Mount destination is '/', skipping implicit device dependencies");
376
                return 0;
377
        }
378

379
        /* Mount units from /proc/self/mountinfo are not bound to devices by default since they're subject to
380
         * races when mounts are established by other tools with different backing devices than what we
381
         * maintain. The user can still force this to be a BindsTo= dependency with an appropriate option (or
382
         * udev property) so the mount units are automatically stopped when the device disappears
383
         * suddenly. */
384
        dep = mount_is_bound_to_device(m) > 0 ? UNIT_BINDS_TO : UNIT_REQUIRES;
246✔
385

386
        /* We always use 'what' from /proc/self/mountinfo if mounted */
387
        mask = m->from_proc_self_mountinfo ? UNIT_DEPENDENCY_MOUNTINFO : UNIT_DEPENDENCY_MOUNT_FILE;
246✔
388

389
        r = unit_add_node_dependency(UNIT(m), p->what, dep, mask);
246✔
390
        if (r < 0)
246✔
391
                return r;
392
        if (r > 0)
246✔
393
                log_unit_trace(UNIT(m), "Added %s dependency on %s", unit_dependency_to_string(dep), p->what);
246✔
394

395
        if (mount_propagate_stop(m)) {
246✔
396
                r = unit_add_node_dependency(UNIT(m), p->what, UNIT_STOP_PROPAGATED_FROM, mask);
51✔
397
                if (r < 0)
51✔
398
                        return r;
399
                if (r > 0)
400
                        log_unit_trace(UNIT(m), "Added %s dependency on %s",
246✔
401
                                       unit_dependency_to_string(UNIT_STOP_PROPAGATED_FROM), p->what);
402
        }
403

404
        r = unit_add_blockdev_dependency(UNIT(m), p->what, mask);
246✔
405
        if (r > 0)
246✔
406
                log_unit_trace(UNIT(m), "Added %s dependency on %s", unit_dependency_to_string(UNIT_AFTER), p->what);
246✔
407

408
        return 0;
246✔
409
}
410

411
static bool mount_is_extrinsic(Unit *u) {
14,804✔
412
        Mount *m = ASSERT_PTR(MOUNT(u));
14,804✔
413
        MountParameters *p;
14,804✔
414

415
        /* Returns true for all units that are "magic" and should be excluded from the usual
416
         * start-up and shutdown dependencies. We call them "extrinsic" here, as they are generally
417
         * mounted outside of the systemd dependency logic. We shouldn't attempt to manage them
418
         * ourselves but it's fine if the user operates on them with us. */
419

420
        /* We only automatically manage mounts if we are in system mode */
421
        if (MANAGER_IS_USER(u->manager))
14,804✔
422
                return true;
423

424
        p = get_mount_parameters(m);
3,035✔
425
        if (p && fstab_is_extrinsic(m->where, p->options))
3,035✔
426
                return true;
2,063✔
427

428
        return false;
429
}
430

431
static int mount_add_default_ordering_dependencies(Mount *m, MountParameters *p, UnitDependencyMask mask) {
432✔
432
        const char *after, *before, *e;
432✔
433
        int r;
432✔
434

435
        assert(m);
432✔
436

437
        e = path_startswith(m->where, "/sysroot");
432✔
438
        if (e && in_initrd()) {
432✔
439
                /* All mounts under /sysroot need to happen later, at initrd-fs.target time. IOW,
440
                 * it's not technically part of the basic initrd filesystem itself, and so
441
                 * shouldn't inherit the default Before=local-fs.target dependency. However,
442
                 * these mounts still need to start after local-fs-pre.target, as a sync point
443
                 * for things like systemd-hibernate-resume.service that should start before
444
                 * any mounts. */
445

446
                after = SPECIAL_LOCAL_FS_PRE_TARGET;
18✔
447
                before = isempty(e) ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_INITRD_FS_TARGET;
18✔
448

449
        } else if (in_initrd() && path_startswith(m->where, "/sysusr/usr")) {
414✔
450
                after = SPECIAL_LOCAL_FS_PRE_TARGET;
451
                before = SPECIAL_INITRD_USR_FS_TARGET;
452

453
        } else if (mount_is_network(p)) {
414✔
454
                after = SPECIAL_REMOTE_FS_PRE_TARGET;
455
                before = SPECIAL_REMOTE_FS_TARGET;
456

457
        } else {
458
                after = SPECIAL_LOCAL_FS_PRE_TARGET;
459
                before = SPECIAL_LOCAL_FS_TARGET;
460
        }
461

462
        if (before && !mount_is_nofail(m)) {
432✔
463
                r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, before, /* add_reference= */ true, mask);
425✔
464
                if (r < 0)
425✔
465
                        return r;
466
        }
467

468
        if (after) {
432✔
469
                r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, /* add_reference= */ true, mask);
432✔
470
                if (r < 0)
432✔
471
                        return r;
472
        }
473

474
        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET,
432✔
475
                                              /* add_reference= */ true, mask);
476
        if (r < 0)
432✔
477
                return r;
478

479
        /* If this is a tmpfs mount then we have to unmount it before we try to deactivate swaps */
480
        if (streq_ptr(p->fstype, "tmpfs")) {
432✔
481
                r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_SWAP_TARGET,
169✔
482
                                                /* add_reference= */ true, mask);
483
                if (r < 0)
169✔
484
                        return r;
×
485
        }
486

487
        return 0;
488
}
489

490
static int mount_add_default_network_dependencies(Mount *m, MountParameters *p, UnitDependencyMask mask) {
432✔
491
        int r;
432✔
492

493
        assert(m);
432✔
494

495
        if (!mount_is_network(p))
432✔
496
                return 0;
497

498
        /* We order ourselves after network.target. This is primarily useful at shutdown: services that take
499
         * down the network should order themselves before network.target, so that they are shut down only
500
         * after this mount unit is stopped. */
501

502
        r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET,
×
503
                                        /* add_reference= */ true, mask);
504
        if (r < 0)
×
505
                return r;
506

507
        /* We pull in network-online.target, and order ourselves after it. This is useful at start-up to
508
         * actively pull in tools that want to be started before we start mounting network file systems, and
509
         * whose purpose it is to delay this until the network is "up". */
510

511
        return unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET,
×
512
                                                 /* add_reference= */ true, mask);
513
}
514

515
static int mount_add_default_dependencies(Mount *m) {
9,229✔
516
        UnitDependencyMask mask;
9,229✔
517
        MountParameters *p;
9,229✔
518
        int r;
9,229✔
519

520
        assert(m);
9,229✔
521

522
        if (!UNIT(m)->default_dependencies)
9,229✔
523
                return 0;
524

525
        /* We do not add any default dependencies to /, /usr or /run/initramfs/, since they are
526
         * guaranteed to stay mounted the whole time, since our system is on it.  Also, don't
527
         * bother with anything mounted below virtual file systems, it's also going to be virtual,
528
         * and hence not worth the effort. */
529
        if (mount_is_extrinsic(UNIT(m)))
7,805✔
530
                return 0;
531

532
        p = get_mount_parameters(m);
481✔
533
        if (!p)
481✔
534
                return 0;
535

536
        mask = m->from_proc_self_mountinfo ? UNIT_DEPENDENCY_MOUNTINFO : UNIT_DEPENDENCY_MOUNT_FILE;
432✔
537

538
        r = mount_add_default_ordering_dependencies(m, p, mask);
432✔
539
        if (r < 0)
432✔
540
                return r;
541

542
        r = mount_add_default_network_dependencies(m, p, mask);
432✔
543
        if (r < 0)
432✔
544
                return r;
×
545

546
        return 0;
547
}
548

549
static int mount_verify(Mount *m) {
7,325✔
550
        _cleanup_free_ char *e = NULL;
7,325✔
551
        MountParameters *p;
7,325✔
552
        int r;
7,325✔
553

554
        assert(m);
7,325✔
555
        assert(UNIT(m)->load_state == UNIT_LOADED);
7,325✔
556

557
        if (!m->from_fragment && !m->from_proc_self_mountinfo && !UNIT(m)->perpetual)
7,325✔
558
                return -ENOENT;
559

560
        r = unit_name_from_path(m->where, ".mount", &e);
7,325✔
561
        if (r < 0)
7,325✔
562
                return log_unit_error_errno(UNIT(m), r, "Failed to generate unit name from mount path: %m");
×
563

564
        if (!unit_has_name(UNIT(m), e))
7,325✔
565
                return log_unit_error_errno(UNIT(m), SYNTHETIC_ERRNO(ENOEXEC), "Where= setting doesn't match unit name. Refusing.");
×
566

567
        if (mount_point_is_api(m->where) || mount_point_ignore(m->where))
7,325✔
568
                return log_unit_error_errno(UNIT(m), SYNTHETIC_ERRNO(ENOEXEC),
×
569
                                            "Cannot create mount unit for API file system '%s'. Refusing.", m->where);
570

571
        if (mount_point_is_credentials(UNIT(m)->manager->prefix[EXEC_DIRECTORY_RUNTIME], m->where))
7,325✔
572
                return log_unit_error_errno(UNIT(m), SYNTHETIC_ERRNO(ENOEXEC),
×
573
                                            "Cannot create mount unit for credential mount '%s'. Refusing.", m->where);
574

575
        p = get_mount_parameters_fragment(m);
7,325✔
576
        if (p && !p->what && !UNIT(m)->perpetual)
7,325✔
577
                return log_unit_error_errno(UNIT(m), SYNTHETIC_ERRNO(ENOEXEC), "What= setting is missing. Refusing.");
×
578

579
        return 0;
580
}
581

582
static int mount_add_non_exec_dependencies(Mount *m) {
9,229✔
583
        int r;
9,229✔
584

585
        assert(m);
9,229✔
586

587
        /* We may be called due to this mount appearing in /proc/self/mountinfo, hence we clear all existing
588
         * dependencies that were initialized from the unit file but whose final value really depends on the
589
         * content of /proc/self/mountinfo. Some (such as m->where) might have become stale now. */
590
        unit_remove_dependencies(UNIT(m), UNIT_DEPENDENCY_MOUNTINFO | UNIT_DEPENDENCY_MOUNT_FILE);
9,229✔
591

592
        if (!m->where)
9,229✔
593
                return 0;
594

595
        /* Adds in all dependencies directly responsible for ordering the mount, as opposed to dependencies
596
         * resulting from the ExecContext and such. */
597

598
        r = mount_add_device_dependencies(m);
9,229✔
599
        if (r < 0)
9,229✔
600
                return r;
601

602
        r = mount_add_mount_dependencies(m);
9,229✔
603
        if (r < 0)
9,229✔
604
                return r;
605

606
        r = mount_add_default_dependencies(m);
9,229✔
607
        if (r < 0)
9,229✔
608
                return r;
×
609

610
        return 0;
611
}
612

613
static int mount_add_extras(Mount *m) {
7,325✔
614
        Unit *u = UNIT(ASSERT_PTR(m));
7,325✔
615
        int r;
7,325✔
616

617
        /* Note: this call might be called after we already have been loaded once (and even when it has already been
618
         * activated), in case data from /proc/self/mountinfo has changed. This means all code here needs to be ready
619
         * to run with an already set up unit. */
620

621
        if (u->fragment_path)
7,325✔
622
                m->from_fragment = true;
1,087✔
623

624
        if (!m->where) {
7,325✔
625
                r = unit_name_to_path(u->id, &m->where);
140✔
626
                if (r == -ENAMETOOLONG)
140✔
627
                        log_unit_error_errno(u, r, "Failed to derive mount point path from unit name, because unit name is hashed. "
×
628
                                                   "Set \"Where=\" in the unit file explicitly.");
629
                if (r < 0)
140✔
630
                        return r;
631
        }
632

633
        path_simplify(m->where);
7,325✔
634

635
        if (!u->description) {
7,325✔
636
                r = unit_set_description(u, m->where);
5,876✔
637
                if (r < 0)
5,876✔
638
                        return r;
639
        }
640

641
        r = unit_patch_contexts(u);
7,325✔
642
        if (r < 0)
7,325✔
643
                return r;
644

645
        r = unit_add_exec_dependencies(u, &m->exec_context);
7,325✔
646
        if (r < 0)
7,325✔
647
                return r;
648

649
        r = unit_set_default_slice(u);
7,325✔
650
        if (r < 0)
7,325✔
651
                return r;
652

653
        r = mount_add_non_exec_dependencies(m);
7,325✔
654
        if (r < 0)
7,325✔
655
                return r;
×
656

657
        return 0;
658
}
659

660
static void mount_load_root_mount(Unit *u) {
27,789✔
661
        Mount *m = ASSERT_PTR(MOUNT(u));
27,789✔
662

663
        if (!unit_has_name(u, SPECIAL_ROOT_MOUNT))
27,789✔
664
                return;
665

666
        u->perpetual = true;
414✔
667
        u->default_dependencies = false;
414✔
668

669
        /* The stdio/kmsg bridge socket is on /, in order to avoid a dep loop, don't use kmsg logging for -.mount */
670
        m->exec_context.std_output = EXEC_OUTPUT_NULL;
414✔
671
        m->exec_context.std_input = EXEC_INPUT_NULL;
414✔
672

673
        if (!u->description)
414✔
674
                u->description = strdup("Root Mount");
414✔
675
}
676

677
static int mount_load(Unit *u) {
27,789✔
678
        Mount *m = ASSERT_PTR(MOUNT(u));
27,789✔
679
        int r;
27,789✔
680

681
        assert(u->load_state == UNIT_STUB);
27,789✔
682

683
        mount_load_root_mount(u);
27,789✔
684

685
        bool from_kernel = m->from_proc_self_mountinfo || u->perpetual;
27,789✔
686

687
        r = unit_load_fragment_and_dropin(u, /* fragment_required = */ !from_kernel);
27,789✔
688

689
        /* Add in some extras. Note we do this in all cases (even if we failed to load the unit) when announced by the
690
         * kernel, because we need some things to be set up no matter what when the kernel establishes a mount and thus
691
         * we need to update the state in our unit to track it. After all, consider that we don't allow changing the
692
         * 'slice' field for a unit once it is active. */
693
        if (u->load_state == UNIT_LOADED || from_kernel)
27,789✔
694
                RET_GATHER(r, mount_add_extras(m));
7,325✔
695

696
        if (r < 0)
27,789✔
697
                return r;
20,464✔
698

699
        if (u->load_state != UNIT_LOADED)
7,325✔
700
                return 0;
701

702
        return mount_verify(m);
7,325✔
703
}
704

705
static void mount_set_state(Mount *m, MountState state) {
8,538✔
706
        MountState old_state;
8,538✔
707

708
        assert(m);
8,538✔
709

710
        if (m->state != state)
8,538✔
711
                bus_unit_send_pending_change_signal(UNIT(m), false);
8,456✔
712

713
        old_state = m->state;
8,538✔
714
        m->state = state;
8,538✔
715

716
        if (!MOUNT_STATE_WITH_PROCESS(state)) {
8,538✔
717
                m->timer_event_source = sd_event_source_disable_unref(m->timer_event_source);
8,224✔
718
                mount_unwatch_control_pid(m);
8,224✔
719
                m->control_command = NULL;
8,224✔
720
                m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
8,224✔
721
        }
722

723
        if (state != old_state)
8,538✔
724
                log_unit_debug(UNIT(m), "Changed %s -> %s", mount_state_to_string(old_state), mount_state_to_string(state));
8,456✔
725

726
        unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
8,538✔
727
}
8,538✔
728

729
static int mount_coldplug(Unit *u) {
14,651✔
730
        Mount *m = ASSERT_PTR(MOUNT(u));
14,651✔
731
        int r;
14,651✔
732

733
        assert(m->state == MOUNT_DEAD);
14,651✔
734

735
        if (m->deserialized_state == m->state)
14,651✔
736
                return 0;
737

738
        if (pidref_is_set(&m->control_pid) &&
1,141✔
739
            pidref_is_unwaited(&m->control_pid) > 0 &&
7✔
740
            MOUNT_STATE_WITH_PROCESS(m->deserialized_state)) {
7✔
741

742
                r = unit_watch_pidref(UNIT(m), &m->control_pid, /* exclusive= */ false);
7✔
743
                if (r < 0)
7✔
744
                        return r;
745

746
                r = mount_arm_timer(m, /* relative= */ false, usec_add(u->state_change_timestamp.monotonic, m->timeout_usec));
14✔
747
                if (r < 0)
7✔
748
                        return r;
749
        }
750

751
        if (!IN_SET(m->deserialized_state, MOUNT_DEAD, MOUNT_FAILED))
1,134✔
752
                (void) unit_setup_exec_runtime(u);
1,134✔
753

754
        mount_set_state(m, m->deserialized_state);
1,134✔
755
        return 0;
1,134✔
756
}
757

758
static void mount_catchup(Unit *u) {
14,651✔
759
        Mount *m = ASSERT_PTR(MOUNT(u));
14,651✔
760

761
        /* Adjust the deserialized state. See comments in mount_process_proc_self_mountinfo(). */
762
        if (m->from_proc_self_mountinfo)
14,651✔
763
                switch (m->state) {
4,798✔
764
                case MOUNT_DEAD:
765
                case MOUNT_FAILED:
766
                        assert(!pidref_is_set(&m->control_pid));
3,666✔
767
                        (void) unit_acquire_invocation_id(u);
3,666✔
768
                        mount_cycle_clear(m);
3,666✔
769
                        mount_enter_mounted(m, MOUNT_SUCCESS);
3,666✔
770
                        break;
3,666✔
771
                case MOUNT_MOUNTING:
772
                        assert(pidref_is_set(&m->control_pid));
5✔
773
                        mount_set_state(m, MOUNT_MOUNTING_DONE);
5✔
774
                        break;
5✔
775
                default:
776
                        ;
777
                }
778
        else
779
                switch (m->state) {
9,853✔
780
                case MOUNT_MOUNTING_DONE:
781
                        assert(pidref_is_set(&m->control_pid));
×
782
                        mount_set_state(m, MOUNT_MOUNTING);
×
783
                        break;
×
784
                case MOUNT_MOUNTED:
785
                        assert(!pidref_is_set(&m->control_pid));
×
786
                        mount_enter_dead(m, MOUNT_SUCCESS, /* flush_result = */ false);
×
787
                        break;
×
788
                default:
14,651✔
789
                        ;
14,651✔
790
                }
791
}
14,651✔
792

793
static void mount_dump(Unit *u, FILE *f, const char *prefix) {
132✔
794
        Mount *m = ASSERT_PTR(MOUNT(u));
132✔
795
        MountParameters *p;
132✔
796
        const char *prefix2;
132✔
797

798
        assert(f);
132✔
799

800
        prefix = strempty(prefix);
132✔
801
        prefix2 = strjoina(prefix, "\t");
660✔
802

803
        p = get_mount_parameters(m);
132✔
804

805
        fprintf(f,
264✔
806
                "%sMount State: %s\n"
807
                "%sResult: %s\n"
808
                "%sClean Result: %s\n"
809
                "%sWhere: %s\n"
810
                "%sWhat: %s\n"
811
                "%sFile System Type: %s\n"
812
                "%sOptions: %s\n"
813
                "%sFrom /proc/self/mountinfo: %s\n"
814
                "%sFrom fragment: %s\n"
815
                "%sExtrinsic: %s\n"
816
                "%sDirectoryMode: %04o\n"
817
                "%sSloppyOptions: %s\n"
818
                "%sLazyUnmount: %s\n"
819
                "%sForceUnmount: %s\n"
820
                "%sReadWriteOnly: %s\n"
821
                "%sTimeoutSec: %s\n",
822
                prefix, mount_state_to_string(m->state),
823
                prefix, mount_result_to_string(m->result),
824
                prefix, mount_result_to_string(m->clean_result),
825
                prefix, m->where,
826
                prefix, p ? strna(p->what) : "n/a",
132✔
827
                prefix, p ? strna(p->fstype) : "n/a",
132✔
828
                prefix, p ? strna(p->options) : "n/a",
132✔
829
                prefix, yes_no(m->from_proc_self_mountinfo),
132✔
830
                prefix, yes_no(m->from_fragment),
132✔
831
                prefix, yes_no(mount_is_extrinsic(u)),
132✔
832
                prefix, m->directory_mode,
833
                prefix, yes_no(m->sloppy_options),
132✔
834
                prefix, yes_no(m->lazy_unmount),
132✔
835
                prefix, yes_no(m->force_unmount),
132✔
836
                prefix, yes_no(m->read_write_only),
132✔
837
                prefix, FORMAT_TIMESPAN(m->timeout_usec, USEC_PER_SEC));
132✔
838

839
        if (pidref_is_set(&m->control_pid))
132✔
840
                fprintf(f,
×
841
                        "%sControl PID: "PID_FMT"\n",
842
                        prefix, m->control_pid.pid);
843

844
        exec_context_dump(&m->exec_context, f, prefix);
132✔
845
        kill_context_dump(&m->kill_context, f, prefix);
132✔
846
        cgroup_context_dump(UNIT(m), f, prefix);
132✔
847

848
        for (MountExecCommand c = 0; c < _MOUNT_EXEC_COMMAND_MAX; c++) {
528✔
849
                if (!m->exec_command[c].argv)
396✔
850
                        continue;
396✔
851

852
                fprintf(f, "%s%s %s:\n",
×
853
                        prefix, glyph(GLYPH_ARROW_RIGHT), mount_exec_command_to_string(c));
854

855
                exec_command_dump(m->exec_command + c, f, prefix2);
×
856
        }
857
}
132✔
858

859
static ExecFlags mount_exec_flags(MountState state) {
173✔
860
        ExecFlags flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN;
173✔
861

862
        assert(IN_SET(state, MOUNT_MOUNTING, MOUNT_REMOUNTING, MOUNT_UNMOUNTING));
173✔
863

864
        if (IN_SET(state, MOUNT_MOUNTING, MOUNT_REMOUNTING))
173✔
865
                flags |= EXEC_SETUP_CREDENTIALS;
866

867
        return flags;
173✔
868
}
869

870
static int mount_spawn(Mount *m, ExecCommand *c, ExecFlags flags, PidRef *ret_pid) {
173✔
871
        _cleanup_(exec_params_shallow_clear) ExecParameters exec_params = EXEC_PARAMETERS_INIT(flags);
173✔
872
        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
173✔
873
        int r;
173✔
874

875
        assert(m);
173✔
876
        assert(c);
173✔
877
        assert(ret_pid);
173✔
878

879
        r = unit_prepare_exec(UNIT(m));
173✔
880
        if (r < 0)
173✔
881
                return r;
882

883
        r = mount_arm_timer(m, /* relative= */ true, m->timeout_usec);
173✔
884
        if (r < 0)
173✔
885
                return r;
886

887
        r = unit_set_exec_params(UNIT(m), &exec_params);
173✔
888
        if (r < 0)
173✔
889
                return r;
890

891
        /* Assume the label inherited from systemd as the fallback */
892
        exec_params.fallback_smack_process_label = NULL;
173✔
893

894
        r = exec_spawn(UNIT(m),
346✔
895
                       c,
896
                       &m->exec_context,
173✔
897
                       &exec_params,
898
                       m->exec_runtime,
899
                       &m->cgroup_context,
173✔
900
                       &pidref);
901
        if (r < 0)
173✔
902
                return r;
903

904
        r = unit_watch_pidref(UNIT(m), &pidref, /* exclusive= */ true);
173✔
905
        if (r < 0)
173✔
906
                return r;
907

908
        *ret_pid = TAKE_PIDREF(pidref);
173✔
909
        return 0;
173✔
910
}
911

912
static void mount_enter_dead(Mount *m, MountResult f, bool flush_result) {
1,618✔
913
        assert(m);
1,618✔
914

915
        if (m->result == MOUNT_SUCCESS || flush_result)
1,618✔
916
                m->result = f;
1,618✔
917

918
        unit_log_result(UNIT(m), m->result == MOUNT_SUCCESS, mount_result_to_string(m->result));
1,618✔
919
        unit_warn_leftover_processes(UNIT(m), /* start = */ false);
1,618✔
920

921
        mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
3,236✔
922

923
        m->exec_runtime = exec_runtime_destroy(m->exec_runtime);
1,618✔
924

925
        unit_destroy_runtime_data(UNIT(m), &m->exec_context, /* destroy_runtime_dir = */ true);
1,618✔
926

927
        unit_unref_uid_gid(UNIT(m), true);
1,618✔
928

929
        /* Any dependencies based on /proc/self/mountinfo are now stale. Let's re-generate dependencies from
930
         * .mount unit. */
931
        (void) mount_add_non_exec_dependencies(m);
1,618✔
932
}
1,618✔
933

934
static void mount_enter_mounted(Mount *m, MountResult f) {
5,397✔
935
        assert(m);
5,397✔
936

937
        if (m->result == MOUNT_SUCCESS)
5,397✔
938
                m->result = f;
5,397✔
939

940
        /* Refer to service_set_state() handling of SERVICE_EXITED state for rationale. In particular
941
         * for mount units let's not leave cred mounts around, otherwise the actual number of mounts would be
942
         * somewhat doubled.
943
         *
944
         * Note that this effectively means fresh creds are used during remount, but that's mostly what
945
         * users would expect anyways. */
946
        unit_destroy_runtime_data(UNIT(m), &m->exec_context, /* destroy_runtime_dir = */ false);
5,397✔
947

948
        mount_set_state(m, MOUNT_MOUNTED);
5,397✔
949
}
5,397✔
950

951
static void mount_enter_dead_or_mounted(Mount *m, MountResult f, bool flush_result) {
39✔
952
        assert(m);
39✔
953

954
        /* Enter DEAD or MOUNTED state, depending on what the kernel currently says about the mount point.
955
         * We use this whenever we executed an operation, so that our internal state reflects what
956
         * the kernel says again, after all ultimately we just mirror the kernel's internal state on this.
957
         *
958
         * Note that flush_result only applies to mount_enter_dead(), since that's when the result gets
959
         * turned into unit end state. */
960

961
        if (m->from_proc_self_mountinfo)
39✔
962
                mount_enter_mounted(m, f);
×
963
        else
964
                mount_enter_dead(m, f, flush_result);
39✔
965
}
39✔
966

967
static int state_to_kill_operation(MountState state) {
×
968
        switch (state) {
×
969

970
        case MOUNT_REMOUNTING_SIGTERM:
971
                return KILL_RESTART;
972

973
        case MOUNT_UNMOUNTING_SIGTERM:
×
974
                return KILL_TERMINATE;
×
975

976
        case MOUNT_REMOUNTING_SIGKILL:
×
977
        case MOUNT_UNMOUNTING_SIGKILL:
978
                return KILL_KILL;
×
979

980
        default:
×
981
                return _KILL_OPERATION_INVALID;
×
982
        }
983
}
984

985
static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
×
986
        int r;
×
987

988
        assert(m);
×
989

990
        if (m->result == MOUNT_SUCCESS)
×
991
                m->result = f;
×
992

993
        r = unit_kill_context(UNIT(m), state_to_kill_operation(state));
×
994
        if (r < 0) {
×
995
                log_unit_warning_errno(UNIT(m), r, "Failed to kill processes: %m");
×
996
                goto fail;
×
997
        }
998

999
        if (r > 0) {
×
1000
                r = mount_arm_timer(m, /* relative= */ true, m->timeout_usec);
×
1001
                if (r < 0) {
×
1002
                        log_unit_warning_errno(UNIT(m), r, "Failed to install timer: %m");
×
1003
                        goto fail;
×
1004
                }
1005

1006
                mount_set_state(m, state);
×
1007
        } else if (state == MOUNT_REMOUNTING_SIGTERM && m->kill_context.send_sigkill)
×
1008
                mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_SUCCESS);
×
1009
        else if (IN_SET(state, MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL))
×
1010
                mount_enter_mounted(m, MOUNT_SUCCESS);
×
1011
        else if (state == MOUNT_UNMOUNTING_SIGTERM && m->kill_context.send_sigkill)
×
1012
                mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_SUCCESS);
×
1013
        else
1014
                mount_enter_dead_or_mounted(m, MOUNT_SUCCESS, /* flush_result = */ false);
×
1015

1016
        return;
1017

1018
fail:
×
1019
        mount_enter_dead_or_mounted(m, MOUNT_FAILURE_RESOURCES, /* flush_result = */ false);
×
1020
}
1021

1022
static int mount_set_umount_command(Mount *m, ExecCommand *c) {
39✔
1023
        int r;
39✔
1024

1025
        assert(m);
39✔
1026
        assert(c);
39✔
1027

1028
        r = exec_command_set(c, UMOUNT_PATH, m->where, "-c", NULL);
39✔
1029
        if (r < 0)
39✔
1030
                return r;
1031

1032
        if (m->lazy_unmount) {
39✔
1033
                r = exec_command_append(c, "-l", NULL);
×
1034
                if (r < 0)
×
1035
                        return r;
1036
        }
1037

1038
        if (m->force_unmount) {
39✔
1039
                r = exec_command_append(c, "-f", NULL);
×
1040
                if (r < 0)
×
1041
                        return r;
×
1042
        }
1043

1044
        return 0;
1045
}
1046

1047
static void mount_enter_unmounting(Mount *m) {
39✔
1048
        int r;
39✔
1049

1050
        assert(m);
39✔
1051

1052
        /* Start counting our attempts */
1053
        if (!IN_SET(m->state,
39✔
1054
                    MOUNT_UNMOUNTING,
1055
                    MOUNT_UNMOUNTING_SIGTERM,
1056
                    MOUNT_UNMOUNTING_SIGKILL))
1057
                m->n_retry_umount = 0;
39✔
1058

1059
        mount_unwatch_control_pid(m);
39✔
1060

1061
        m->control_command_id = MOUNT_EXEC_UNMOUNT;
39✔
1062
        m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
39✔
1063

1064
        r = mount_set_umount_command(m, m->control_command);
39✔
1065
        if (r < 0) {
39✔
1066
                log_unit_warning_errno(UNIT(m), r, "Failed to prepare umount command line: %m");
×
1067
                goto fail;
×
1068
        }
1069

1070
        r = mount_spawn(m, m->control_command, mount_exec_flags(MOUNT_UNMOUNTING), &m->control_pid);
39✔
1071
        if (r < 0) {
39✔
1072
                log_unit_warning_errno(UNIT(m), r, "Failed to spawn 'umount' task: %m");
×
1073
                goto fail;
×
1074
        }
1075

1076
        mount_set_state(m, MOUNT_UNMOUNTING);
39✔
1077
        return;
39✔
1078

1079
fail:
×
1080
        mount_enter_dead_or_mounted(m, MOUNT_FAILURE_RESOURCES, /* flush_result = */ false);
×
1081
}
1082

1083
static int mount_apply_graceful_options(Mount *m, const MountParameters *p, char **opts) {
134✔
1084
        _cleanup_strv_free_ char **graceful = NULL;
×
1085
        _cleanup_free_ char *filtered = NULL;
134✔
1086
        int r;
134✔
1087

1088
        assert(m);
134✔
1089
        assert(p);
134✔
1090
        assert(opts);
134✔
1091

1092
        r = fstab_filter_options(*opts, "x-systemd.graceful-option\0", NULL, NULL, &graceful, &filtered);
134✔
1093
        if (r <= 0)
134✔
1094
                return r;
1095

1096
        if (!p->fstype) {
15✔
1097
                log_unit_warning(UNIT(m), "x-systemd.graceful-option= used but file system type not known, suppressing all graceful options.");
×
1098
                return 0;
×
1099
        }
1100

1101
        STRV_FOREACH(o, graceful) {
30✔
1102
                _cleanup_free_ char *k = NULL, *v = NULL;
15✔
1103

1104
                r = split_pair(*o, "=", &k, &v);
15✔
1105
                if (r < 0 && r != -EINVAL) /* EINVAL → not a key/value pair */
15✔
1106
                        return r;
1107

1108
                r = mount_option_supported(p->fstype, k ?: *o, v);
15✔
1109
                if (r == -EAGAIN) {
15✔
1110
                        log_unit_warning_errno(UNIT(m), r,
×
1111
                                               "x-systemd.graceful-option= used but not supported by file system %s, suppressing all.",
1112
                                               p->fstype);
1113
                        break;
×
1114
                }
1115
                if (r < 0)
15✔
1116
                        log_unit_warning_errno(UNIT(m), r,
×
1117
                                               "x-systemd.graceful-option=%s specified, but cannot determine availability, suppressing: %m", *o);
1118
                else if (r == 0)
15✔
1119
                        log_unit_info(UNIT(m), "x-systemd.graceful-option=%s specified, but option is not available, suppressing.", *o);
×
1120
                else {
1121
                        log_unit_debug(UNIT(m), "x-systemd.graceful-option=%s specified and supported, appending to mount option string.", *o);
15✔
1122

1123
                        if (!strextend_with_separator(&filtered, ",", *o))
15✔
1124
                                return -ENOMEM;
1125
                }
1126
        }
1127

1128
        return free_and_replace(*opts, filtered);
15✔
1129
}
1130

1131
static int mount_set_mount_command(Mount *m, ExecCommand *c, const MountParameters *p, bool remount) {
134✔
1132
        int r;
134✔
1133

1134
        assert(m);
134✔
1135
        assert(c);
134✔
1136
        assert(p);
134✔
1137

1138
        r = exec_command_set(c, MOUNT_PATH, p->what, m->where, NULL);
134✔
1139
        if (r < 0)
134✔
1140
                return r;
134✔
1141

1142
        if (m->sloppy_options) {
134✔
1143
                r = exec_command_append(c, "-s", NULL);
×
1144
                if (r < 0)
×
1145
                        return r;
1146
        }
1147

1148
        if (m->read_write_only) {
134✔
1149
                r = exec_command_append(c, "-w", NULL);
×
1150
                if (r < 0)
×
1151
                        return r;
1152
        }
1153

1154
        if (p->fstype) {
134✔
1155
                r = exec_command_append(c, "-t", p->fstype, NULL);
124✔
1156
                if (r < 0)
124✔
1157
                        return r;
1158
        }
1159

1160
        _cleanup_free_ char *opts = NULL;
134✔
1161
        r = fstab_filter_options(p->options, "nofail\0" "fail\0" "noauto\0" "auto\0", NULL, NULL, NULL, &opts);
134✔
1162
        if (r < 0)
134✔
1163
                return r;
1164

1165
        r = mount_apply_graceful_options(m, p, &opts);
134✔
1166
        if (r < 0)
134✔
1167
                return r;
1168

1169
        if (remount) {
134✔
1170
                if (isempty(opts)) {
×
1171
                        opts = strdup("remount");
×
1172
                        if (!opts)
×
1173
                                return -ENOMEM;
1174
                } else if (!strprepend(&opts, "remount,"))
×
1175
                        return -ENOMEM;
1176
        }
1177

1178
        if (!isempty(opts)) {
257✔
1179
                r = exec_command_append(c, "-o", opts, NULL);
123✔
1180
                if (r < 0)
123✔
1181
                        return r;
×
1182
        }
1183

1184
        return 0;
1185
}
1186

1187
static void mount_enter_mounting(Mount *m) {
134✔
1188
        _cleanup_close_ int fd = -EBADF;
134✔
1189
        _cleanup_free_ char *fn = NULL;
134✔
1190
        int r;
134✔
1191

1192
        assert(m);
134✔
1193

1194
        /* Validate that the path we are overmounting does not contain any symlinks, because if it does, we
1195
         * couldn't support that reasonably: the mounts in /proc/self/mountinfo would not be recognizable to
1196
         * us anymore. */
1197
        fd = chase_and_open_parent(m->where, /* root= */ NULL, CHASE_PROHIBIT_SYMLINKS|CHASE_MKDIR_0755, &fn);
134✔
1198
        if (fd == -EREMCHG) {
134✔
1199
                r = unit_log_noncanonical_mount_path(UNIT(m), m->where);
×
1200
                goto fail;
×
1201
        }
1202
        if (fd < 0) {
134✔
1203
                log_unit_error_errno(UNIT(m), fd, "Failed to resolve parent of mount point '%s': %m", m->where);
×
1204
                goto fail;
×
1205
        }
1206

1207
        MountParameters *p = get_mount_parameters_fragment(m);
134✔
1208
        if (!p) {
134✔
1209
                r = log_unit_warning_errno(UNIT(m), SYNTHETIC_ERRNO(ENOENT), "No mount parameters to operate on.");
×
1210
                goto fail;
×
1211
        }
1212

1213
        bool source_is_dir = true;
134✔
1214
        if (mount_is_bind(p)) {
134✔
1215
                r = is_dir(p->what, /* follow = */ true);
×
1216
                if (r < 0 && r != -ENOENT)
×
1217
                        log_unit_info_errno(UNIT(m), r, "Failed to determine type of bind mount source '%s', ignoring: %m", p->what);
×
1218
                else if (r == 0)
×
1219
                        source_is_dir = false;
×
1220
        }
1221

1222
        r = make_mount_point_inode_from_mode(
134✔
1223
                        fd,
1224
                        fn,
1225
                        source_is_dir ? S_IFDIR : S_IFREG,
1226
                        m->directory_mode);
1227
        if (r < 0 && r != -EEXIST)
134✔
1228
                log_unit_warning_errno(UNIT(m), r, "Failed to create mount point '%s', ignoring: %m", m->where);
×
1229

1230
        /* If we are asked to create an OverlayFS, create the upper/work directories if they are missing */
1231
        if (streq_ptr(p->fstype, "overlay")) {
134✔
1232
                _cleanup_strv_free_ char **dirs = NULL;
×
1233

1234
                r = fstab_filter_options(
×
1235
                                p->options,
×
1236
                                "upperdir\0workdir\0",
1237
                                /* ret_namefound= */ NULL,
1238
                                /* ret_value= */ NULL,
1239
                                &dirs,
1240
                                /* ret_filtered= */ NULL);
1241
                if (r < 0)
×
1242
                        log_unit_warning_errno(
×
1243
                                        UNIT(m),
1244
                                        r,
1245
                                        "Failed to determine upper directory for OverlayFS, ignoring: %m");
1246
                else
1247
                        STRV_FOREACH(d, dirs) {
×
1248
                                r = mkdir_p_label(*d, m->directory_mode);
×
1249
                                if (r < 0 && r != -EEXIST)
×
1250
                                        log_unit_warning_errno(
×
1251
                                                        UNIT(m),
1252
                                                        r,
1253
                                                        "Failed to create overlay directory '%s', ignoring: %m",
1254
                                                        *d);
1255
                        }
1256
        }
1257

1258
        if (source_is_dir)
134✔
1259
                unit_warn_if_dir_nonempty(UNIT(m), m->where);
134✔
1260

1261
        /* Create the source directory for bind-mounts if needed */
1262
        if (mount_is_bind(p)) {
134✔
1263
                r = mkdir_p_label(p->what, m->directory_mode);
×
1264
                /* mkdir_p_label() can return -EEXIST if the target path exists and is not a directory - which is
1265
                 * totally OK, in case the user wants us to overmount a non-directory inode. Also -EROFS can be
1266
                 * returned on read-only filesystem. Moreover, -EACCES (and also maybe -EPERM?) may be returned
1267
                 * when the path is on NFS. See issue #24120. All such errors will be logged in the debug level. */
1268
                if (r < 0 && r != -EEXIST)
×
1269
                        log_unit_full_errno(UNIT(m),
×
1270
                                            (r == -EROFS || ERRNO_IS_PRIVILEGE(r)) ? LOG_DEBUG : LOG_WARNING,
1271
                                            r, "Failed to make bind mount source '%s', ignoring: %m", p->what);
1272
        }
1273

1274
        mount_unwatch_control_pid(m);
134✔
1275
        unit_warn_leftover_processes(UNIT(m), /* start = */ true);
134✔
1276

1277
        m->control_command_id = MOUNT_EXEC_MOUNT;
134✔
1278
        m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
134✔
1279

1280
        r = mount_set_mount_command(m, m->control_command, p, /* remount = */ false);
134✔
1281
        if (r < 0) {
134✔
1282
                log_unit_error_errno(UNIT(m), r, "Failed to prepare mount command line: %m");
×
1283
                goto fail;
×
1284
        }
1285

1286
        r = mount_spawn(m, m->control_command, mount_exec_flags(MOUNT_MOUNTING), &m->control_pid);
134✔
1287
        if (r < 0) {
134✔
1288
                log_unit_warning_errno(UNIT(m), r, "Failed to spawn 'mount' task: %m");
×
1289
                goto fail;
×
1290
        }
1291

1292
        mount_set_state(m, MOUNT_MOUNTING);
134✔
1293
        return;
134✔
1294

1295
fail:
×
1296
        mount_enter_dead_or_mounted(m, MOUNT_FAILURE_RESOURCES, /* flush_result = */ false);
×
1297
}
1298

1299
static void mount_set_reload_result(Mount *m, MountResult result) {
×
1300
        assert(m);
×
1301

1302
        /* Only store the first error we encounter */
1303
        if (m->reload_result != MOUNT_SUCCESS)
×
1304
                return;
1305

1306
        m->reload_result = result;
×
1307
}
1308

1309
static void mount_enter_remounting(Mount *m) {
×
1310
        MountParameters *p;
×
1311
        int r;
×
1312

1313
        assert(m);
×
1314

1315
        p = get_mount_parameters_fragment(m);
×
1316
        if (!p) {
×
1317
                r = log_unit_warning_errno(UNIT(m), SYNTHETIC_ERRNO(ENOENT), "No mount parameters to operate on.");
×
1318
                goto fail;
×
1319
        }
1320

1321
        mount_unwatch_control_pid(m);
×
1322
        m->reload_result = MOUNT_SUCCESS;
×
1323

1324
        m->control_command_id = MOUNT_EXEC_REMOUNT;
×
1325
        m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
×
1326

1327
        r = mount_set_mount_command(m, m->control_command, p, /* remount = */ true);
×
1328
        if (r < 0) {
×
1329
                log_unit_error_errno(UNIT(m), r, "Failed to prepare remount command line: %m");
×
1330
                goto fail;
×
1331
        }
1332

1333
        r = mount_spawn(m, m->control_command, mount_exec_flags(MOUNT_REMOUNTING), &m->control_pid);
×
1334
        if (r < 0) {
×
1335
                log_unit_warning_errno(UNIT(m), r, "Failed to spawn 'remount' task: %m");
×
1336
                goto fail;
×
1337
        }
1338

1339
        mount_set_state(m, MOUNT_REMOUNTING);
×
1340
        return;
×
1341

1342
fail:
×
1343
        mount_set_reload_result(m, MOUNT_FAILURE_RESOURCES);
×
1344
        mount_enter_dead_or_mounted(m, MOUNT_SUCCESS, /* flush_result = */ false);
×
1345
}
1346

1347
static void mount_cycle_clear(Mount *m) {
6,976✔
1348
        assert(m);
6,976✔
1349

1350
        /* Clear all state we shall forget for this new cycle */
1351

1352
        m->result = MOUNT_SUCCESS;
6,976✔
1353
        m->reload_result = MOUNT_SUCCESS;
6,976✔
1354
        exec_command_reset_status_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
6,976✔
1355

1356
        if (m->cgroup_runtime)
6,976✔
1357
                m->cgroup_runtime->reset_accounting = true;
3✔
1358
}
6,976✔
1359

1360
static int mount_start(Unit *u) {
134✔
1361
        Mount *m = ASSERT_PTR(MOUNT(u));
134✔
1362
        int r;
134✔
1363

1364
        /* We cannot fulfill this request right now, try again later
1365
         * please! */
1366
        if (IN_SET(m->state,
134✔
1367
                   MOUNT_UNMOUNTING,
1368
                   MOUNT_UNMOUNTING_SIGTERM,
1369
                   MOUNT_UNMOUNTING_SIGKILL,
1370
                   MOUNT_CLEANING))
1371
                return -EAGAIN;
1372

1373
        /* Already on it! */
1374
        if (IN_SET(m->state, MOUNT_MOUNTING, MOUNT_MOUNTING_DONE))
134✔
1375
                return 0;
1376

1377
        assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED));
134✔
1378

1379
        r = unit_acquire_invocation_id(u);
134✔
1380
        if (r < 0)
134✔
1381
                return r;
1382

1383
        mount_cycle_clear(m);
134✔
1384
        mount_enter_mounting(m);
134✔
1385

1386
        return 1;
134✔
1387
}
1388

1389
static int mount_stop(Unit *u) {
39✔
1390
        Mount *m = ASSERT_PTR(MOUNT(u));
39✔
1391

1392
        switch (m->state) {
39✔
1393

1394
        case MOUNT_UNMOUNTING:
1395
        case MOUNT_UNMOUNTING_SIGKILL:
1396
        case MOUNT_UNMOUNTING_SIGTERM:
1397
                /* Already on it */
1398
                return 0;
1399

1400
        case MOUNT_MOUNTING:
×
1401
        case MOUNT_MOUNTING_DONE:
1402
        case MOUNT_REMOUNTING:
1403
                /* If we are still waiting for /bin/mount, we go directly into kill mode. */
1404
                mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_SUCCESS);
×
1405
                return 0;
×
1406

1407
        case MOUNT_REMOUNTING_SIGTERM:
×
1408
                /* If we are already waiting for a hung remount, convert this to the matching unmounting state */
1409
                mount_set_state(m, MOUNT_UNMOUNTING_SIGTERM);
×
1410
                return 0;
×
1411

1412
        case MOUNT_REMOUNTING_SIGKILL:
×
1413
                /* as above */
1414
                mount_set_state(m, MOUNT_UNMOUNTING_SIGKILL);
×
1415
                return 0;
×
1416

1417
        case MOUNT_MOUNTED:
39✔
1418
                mount_enter_unmounting(m);
39✔
1419
                return 1;
39✔
1420

1421
        case MOUNT_CLEANING:
×
1422
                /* If we are currently cleaning, then abort it, brutally. */
1423
                mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_SUCCESS);
×
1424
                return 0;
×
1425

1426
        default:
×
1427
                assert_not_reached();
×
1428
        }
1429
}
1430

1431
static int mount_reload(Unit *u) {
×
1432
        Mount *m = ASSERT_PTR(MOUNT(u));
×
1433

1434
        assert(m->state == MOUNT_MOUNTED);
×
1435

1436
        mount_enter_remounting(m);
×
1437

1438
        return 1;
×
1439
}
1440

1441
static bool mount_can_reload(Unit *u) {
78✔
1442
        Mount *m = ASSERT_PTR(MOUNT(u));
78✔
1443

1444
        return get_mount_parameters_fragment(m);
78✔
1445
}
1446

1447
static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
1,435✔
1448
        Mount *m = ASSERT_PTR(MOUNT(u));
1,435✔
1449

1450
        assert(f);
1,435✔
1451
        assert(fds);
1,435✔
1452

1453
        (void) serialize_item(f, "state", mount_state_to_string(m->state));
1,435✔
1454
        (void) serialize_item(f, "result", mount_result_to_string(m->result));
1,435✔
1455
        (void) serialize_item(f, "reload-result", mount_result_to_string(m->reload_result));
1,435✔
1456
        (void) serialize_item_format(f, "n-retry-umount", "%u", m->n_retry_umount);
1,435✔
1457
        (void) serialize_pidref(f, fds, "control-pid", &m->control_pid);
1,435✔
1458

1459
        if (m->control_command_id >= 0)
1,435✔
1460
                (void) serialize_item(f, "control-command", mount_exec_command_to_string(m->control_command_id));
7✔
1461

1462
        return 0;
1,435✔
1463
}
1464

1465
static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
4,865✔
1466
        Mount *m = ASSERT_PTR(MOUNT(u));
4,865✔
1467
        int r;
4,865✔
1468

1469
        assert(key);
4,865✔
1470
        assert(value);
4,865✔
1471
        assert(fds);
4,865✔
1472

1473
        if (streq(key, "state")) {
4,865✔
1474
                MountState state;
1,211✔
1475

1476
                state = mount_state_from_string(value);
1,211✔
1477
                if (state < 0)
1,211✔
1478
                        log_unit_debug_errno(u, state, "Failed to parse state value: %s", value);
×
1479
                else
1480
                        m->deserialized_state = state;
1,211✔
1481

1482
        } else if (streq(key, "result")) {
3,654✔
1483
                MountResult f;
1,211✔
1484

1485
                f = mount_result_from_string(value);
1,211✔
1486
                if (f < 0)
1,211✔
1487
                        log_unit_debug_errno(u, f, "Failed to parse result value: %s", value);
×
1488
                else if (f != MOUNT_SUCCESS)
1,211✔
1489
                        m->result = f;
×
1490

1491
        } else if (streq(key, "reload-result")) {
2,443✔
1492
                MountResult f;
1,211✔
1493

1494
                f = mount_result_from_string(value);
1,211✔
1495
                if (f < 0)
1,211✔
1496
                        log_unit_debug_errno(u, f, "Failed to parse reload result value: %s", value);
×
1497
                else if (f != MOUNT_SUCCESS)
1,211✔
1498
                        m->reload_result = f;
×
1499

1500
        } else if (streq(key, "n-retry-umount")) {
1,232✔
1501

1502
                r = safe_atou(value, &m->n_retry_umount);
1,211✔
1503
                if (r < 0)
1,211✔
1504
                        log_unit_debug_errno(u, r, "Failed to parse n-retry-umount value: %s", value);
×
1505

1506
        } else if (streq(key, "control-pid")) {
21✔
1507

1508
                if (!pidref_is_set(&m->control_pid))
14✔
1509
                        (void) deserialize_pidref(fds, value, &m->control_pid);
7✔
1510

1511
        } else if (streq(key, "control-command")) {
7✔
1512
                MountExecCommand id;
7✔
1513

1514
                id = mount_exec_command_from_string(value);
7✔
1515
                if (id < 0)
7✔
1516
                        log_unit_debug_errno(u, id, "Failed to parse exec-command value: %s", value);
×
1517
                else {
1518
                        m->control_command_id = id;
7✔
1519
                        m->control_command = m->exec_command + id;
7✔
1520
                }
1521
        } else
1522
                log_unit_debug(u, "Unknown serialization key: %s", key);
×
1523

1524
        return 0;
4,865✔
1525
}
1526

1527
static UnitActiveState mount_active_state(Unit *u) {
354,156✔
1528
        Mount *m = ASSERT_PTR(MOUNT(u));
354,156✔
1529

1530
        return state_translation_table[m->state];
354,156✔
1531
}
1532

1533
static const char *mount_sub_state_to_string(Unit *u) {
1,809✔
1534
        Mount *m = ASSERT_PTR(MOUNT(u));
1,809✔
1535

1536
        return mount_state_to_string(m->state);
1,809✔
1537
}
1538

1539
static bool mount_may_gc(Unit *u) {
52,510✔
1540
        Mount *m = ASSERT_PTR(MOUNT(u));
52,510✔
1541

1542
        if (m->from_proc_self_mountinfo)
52,510✔
1543
                return false;
5,623✔
1544

1545
        return true;
1546
}
1547

1548
static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
173✔
1549
        Mount *m = ASSERT_PTR(MOUNT(u));
173✔
1550
        MountResult f;
173✔
1551

1552
        assert(pid >= 0);
173✔
1553

1554
        if (pid != m->control_pid.pid)
173✔
1555
                return;
1556

1557
        /* So here's the thing, we really want to know before /usr/bin/mount or /usr/bin/umount exit whether
1558
         * they established/remove a mount. This is important when mounting, but even more so when unmounting
1559
         * since we need to deal with nested mounts and otherwise cannot safely determine whether to repeat
1560
         * the unmounts. In theory, the kernel fires /proc/self/mountinfo changes off before returning from
1561
         * the mount() or umount() syscalls, and thus we should see the changes to the proc file before we
1562
         * process the waitid() for the /usr/bin/(u)mount processes. However, this is unfortunately racy: we
1563
         * have to waitid() for processes using P_ALL (since we need to reap unexpected children that got
1564
         * reparented to PID 1), but when using P_ALL we might end up reaping processes that terminated just
1565
         * instants ago, i.e. already after our last event loop iteration (i.e. after the last point we might
1566
         * have noticed /proc/self/mountinfo events via epoll). This means event loop priorities for
1567
         * processing SIGCHLD vs. /proc/self/mountinfo IO events are not as relevant as we want. To fix that
1568
         * race, let's explicitly scan /proc/self/mountinfo before we start processing /usr/bin/(u)mount
1569
         * dying. It's ugly, but it makes our ordering systematic again, and makes sure we always see
1570
         * /proc/self/mountinfo changes before our mount/umount exits. */
1571
        (void) mount_process_proc_self_mountinfo(u->manager);
173✔
1572

1573
        pidref_done(&m->control_pid);
173✔
1574

1575
        if (is_clean_exit(code, status, EXIT_CLEAN_COMMAND, NULL))
173✔
1576
                f = MOUNT_SUCCESS;
1577
        else if (code == CLD_EXITED)
×
1578
                f = MOUNT_FAILURE_EXIT_CODE;
1579
        else if (code == CLD_KILLED)
×
1580
                f = MOUNT_FAILURE_SIGNAL;
1581
        else if (code == CLD_DUMPED)
×
1582
                f = MOUNT_FAILURE_CORE_DUMP;
1583
        else
1584
                assert_not_reached();
×
1585

1586
        if (IN_SET(m->state, MOUNT_REMOUNTING, MOUNT_REMOUNTING_SIGKILL, MOUNT_REMOUNTING_SIGTERM))
173✔
1587
                mount_set_reload_result(m, f);
×
1588
        else if (m->result == MOUNT_SUCCESS && !IN_SET(m->state, MOUNT_MOUNTING, MOUNT_UNMOUNTING))
173✔
1589
                /* MOUNT_MOUNTING and MOUNT_UNMOUNTING states need to be patched, see below. */
1590
                m->result = f;
134✔
1591

1592
        if (m->control_command) {
173✔
1593
                exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
173✔
1594

1595
                m->control_command = NULL;
173✔
1596
                m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
173✔
1597
        }
1598

1599
        unit_log_process_exit(
173✔
1600
                        u,
1601
                        "Mount process",
1602
                        mount_exec_command_to_string(m->control_command_id),
1603
                        f == MOUNT_SUCCESS,
1604
                        code, status);
1605

1606
        /* Note that due to the io event priority logic, we can be sure the new mountinfo is loaded
1607
         * before we process the SIGCHLD for the mount command. */
1608

1609
        switch (m->state) {
173✔
1610

1611
        case MOUNT_MOUNTING:
×
1612
                /* Our mount point has not appeared in mountinfo. Something went wrong. */
1613

1614
                if (f == MOUNT_SUCCESS) {
×
1615
                        /* Either /bin/mount has an unexpected definition of success, or someone raced us
1616
                         * and we lost. */
1617
                        log_unit_warning(UNIT(m), "Mount process finished, but there is no mount.");
×
1618
                        f = MOUNT_FAILURE_PROTOCOL;
×
1619
                }
1620
                mount_enter_dead(m, f, /* flush_result = */ false);
×
1621
                break;
×
1622

1623
        case MOUNT_MOUNTING_DONE:
134✔
1624
                mount_enter_mounted(m, f);
134✔
1625
                break;
134✔
1626

1627
        case MOUNT_REMOUNTING:
×
1628
        case MOUNT_REMOUNTING_SIGTERM:
1629
        case MOUNT_REMOUNTING_SIGKILL:
1630
                mount_enter_dead_or_mounted(m, MOUNT_SUCCESS, /* flush_result = */ false);
×
1631
                break;
×
1632

1633
        case MOUNT_UNMOUNTING:
39✔
1634
                if (f == MOUNT_SUCCESS && m->from_proc_self_mountinfo) {
39✔
1635
                        /* Still a mount point? If so, let's try again. Most likely there were multiple mount points
1636
                         * stacked on top of each other. We might exceed the timeout specified by the user overall,
1637
                         * but we will stop as soon as any one umount times out. */
1638

1639
                        if (m->n_retry_umount < RETRY_UMOUNT_MAX) {
×
1640
                                log_unit_debug(u, "Mount still present, trying again.");
×
1641
                                m->n_retry_umount++;
×
1642
                                mount_enter_unmounting(m);
×
1643
                        } else {
1644
                                log_unit_warning(u, "Mount still present after %u attempts to unmount, giving up.", m->n_retry_umount);
×
1645
                                mount_enter_mounted(m, MOUNT_FAILURE_PROTOCOL);
×
1646
                        }
1647
                } else if (f == MOUNT_FAILURE_EXIT_CODE && !m->from_proc_self_mountinfo) {
39✔
1648
                        /* Hmm, umount process spawned by us failed, but the mount disappeared anyway?
1649
                         * Maybe someone else is trying to unmount at the same time. */
1650
                        log_unit_notice(u, "Mount disappeared even though umount process failed, continuing.");
×
1651
                        mount_enter_dead(m, MOUNT_SUCCESS, /* flush_result = */ true);
×
1652
                } else
1653
                        /* At this point, either the unmount succeeded or unexpected error occurred. We usually
1654
                         * remember the first error in 'result', but here let's update that forcibly, since
1655
                         * there could previous failed attempts yet we only care about the most recent
1656
                         * attempt. IOW, if we eventually managed to unmount the stuff, don't enter failed
1657
                         * end state. */
1658
                        mount_enter_dead_or_mounted(m, f, /* flush_result = */ true);
39✔
1659

1660
                break;
1661

1662
        case MOUNT_UNMOUNTING_SIGTERM:
×
1663
        case MOUNT_UNMOUNTING_SIGKILL:
1664
                mount_enter_dead_or_mounted(m, f, /* flush_result = */ false);
×
1665
                break;
×
1666

1667
        case MOUNT_CLEANING:
×
1668
                if (m->clean_result == MOUNT_SUCCESS)
×
1669
                        m->clean_result = f;
×
1670

1671
                mount_enter_dead(m, MOUNT_SUCCESS, /* flush_result = */ false);
×
1672
                break;
×
1673

1674
        default:
×
1675
                assert_not_reached();
×
1676
        }
1677

1678
        /* Notify clients about changed exit status */
1679
        unit_add_to_dbus_queue(u);
173✔
1680
}
1681

1682
static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
×
1683
        Mount *m = ASSERT_PTR(MOUNT(userdata));
×
1684

1685
        assert(m->timer_event_source == source);
×
1686

1687
        switch (m->state) {
×
1688

1689
        case MOUNT_MOUNTING:
1690
        case MOUNT_MOUNTING_DONE:
1691
                log_unit_warning(UNIT(m), "Mounting timed out. Terminating.");
×
1692
                mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
×
1693
                break;
×
1694

1695
        case MOUNT_REMOUNTING:
1696
                log_unit_warning(UNIT(m), "Remounting timed out. Terminating remount process.");
×
1697
                mount_set_reload_result(m, MOUNT_FAILURE_TIMEOUT);
×
1698
                mount_enter_signal(m, MOUNT_REMOUNTING_SIGTERM, MOUNT_SUCCESS);
×
1699
                break;
×
1700

1701
        case MOUNT_REMOUNTING_SIGTERM:
×
1702
                mount_set_reload_result(m, MOUNT_FAILURE_TIMEOUT);
×
1703

1704
                if (m->kill_context.send_sigkill) {
×
1705
                        log_unit_warning(UNIT(m), "Remounting timed out. Killing.");
×
1706
                        mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_SUCCESS);
×
1707
                } else {
1708
                        log_unit_warning(UNIT(m), "Remounting timed out. Skipping SIGKILL. Ignoring.");
×
1709
                        mount_enter_dead_or_mounted(m, MOUNT_SUCCESS, /* flush_result = */ false);
×
1710
                }
1711
                break;
1712

1713
        case MOUNT_REMOUNTING_SIGKILL:
×
1714
                mount_set_reload_result(m, MOUNT_FAILURE_TIMEOUT);
×
1715

1716
                log_unit_warning(UNIT(m), "Mount process still around after SIGKILL. Ignoring.");
×
1717
                mount_enter_dead_or_mounted(m, MOUNT_SUCCESS, /* flush_result = */ false);
×
1718
                break;
×
1719

1720
        case MOUNT_UNMOUNTING:
1721
                log_unit_warning(UNIT(m), "Unmounting timed out. Terminating.");
×
1722
                mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
×
1723
                break;
×
1724

1725
        case MOUNT_UNMOUNTING_SIGTERM:
×
1726
                if (m->kill_context.send_sigkill) {
×
1727
                        log_unit_warning(UNIT(m), "Mount process timed out. Killing.");
×
1728
                        mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
×
1729
                } else {
1730
                        log_unit_warning(UNIT(m), "Mount process timed out. Skipping SIGKILL. Ignoring.");
×
1731
                        mount_enter_dead_or_mounted(m, MOUNT_FAILURE_TIMEOUT, /* flush_result = */ false);
×
1732
                }
1733
                break;
1734

1735
        case MOUNT_UNMOUNTING_SIGKILL:
1736
                log_unit_warning(UNIT(m), "Mount process still around after SIGKILL. Ignoring.");
×
1737
                mount_enter_dead_or_mounted(m, MOUNT_FAILURE_TIMEOUT, /* flush_result = */ false);
×
1738
                break;
×
1739

1740
        case MOUNT_CLEANING:
1741
                log_unit_warning(UNIT(m), "Cleaning timed out. killing.");
×
1742

1743
                if (m->clean_result == MOUNT_SUCCESS)
×
1744
                        m->clean_result = MOUNT_FAILURE_TIMEOUT;
×
1745

1746
                mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, 0);
×
1747
                break;
×
1748

1749
        default:
×
1750
                assert_not_reached();
×
1751
        }
1752

1753
        return 0;
×
1754
}
1755

1756
static int mount_setup_new_unit(
6,121✔
1757
                Manager *m,
1758
                const char *name,
1759
                const char *what,
1760
                const char *where,
1761
                const char *options,
1762
                const char *fstype,
1763
                MountProcFlags *ret_flags,
1764
                Unit **ret) {
1765

1766
        _cleanup_(unit_freep) Unit *u = NULL;
6,121✔
1767
        Mount *mnt;
6,121✔
1768
        int r;
6,121✔
1769

1770
        assert(m);
6,121✔
1771
        assert(name);
6,121✔
1772
        assert(ret_flags);
6,121✔
1773
        assert(ret);
6,121✔
1774

1775
        r = unit_new_for_name(m, sizeof(Mount), name, &u);
6,121✔
1776
        if (r < 0)
6,121✔
1777
                return r;
1778

1779
        mnt = ASSERT_PTR(MOUNT(u));
6,121✔
1780

1781
        r = free_and_strdup(&u->source_path, "/proc/self/mountinfo");
6,121✔
1782
        if (r < 0)
6,121✔
1783
                return r;
1784

1785
        r = free_and_strdup(&mnt->where, where);
6,121✔
1786
        if (r < 0)
6,121✔
1787
                return r;
1788

1789
        r = update_parameters_proc_self_mountinfo(mnt, what, options, fstype);
6,121✔
1790
        if (r < 0)
6,121✔
1791
                return r;
1792

1793
        /* This unit was generated because /proc/self/mountinfo reported it. Remember this, so that by the
1794
         * time we load the unit file for it (and thus add in extra deps right after) we know what source to
1795
         * attributes the deps to. */
1796
        mnt->from_proc_self_mountinfo = true;
6,121✔
1797

1798
        /* We have only allocated the stub now, let's enqueue this unit for loading now, so that everything
1799
         * else is loaded in now. */
1800
        unit_add_to_load_queue(u);
6,121✔
1801

1802
        *ret_flags = MOUNT_PROC_IS_MOUNTED | MOUNT_PROC_JUST_MOUNTED | MOUNT_PROC_JUST_CHANGED;
6,121✔
1803
        *ret = TAKE_PTR(u);
6,121✔
1804
        return 0;
6,121✔
1805
}
1806

1807
static int mount_setup_existing_unit(
64,243✔
1808
                Unit *u,
1809
                const char *what,
1810
                const char *where,
1811
                const char *options,
1812
                const char *fstype,
1813
                MountProcFlags *ret_flags) {
1814

1815
        Mount *m = ASSERT_PTR(MOUNT(u));
64,243✔
1816
        int r;
64,243✔
1817

1818
        assert(u);
64,243✔
1819
        assert(where);
64,243✔
1820
        assert(ret_flags);
64,243✔
1821

1822
        if (!m->where) {
64,243✔
1823
                m->where = strdup(where);
274✔
1824
                if (!m->where)
274✔
1825
                        return -ENOMEM;
1826
        }
1827

1828
        /* In case we have multiple mounts established on the same mount point, let's merge flags set already
1829
         * for the current unit. Note that the flags field is reset on each iteration of reading
1830
         * /proc/self/mountinfo, hence we know for sure anything already set here is from the current
1831
         * iteration and thus worthy of taking into account. */
1832
        MountProcFlags flags = m->proc_flags | MOUNT_PROC_IS_MOUNTED;
64,243✔
1833

1834
        r = update_parameters_proc_self_mountinfo(m, what, options, fstype);
64,243✔
1835
        if (r < 0)
64,243✔
1836
                return r;
1837
        if (r > 0)
64,243✔
1838
                flags |= MOUNT_PROC_JUST_CHANGED;
514✔
1839

1840
        /* There are two conditions when we consider a mount point just mounted: when we haven't seen it in
1841
         * /proc/self/mountinfo before or when MOUNT_MOUNTING is our current state. Why bother with the
1842
         * latter? Shouldn't that be covered by the former? No, during reload it is not because we might then
1843
         * encounter a new /proc/self/mountinfo in combination with an old mount unit state (since it stems
1844
         * from the serialized state), and need to catch up. Since we know that the MOUNT_MOUNTING state is
1845
         * reached when we wait for the mount to appear we hence can assume that if we are in it, we are
1846
         * actually seeing it established for the first time. */
1847
        if (!m->from_proc_self_mountinfo || m->state == MOUNT_MOUNTING)
64,243✔
1848
                flags |= MOUNT_PROC_JUST_MOUNTED;
403✔
1849

1850
        m->from_proc_self_mountinfo = true;
64,243✔
1851

1852
        if (UNIT_IS_LOAD_ERROR(u->load_state)) {
64,243✔
1853
                /* The unit was previously not found or otherwise not loaded. Now that the unit shows up in
1854
                 * /proc/self/mountinfo we should reconsider that. Hence, let's reset the load state and load
1855
                 * error, and add the unit to load queue. */
1856
                u->load_state = UNIT_STUB;
×
1857
                u->load_error = 0;
×
1858
                unit_add_to_load_queue(u);
×
1859

1860
                flags |= MOUNT_PROC_JUST_CHANGED;
×
1861
        }
1862

1863
        if (FLAGS_SET(flags, MOUNT_PROC_JUST_CHANGED) && u->load_state == UNIT_LOADED) {
64,243✔
1864
                /* If things changed, and we have successfully loaded the unit, then make sure that all deps
1865
                 * are regenerated. Let's first remove all automatic deps, and then add in the new ones. */
1866
                r = mount_add_non_exec_dependencies(m);
286✔
1867
                if (r < 0)
286✔
1868
                        return r;
1869
        }
1870

1871
        *ret_flags = flags;
64,243✔
1872
        return 0;
64,243✔
1873
}
1874

1875
static int mount_setup_unit(
126,321✔
1876
                Manager *m,
1877
                const char *what,
1878
                const char *where,
1879
                const char *options,
1880
                const char *fstype,
1881
                bool set_flags) {
1882

1883
        _cleanup_free_ char *e = NULL;
126,321✔
1884
        MountProcFlags flags;
126,321✔
1885
        Unit *u;
126,321✔
1886
        int r;
126,321✔
1887

1888
        assert(m);
126,321✔
1889
        assert(what);
126,321✔
1890
        assert(where);
126,321✔
1891
        assert(options);
126,321✔
1892
        assert(fstype);
126,321✔
1893

1894
        /* Ignore API and credential mount points. They should never be referenced in dependencies ever.
1895
         * Furthermore, the lifetime of credential mounts is strictly bound to the owning services,
1896
         * so mount units make little sense for them. */
1897
        if (mount_point_is_api(where) || mount_point_ignore(where) ||
204,297✔
1898
            mount_point_is_credentials(m->prefix[EXEC_DIRECTORY_RUNTIME], where))
77,976✔
1899
                return 0;
50,667✔
1900

1901
        if (streq(fstype, "autofs"))
75,654✔
1902
                return 0;
1903

1904
        /* probably some kind of swap, ignore */
1905
        if (!is_path(where))
70,364✔
1906
                return 0;
1907

1908
        r = unit_name_from_path(where, ".mount", &e);
70,364✔
1909
        if (r < 0)
70,364✔
1910
                return log_struct_errno(
×
1911
                                LOG_WARNING, r,
1912
                                LOG_MESSAGE_ID(SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE_STR),
1913
                                LOG_ITEM("MOUNT_POINT=%s", where),
1914
                                LOG_MESSAGE("Failed to generate valid unit name from mount point path '%s', ignoring mount point: %m",
1915
                                            where));
1916

1917
        u = manager_get_unit(m, e);
70,364✔
1918
        if (u)
70,364✔
1919
                r = mount_setup_existing_unit(u, what, where, options, fstype, &flags);
64,243✔
1920
        else
1921
                /* First time we see this mount point meaning that it's not been initiated by a mount unit
1922
                 * but rather by the sysadmin having called mount(8) directly. */
1923
                r = mount_setup_new_unit(m, e, what, where, options, fstype, &flags, &u);
6,121✔
1924
        if (r < 0)
70,364✔
1925
                return log_warning_errno(r, "Failed to set up mount unit for '%s': %m", where);
×
1926

1927
        /* If the mount changed properties or state, let's notify our clients */
1928
        if (flags & (MOUNT_PROC_JUST_CHANGED|MOUNT_PROC_JUST_MOUNTED))
70,364✔
1929
                unit_add_to_dbus_queue(u);
6,703✔
1930

1931
        if (set_flags)
70,364✔
1932
                MOUNT(u)->proc_flags = flags;
130,808✔
1933

1934
        return 0;
1935
}
1936

1937
static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
3,964✔
1938
        _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
3,964✔
1939
        _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
3,964✔
1940
        _cleanup_set_free_ Set *devices = NULL;
3,964✔
1941
        int r;
3,964✔
1942

1943
        assert(m);
3,964✔
1944

1945
        r = libmount_parse_with_utab(&table, &iter);
3,964✔
1946
        if (r < 0)
3,964✔
1947
                return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
×
1948

1949
        for (;;) {
130,285✔
1950
                struct libmnt_fs *fs;
130,285✔
1951
                const char *device, *path, *options, *fstype;
130,285✔
1952

1953
                r = mnt_table_next_fs(table, iter, &fs);
130,285✔
1954
                if (r == 1)
130,285✔
1955
                        break;
1956
                if (r < 0)
126,321✔
1957
                        return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
×
1958

1959
                device = mnt_fs_get_source(fs);
126,321✔
1960
                path = mnt_fs_get_target(fs);
126,321✔
1961
                options = mnt_fs_get_options(fs);
126,321✔
1962
                fstype = mnt_fs_get_fstype(fs);
126,321✔
1963

1964
                if (!device || !path)
126,321✔
1965
                        continue;
×
1966

1967
                /* Just to achieve device name uniqueness. Note that the suppression of the duplicate
1968
                 * processing is merely an optimization, hence in case of OOM (unlikely) we'll just process
1969
                 * it twice. */
1970
                if (set_put_strdup_full(&devices, &path_hash_ops_free, device) != 0)
126,321✔
1971
                        device_found_node(m, device, DEVICE_FOUND_MOUNT, DEVICE_FOUND_MOUNT);
63,071✔
1972

1973
                (void) mount_setup_unit(m, device, path, options, fstype, set_flags);
126,321✔
1974
        }
1975

1976
        return 0;
3,964✔
1977
}
1978

1979
static void mount_shutdown(Manager *m) {
702✔
1980
        assert(m);
702✔
1981

1982
        m->mount_event_source = sd_event_source_disable_unref(m->mount_event_source);
702✔
1983

1984
        mnt_unref_monitor(m->mount_monitor);
702✔
1985
        m->mount_monitor = NULL;
702✔
1986
}
702✔
1987

1988
static void mount_handoff_timestamp(
346✔
1989
                Unit *u,
1990
                const struct ucred *ucred,
1991
                const dual_timestamp *ts) {
1992

1993
        Mount *m = ASSERT_PTR(MOUNT(u));
346✔
1994

1995
        assert(ucred);
346✔
1996
        assert(ts);
346✔
1997

1998
        if (m->control_pid.pid == ucred->pid && m->control_command) {
346✔
1999
                exec_status_handoff(&m->control_command->exec_status, ucred, ts);
346✔
2000
                unit_add_to_dbus_queue(u);
346✔
2001
        }
2002
}
346✔
2003

2004
static int mount_get_timeout(Unit *u, usec_t *timeout) {
×
2005
        Mount *m = ASSERT_PTR(MOUNT(u));
×
2006
        usec_t t;
×
2007
        int r;
×
2008

2009
        if (!m->timer_event_source)
×
2010
                return 0;
×
2011

2012
        r = sd_event_source_get_time(m->timer_event_source, &t);
×
2013
        if (r < 0)
×
2014
                return r;
2015
        if (t == USEC_INFINITY)
×
2016
                return 0;
2017

2018
        *timeout = t;
×
2019
        return 1;
×
2020
}
2021

2022
static void mount_enumerate_perpetual(Manager *m) {
274✔
2023
        Unit *u;
274✔
2024
        int r;
274✔
2025

2026
        assert(m);
274✔
2027

2028
        /* Whatever happens, we know for sure that the root directory is around, and cannot go away. Let's
2029
         * unconditionally synthesize it here and mark it as perpetual. */
2030

2031
        u = manager_get_unit(m, SPECIAL_ROOT_MOUNT);
274✔
2032
        if (!u) {
274✔
2033
                r = unit_new_for_name(m, sizeof(Mount), SPECIAL_ROOT_MOUNT, &u);
274✔
2034
                if (r < 0) {
274✔
2035
                        log_error_errno(r, "Failed to allocate the special " SPECIAL_ROOT_MOUNT " unit: %m");
×
2036
                        return;
×
2037
                }
2038
        }
2039

2040
        u->perpetual = true;
274✔
2041
        MOUNT(u)->deserialized_state = MOUNT_MOUNTED;
274✔
2042

2043
        unit_add_to_load_queue(u);
274✔
2044
        unit_add_to_dbus_queue(u);
274✔
2045
}
2046

2047
static bool mount_is_mounted(Mount *m) {
148,996✔
2048
        assert(m);
148,996✔
2049

2050
        return UNIT(m)->perpetual || FLAGS_SET(m->proc_flags, MOUNT_PROC_IS_MOUNTED);
148,996✔
2051
}
2052

2053
static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) {
199✔
2054
        Manager *m = ASSERT_PTR(userdata);
199✔
2055
        Job *j;
199✔
2056

2057
        /* Let's enqueue all start jobs that were previously skipped because of active ratelimit. */
2058
        HASHMAP_FOREACH(j, m->jobs) {
2,596✔
2059
                if (j->unit->type != UNIT_MOUNT)
2,397✔
2060
                        continue;
2,352✔
2061

2062
                job_add_to_run_queue(j);
45✔
2063
        }
2064

2065
        /* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so
2066
         * let's make sure we dispatch them in the next iteration. */
2067
        manager_trigger_run_queue(m);
199✔
2068

2069
        return 0;
199✔
2070
}
2071

2072
static void mount_enumerate(Manager *m) {
274✔
2073
        int r;
274✔
2074

2075
        assert(m);
274✔
2076

2077
        mnt_init_debug(0);
274✔
2078

2079
        if (!m->mount_monitor) {
274✔
2080
                usec_t mount_rate_limit_interval = 1 * USEC_PER_SEC;
248✔
2081
                unsigned mount_rate_limit_burst = 5;
248✔
2082
                int fd;
248✔
2083

2084
                m->mount_monitor = mnt_new_monitor();
248✔
2085
                if (!m->mount_monitor) {
248✔
2086
                        log_oom();
×
2087
                        goto fail;
×
2088
                }
2089

2090
                r = mnt_monitor_enable_kernel(m->mount_monitor, 1);
248✔
2091
                if (r < 0) {
248✔
2092
                        log_error_errno(r, "Failed to enable watching of kernel mount events: %m");
×
2093
                        goto fail;
×
2094
                }
2095

2096
                r = mnt_monitor_enable_userspace(m->mount_monitor, 1, NULL);
248✔
2097
                if (r < 0) {
248✔
2098
                        log_error_errno(r, "Failed to enable watching of userspace mount events: %m");
×
2099
                        goto fail;
×
2100
                }
2101

2102
                /* mnt_unref_monitor() will close the fd */
2103
                fd = r = mnt_monitor_get_fd(m->mount_monitor);
248✔
2104
                if (r < 0) {
248✔
2105
                        log_error_errno(r, "Failed to acquire watch file descriptor: %m");
×
2106
                        goto fail;
×
2107
                }
2108

2109
                r = sd_event_add_io(m->event, &m->mount_event_source, fd, EPOLLIN, mount_dispatch_io, m);
248✔
2110
                if (r < 0) {
248✔
2111
                        log_error_errno(r, "Failed to watch mount file descriptor: %m");
×
2112
                        goto fail;
×
2113
                }
2114

2115
                r = sd_event_source_set_priority(m->mount_event_source, EVENT_PRIORITY_MOUNT_TABLE);
248✔
2116
                if (r < 0) {
248✔
2117
                        log_error_errno(r, "Failed to adjust mount watch priority: %m");
×
2118
                        goto fail;
×
2119
                }
2120

2121
                /* Let users override the default (5 in 1s), as it stalls the boot sequence on busy systems. */
2122
                const char *e = secure_getenv("SYSTEMD_DEFAULT_MOUNT_RATE_LIMIT_INTERVAL_SEC");
248✔
2123
                if (e) {
248✔
2124
                        r = parse_sec(e, &mount_rate_limit_interval);
×
2125
                        if (r < 0)
×
2126
                                log_debug_errno(r, "Invalid value in $SYSTEMD_DEFAULT_MOUNT_RATE_LIMIT_INTERVAL_SEC, ignoring: %s", e);
×
2127
                }
2128

2129
                e = secure_getenv("SYSTEMD_DEFAULT_MOUNT_RATE_LIMIT_BURST");
248✔
2130
                if (e) {
248✔
2131
                        r = safe_atou(e, &mount_rate_limit_burst);
×
2132
                        if (r < 0)
×
2133
                                log_debug_errno(r, "Invalid value in $SYSTEMD_DEFAULT_MOUNT_RATE_LIMIT_BURST, ignoring: %s", e);
×
2134
                }
2135

2136
                r = sd_event_source_set_ratelimit(m->mount_event_source, mount_rate_limit_interval, mount_rate_limit_burst);
248✔
2137
                if (r < 0) {
248✔
2138
                        log_error_errno(r, "Failed to enable rate limit for mount events: %m");
×
2139
                        goto fail;
×
2140
                }
2141

2142
                r = sd_event_source_set_ratelimit_expire_callback(m->mount_event_source, mount_on_ratelimit_expire);
248✔
2143
                if (r < 0) {
248✔
2144
                         log_error_errno(r, "Failed to enable rate limit for mount events: %m");
×
2145
                         goto fail;
×
2146
                }
2147

2148
                (void) sd_event_source_set_description(m->mount_event_source, "mount-monitor-dispatch");
248✔
2149
        }
2150

2151
        r = mount_load_proc_self_mountinfo(m, false);
274✔
2152
        if (r < 0)
274✔
2153
                goto fail;
×
2154

2155
        return;
2156

2157
fail:
×
2158
        mount_shutdown(m);
×
2159
}
2160

2161
static int drain_libmount(Manager *m) {
3,861✔
2162
        bool rescan = false;
3,861✔
2163
        int r;
3,861✔
2164

2165
        assert(m);
3,861✔
2166

2167
        /* Drain all events and verify that the event is valid.
2168
         *
2169
         * Note that libmount also monitors /run/mount mkdir if the directory does not exist yet. The mkdir
2170
         * may generate event which is irrelevant for us.
2171
         *
2172
         * error: r < 0; valid: r == 0, false positive: r == 1 */
2173
        do {
7,555✔
2174
                r = mnt_monitor_next_change(m->mount_monitor, NULL, NULL);
7,555✔
2175
                if (r < 0)
7,555✔
2176
                        return log_error_errno(r, "Failed to drain libmount events: %m");
×
2177
                if (r == 0)
7,555✔
2178
                        rescan = true;
3,694✔
2179
        } while (r == 0);
7,555✔
2180

2181
        return rescan;
3,861✔
2182
}
2183

2184
static int mount_process_proc_self_mountinfo(Manager *m) {
3,861✔
2185
        _cleanup_set_free_ Set *around = NULL, *gone = NULL;
3,861✔
2186
        const char *what;
3,861✔
2187
        int r;
3,861✔
2188

2189
        assert(m);
3,861✔
2190

2191
        r = drain_libmount(m);
3,861✔
2192
        if (r <= 0)
3,861✔
2193
                return r;
2194

2195
        r = mount_load_proc_self_mountinfo(m, true);
3,690✔
2196
        if (r < 0) {
3,690✔
2197
                /* Reset flags, just in case, for later calls */
2198
                LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT])
×
2199
                        MOUNT(u)->proc_flags = 0;
×
2200

2201
                return 0;
2202
        }
2203

2204
        manager_dispatch_load_queue(m);
3,690✔
2205

2206
        LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
78,188✔
2207
                Mount *mount = MOUNT(u);
74,498✔
2208

2209
                if (!mount_is_mounted(mount)) {
74,498✔
2210

2211
                        /* A mount point is not around right now. It might be gone, or might never have
2212
                         * existed. */
2213

2214
                        if (mount->from_proc_self_mountinfo &&
10,286✔
2215
                            mount->parameters_proc_self_mountinfo.what)
1,618✔
2216
                                /* Remember that this device might just have disappeared */
2217
                                if (set_put_strdup_full(&gone, &path_hash_ops_free, mount->parameters_proc_self_mountinfo.what) < 0)
1,618✔
2218
                                        log_oom(); /* we don't care too much about OOM here... */
×
2219

2220
                        mount->from_proc_self_mountinfo = false;
10,286✔
2221
                        assert_se(update_parameters_proc_self_mountinfo(mount, NULL, NULL, NULL) >= 0);
10,286✔
2222

2223
                        switch (mount->state) {
10,286✔
2224

2225
                        case MOUNT_MOUNTED:
1,579✔
2226
                                /* This has just been unmounted by somebody else, follow the state change.
2227
                                 * Also explicitly override the result (see the comment in mount_sigchld_event()),
2228
                                 * but more aggressively here since the state change is extrinsic. */
2229
                                mount_cycle_clear(mount);
1,579✔
2230
                                mount_enter_dead(mount, MOUNT_SUCCESS, /* flush_result = */ true);
1,579✔
2231
                                break;
2232

2233
                        case MOUNT_MOUNTING_DONE:
×
2234
                                /* The mount command may add the corresponding proc mountinfo entry and
2235
                                 * then remove it because of an internal error. E.g., fuse.sshfs seems
2236
                                 * to do that when the connection fails. See #17617. To handle such the
2237
                                 * case, let's once set the state back to mounting. Then, the unit can
2238
                                 * correctly enter the failed state later in mount_sigchld_event(). */
2239
                                mount_set_state(mount, MOUNT_MOUNTING);
×
2240
                                break;
2241

2242
                        default:
2243
                                ;
2244
                        }
2245

2246
                } else if (mount->proc_flags & (MOUNT_PROC_JUST_MOUNTED|MOUNT_PROC_JUST_CHANGED)) {
64,212✔
2247

2248
                        /* A mount point was added or changed */
2249

2250
                        switch (mount->state) {
1,808✔
2251

2252
                        case MOUNT_DEAD:
1,597✔
2253
                        case MOUNT_FAILED:
2254

2255
                                /* This has just been mounted by somebody else, follow the state change, but let's
2256
                                 * generate a new invocation ID for this implicitly and automatically. */
2257
                                (void) unit_acquire_invocation_id(u);
1,597✔
2258
                                mount_cycle_clear(mount);
1,597✔
2259
                                mount_enter_mounted(mount, MOUNT_SUCCESS);
1,597✔
2260
                                break;
2261

2262
                        case MOUNT_MOUNTING:
129✔
2263
                                mount_set_state(mount, MOUNT_MOUNTING_DONE);
129✔
2264
                                break;
2265

2266
                        default:
82✔
2267
                                /* Nothing really changed, but let's issue an notification call nonetheless,
2268
                                 * in case somebody is waiting for this. (e.g. file system ro/rw
2269
                                 * remounts.) */
2270
                                mount_set_state(mount, mount->state);
82✔
2271
                        }
2272
                }
2273

2274
                if (mount_is_mounted(mount) &&
74,498✔
2275
                    mount->from_proc_self_mountinfo &&
64,212✔
2276
                    mount->parameters_proc_self_mountinfo.what)
64,212✔
2277
                        /* Track devices currently used */
2278
                        if (set_put_strdup_full(&around, &path_hash_ops_free, mount->parameters_proc_self_mountinfo.what) < 0)
64,212✔
2279
                                log_oom();
×
2280

2281
                /* Reset the flags for later calls */
2282
                mount->proc_flags = 0;
74,498✔
2283
        }
2284

2285
        SET_FOREACH(what, gone) {
5,245✔
2286
                if (set_contains(around, what))
1,555✔
2287
                        continue;
1,354✔
2288

2289
                /* Let the device units know that the device is no longer mounted */
2290
                device_found_node(m, what, DEVICE_NOT_FOUND, DEVICE_FOUND_MOUNT);
201✔
2291
        }
2292

2293
        return 0;
3,690✔
2294
}
2295

2296
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
3,688✔
2297
        Manager *m = ASSERT_PTR(userdata);
3,688✔
2298

2299
        assert(revents & EPOLLIN);
3,688✔
2300

2301
        return mount_process_proc_self_mountinfo(m);
3,688✔
2302
}
2303

2304
static void mount_reset_failed(Unit *u) {
27✔
2305
        Mount *m = MOUNT(u);
27✔
2306

2307
        assert(m);
×
2308

2309
        if (m->state == MOUNT_FAILED)
27✔
2310
                mount_set_state(m, MOUNT_DEAD);
×
2311

2312
        m->result = MOUNT_SUCCESS;
27✔
2313
        m->reload_result = MOUNT_SUCCESS;
27✔
2314
        m->clean_result = MOUNT_SUCCESS;
27✔
2315
}
27✔
2316

2317
static PidRef* mount_control_pid(Unit *u) {
×
2318
        return &ASSERT_PTR(MOUNT(u))->control_pid;
×
2319
}
2320

2321
static int mount_clean(Unit *u, ExecCleanMask mask) {
×
2322
        _cleanup_strv_free_ char **l = NULL;
×
2323
        Mount *m = MOUNT(u);
×
2324
        int r;
×
2325

2326
        assert(m);
×
2327
        assert(mask != 0);
×
2328

2329
        if (m->state != MOUNT_DEAD)
×
2330
                return -EBUSY;
2331

2332
        r = exec_context_get_clean_directories(&m->exec_context, u->manager->prefix, mask, &l);
×
2333
        if (r < 0)
×
2334
                return r;
2335

2336
        if (strv_isempty(l))
×
2337
                return -EUNATCH;
2338

2339
        mount_unwatch_control_pid(m);
×
2340
        m->clean_result = MOUNT_SUCCESS;
×
2341
        m->control_command = NULL;
×
2342
        m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
×
2343

2344
        r = mount_arm_timer(m, /* relative= */ true, m->exec_context.timeout_clean_usec);
×
2345
        if (r < 0) {
×
2346
                log_unit_warning_errno(u, r, "Failed to install timer: %m");
×
2347
                goto fail;
×
2348
        }
2349

2350
        r = unit_fork_and_watch_rm_rf(u, l, &m->control_pid);
×
2351
        if (r < 0) {
×
2352
                log_unit_warning_errno(u, r, "Failed to spawn cleaning task: %m");
×
2353
                goto fail;
×
2354
        }
2355

2356
        mount_set_state(m, MOUNT_CLEANING);
×
2357
        return 0;
2358

2359
fail:
×
2360
        m->clean_result = MOUNT_FAILURE_RESOURCES;
×
2361
        m->timer_event_source = sd_event_source_disable_unref(m->timer_event_source);
×
2362
        return r;
×
2363
}
2364

2365
static int mount_can_clean(Unit *u, ExecCleanMask *ret) {
75✔
2366
        Mount *m = ASSERT_PTR(MOUNT(u));
75✔
2367

2368
        return exec_context_get_clean_mask(&m->exec_context, ret);
75✔
2369
}
2370

2371
static int mount_can_start(Unit *u) {
134✔
2372
        Mount *m = ASSERT_PTR(MOUNT(u));
134✔
2373
        int r;
134✔
2374

2375
        r = unit_test_start_limit(u);
134✔
2376
        if (r < 0) {
134✔
2377
                mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT, /* flush_result = */ false);
×
2378
                return r;
×
2379
        }
2380

2381
        if (!get_mount_parameters_fragment(m))
134✔
2382
                return -ENOENT;
×
2383

2384
        return 1;
2385
}
2386

2387
static int mount_subsystem_ratelimited(Manager *m) {
255✔
2388
        assert(m);
255✔
2389

2390
        if (!m->mount_event_source)
255✔
2391
                return false;
2392

2393
        return sd_event_source_is_ratelimited(m->mount_event_source);
255✔
2394
}
2395

2396
char* mount_get_what_escaped(const Mount *m) {
1,456✔
2397
        _cleanup_free_ char *escaped = NULL;
2,912✔
2398
        const char *s = NULL;
1,456✔
2399

2400
        assert(m);
1,456✔
2401

2402
        if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
1,456✔
2403
                s = m->parameters_proc_self_mountinfo.what;
2404
        else if (m->from_fragment && m->parameters_fragment.what)
275✔
2405
                s = m->parameters_fragment.what;
2406

2407
        if (s) {
1,326✔
2408
                escaped = utf8_escape_invalid(s);
1,326✔
2409
                if (!escaped)
1,326✔
2410
                        return NULL;
×
2411
        }
2412

2413
        return escaped ? TAKE_PTR(escaped) : strdup("");
130✔
2414
}
2415

2416
char* mount_get_options_escaped(const Mount *m) {
1,456✔
2417
        const char *s = NULL;
1,456✔
2418

2419
        assert(m);
1,456✔
2420

2421
        if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options)
1,456✔
2422
                s = m->parameters_proc_self_mountinfo.options;
2423
        else if (m->from_fragment && m->parameters_fragment.options)
275✔
2424
                s = m->parameters_fragment.options;
2425
        if (!s)
1,238✔
2426
                return strdup("");
218✔
2427

2428
        return utf8_escape_invalid(s);
1,238✔
2429
}
2430

2431
const char* mount_get_fstype(const Mount *m) {
1,456✔
2432
        assert(m);
1,456✔
2433

2434
        if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype)
1,456✔
2435
                return m->parameters_proc_self_mountinfo.fstype;
2436

2437
        if (m->from_fragment && m->parameters_fragment.fstype)
275✔
2438
                return m->parameters_fragment.fstype;
124✔
2439

2440
        return NULL;
2441
}
2442

2443
static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
2444
        [MOUNT_EXEC_MOUNT]   = "ExecMount",
2445
        [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
2446
        [MOUNT_EXEC_REMOUNT] = "ExecRemount",
2447
};
2448

2449
DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
239✔
2450

2451
static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
2452
        [MOUNT_SUCCESS]                 = "success",
2453
        [MOUNT_FAILURE_RESOURCES]       = "resources",
2454
        [MOUNT_FAILURE_TIMEOUT]         = "timeout",
2455
        [MOUNT_FAILURE_EXIT_CODE]       = "exit-code",
2456
        [MOUNT_FAILURE_SIGNAL]          = "signal",
2457
        [MOUNT_FAILURE_CORE_DUMP]       = "core-dump",
2458
        [MOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
2459
        [MOUNT_FAILURE_PROTOCOL]        = "protocol",
2460
};
2461

2462
DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
11,604✔
2463

2464
const UnitVTable mount_vtable = {
2465
        .object_size = sizeof(Mount),
2466
        .exec_context_offset = offsetof(Mount, exec_context),
2467
        .cgroup_context_offset = offsetof(Mount, cgroup_context),
2468
        .kill_context_offset = offsetof(Mount, kill_context),
2469
        .exec_runtime_offset = offsetof(Mount, exec_runtime),
2470
        .cgroup_runtime_offset = offsetof(Mount, cgroup_runtime),
2471

2472
        .sections =
2473
                "Unit\0"
2474
                "Mount\0"
2475
                "Install\0",
2476
        .private_section = "Mount",
2477

2478
        .can_transient = true,
2479
        .can_fail = true,
2480
        .exclude_from_switch_root_serialization = true,
2481

2482
        .init = mount_init,
2483
        .load = mount_load,
2484
        .done = mount_done,
2485

2486
        .coldplug = mount_coldplug,
2487
        .catchup = mount_catchup,
2488

2489
        .dump = mount_dump,
2490

2491
        .start = mount_start,
2492
        .stop = mount_stop,
2493

2494
        .reload = mount_reload,
2495
        .can_reload = mount_can_reload,
2496

2497
        .clean = mount_clean,
2498
        .can_clean = mount_can_clean,
2499

2500
        .serialize = mount_serialize,
2501
        .deserialize_item = mount_deserialize_item,
2502

2503
        .active_state = mount_active_state,
2504
        .sub_state_to_string = mount_sub_state_to_string,
2505

2506
        .will_restart = unit_will_restart_default,
2507

2508
        .may_gc = mount_may_gc,
2509
        .is_extrinsic = mount_is_extrinsic,
2510

2511
        .sigchld_event = mount_sigchld_event,
2512

2513
        .reset_failed = mount_reset_failed,
2514

2515
        .notify_handoff_timestamp = mount_handoff_timestamp,
2516

2517
        .control_pid = mount_control_pid,
2518

2519
        .bus_set_property = bus_mount_set_property,
2520
        .bus_commit_properties = bus_mount_commit_properties,
2521

2522
        .get_timeout = mount_get_timeout,
2523

2524
        .enumerate_perpetual = mount_enumerate_perpetual,
2525
        .enumerate = mount_enumerate,
2526
        .shutdown = mount_shutdown,
2527
        .subsystem_ratelimited = mount_subsystem_ratelimited,
2528

2529
        .status_message_formats = {
2530
                .starting_stopping = {
2531
                        [0] = "Mounting %s...",
2532
                        [1] = "Unmounting %s...",
2533
                },
2534
                .finished_start_job = {
2535
                        [JOB_DONE]       = "Mounted %s.",
2536
                        [JOB_FAILED]     = "Failed to mount %s.",
2537
                        [JOB_TIMEOUT]    = "Timed out mounting %s.",
2538
                },
2539
                .finished_stop_job = {
2540
                        [JOB_DONE]       = "Unmounted %s.",
2541
                        [JOB_FAILED]     = "Failed unmounting %s.",
2542
                        [JOB_TIMEOUT]    = "Timed out unmounting %s.",
2543
                },
2544
        },
2545

2546
        .can_start = mount_can_start,
2547

2548
        .notify_plymouth = true,
2549
};
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