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

systemd / systemd / 13424846548

19 Feb 2025 10:09PM UTC coverage: 71.768% (+0.02%) from 71.753%
13424846548

push

github

web-flow
tree-wide: tweaks to mount point inode creation (#36308)

Some love for make_mount_point_inode_from_xyz() and ports PID 1 over to
it for mount units.

Alternative to #36290

58 of 91 new or added lines in 7 files covered. (63.74%)

1322 existing lines in 48 files now uncovered.

293681 of 409206 relevant lines covered (71.77%)

717000.31 hits per line

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

71.6
/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-setup.h"
27
#include "mount.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-name.h"
39
#include "unit.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) {
7,676✔
67
        return IN_SET(state,
7,676✔
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) {
25,186✔
80
        assert(m);
25,186✔
81

82
        if (m->from_fragment)
25,186✔
83
                return &m->parameters_fragment;
8,522✔
84

85
        return NULL;
86
}
87

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

91
        if (m->from_proc_self_mountinfo)
19,418✔
92
                return &m->parameters_proc_self_mountinfo;
14,754✔
93

94
        return get_mount_parameters_fragment(m);
4,664✔
95
}
96

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

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

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

106
        return false;
107
}
108

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

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

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

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

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

124
        return false;
125
}
126

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

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

137
        assert(m);
748✔
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);
748✔
145
        if (!p)
748✔
146
                return false;
147

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

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

157
        return parse_boolean(value);
×
158
}
159

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

163
        assert(m);
374✔
164

165
        r = mount_is_bound_to_device(m);
374✔
166
        if (r >= 0)
374✔
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)
374✔
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,
374✔
174
                                  * otherwise let's not bother. */
175
}
176

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

180
        assert(u->load_state == UNIT_STUB);
26,790✔
181

182
        m->timeout_usec = u->manager->defaults.timeout_start_usec;
26,790✔
183

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

187
        m->directory_mode = 0755;
26,790✔
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;
26,790✔
194

195
        m->control_pid = PIDREF_NULL;
26,790✔
196
        m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
26,790✔
197

198
        u->ignore_on_isolate = true;
26,790✔
199
}
26,790✔
200

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

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

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

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

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

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

223
        m->where = mfree(m->where);
26,790✔
224

225
        mount_parameters_done(&m->parameters_proc_self_mountinfo);
26,790✔
226
        mount_parameters_done(&m->parameters_fragment);
26,790✔
227

228
        m->exec_runtime = exec_runtime_free(m->exec_runtime);
26,790✔
229

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

233
        mount_unwatch_control_pid(m);
26,790✔
234

235
        m->timer_event_source = sd_event_source_disable_unref(m->timer_event_source);
26,790✔
236
}
26,790✔
237

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

244
        MountParameters *p;
61,640✔
245
        int r, q, w;
61,640✔
246

247
        assert(m);
61,640✔
248

249
        p = &m->parameters_proc_self_mountinfo;
61,640✔
250

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

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

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

263
        return r > 0 || q > 0 || w > 0;
61,640✔
264
}
265

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

270
        assert(m);
12,992✔
271

272
        if (!path_equal(m->where, "/")) {
12,992✔
273
                _cleanup_free_ char *parent = NULL;
12,329✔
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);
12,329✔
278
                if (r < 0)
12,329✔
279
                        return r;
280

281
                r = unit_add_mounts_for(UNIT(m), parent, UNIT_DEPENDENCY_IMPLICIT, UNIT_MOUNT_REQUIRES);
12,329✔
282
                if (r < 0)
12,329✔
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);
12,992✔
289
        if (pm && pm->what &&
12,992✔
290
            path_is_absolute(pm->what) &&
2,612✔
291
            (mount_is_bind(pm) || mount_is_loop(pm) || !mount_is_network(pm))) {
672✔
292

293
                r = unit_add_mounts_for(UNIT(m), pm->what, UNIT_DEPENDENCY_FILE, UNIT_MOUNT_REQUIRES);
336✔
294
                if (r < 0)
336✔
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) {
38,976✔
300
                Unit *other;
25,984✔
301
                Set *s = manager_get_units_needing_mounts_for(UNIT(m)->manager, m->where, t);
25,984✔
302

303
                SET_FOREACH(other, s) {
40,745✔
304
                        if (other->load_state != UNIT_LOADED)
14,761✔
305
                                continue;
76✔
306

307
                        if (other == UNIT(m))
29,370✔
308
                                continue;
161✔
309

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

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

333
        return 0;
334
}
335

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

342
        assert(m);
12,992✔
343

344
        log_unit_trace(UNIT(m), "Processing implicit device dependencies");
12,992✔
345

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

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

357
        if (mount_is_bind(p)) {
12,005✔
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)) {
12,005✔
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")) {
518✔
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, "/")) {
518✔
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;
374✔
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;
374✔
388

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

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

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

408
        return 0;
374✔
409
}
410

411
static bool mount_is_extrinsic(Unit *u) {
16,853✔
412
        Mount *m = ASSERT_PTR(MOUNT(u));
16,853✔
413
        MountParameters *p;
16,853✔
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))
16,853✔
422
                return true;
423

424
        p = get_mount_parameters(m);
4,735✔
425
        if (p && fstab_is_extrinsic(m->where, p->options))
4,735✔
426
                return true;
3,310✔
427

428
        return false;
429
}
430

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

435
        assert(m);
766✔
436

437
        e = path_startswith(m->where, "/sysroot");
766✔
438
        if (e && in_initrd()) {
766✔
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;
122✔
447
                before = isempty(e) ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_INITRD_FS_TARGET;
122✔
448

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

453
        } else if (mount_is_network(p)) {
644✔
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)) {
766✔
463
                r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, before, /* add_reference= */ true, mask);
759✔
464
                if (r < 0)
759✔
465
                        return r;
466
        }
467

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

474
        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET,
766✔
475
                                              /* add_reference= */ true, mask);
476
        if (r < 0)
766✔
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")) {
766✔
481
                r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_SWAP_TARGET,
290✔
482
                                                /* add_reference= */ true, mask);
483
                if (r < 0)
290✔
484
                        return r;
×
485
        }
486

487
        return 0;
488
}
489

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

493
        assert(m);
766✔
494

495
        if (!mount_is_network(p))
766✔
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) {
12,992✔
516
        UnitDependencyMask mask;
12,992✔
517
        MountParameters *p;
12,992✔
518
        int r;
12,992✔
519

520
        assert(m);
12,992✔
521

522
        if (!UNIT(m)->default_dependencies)
12,992✔
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)))
21,468✔
530
                return 0;
531

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

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

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

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

546
        return 0;
547
}
548

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

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

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

560
        r = unit_name_from_path(m->where, ".mount", &e);
6,389✔
561
        if (r < 0)
6,389✔
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))
12,778✔
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))
6,389✔
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))
6,389✔
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);
6,389✔
576
        if (p && !p->what && !UNIT(m)->perpetual)
6,389✔
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) {
12,992✔
583
        int r;
12,992✔
584

585
        assert(m);
12,992✔
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);
12,992✔
591

592
        if (!m->where)
12,992✔
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);
12,992✔
599
        if (r < 0)
12,992✔
600
                return r;
601

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

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

610
        return 0;
611
}
612

613
static int mount_add_extras(Mount *m) {
6,389✔
614
        Unit *u = UNIT(ASSERT_PTR(m));
6,389✔
615
        int r;
6,389✔
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)
6,389✔
622
                m->from_fragment = true;
1,566✔
623

624
        if (!m->where) {
6,389✔
625
                r = unit_name_to_path(u->id, &m->where);
93✔
626
                if (r == -ENAMETOOLONG)
93✔
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)
93✔
630
                        return r;
631
        }
632

633
        path_simplify(m->where);
6,389✔
634

635
        if (!u->description) {
6,389✔
636
                r = unit_set_description(u, m->where);
4,545✔
637
                if (r < 0)
4,545✔
638
                        return r;
639
        }
640

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

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

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

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

657
        return 0;
658
}
659

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

663
        if (!unit_has_name(u, SPECIAL_ROOT_MOUNT))
26,790✔
664
                return;
665

666
        u->perpetual = true;
378✔
667
        u->default_dependencies = false;
378✔
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;
378✔
671
        m->exec_context.std_input = EXEC_INPUT_NULL;
378✔
672

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

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

681
        assert(u->load_state == UNIT_STUB);
26,790✔
682

683
        mount_load_root_mount(u);
26,790✔
684

685
        bool from_kernel = m->from_proc_self_mountinfo || u->perpetual;
26,790✔
686

687
        r = unit_load_fragment_and_dropin(u, /* fragment_required = */ !from_kernel);
26,790✔
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)
26,790✔
694
                RET_GATHER(r, mount_add_extras(m));
6,389✔
695

696
        if (r < 0)
26,790✔
697
                return r;
20,401✔
698

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

702
        return mount_verify(m);
6,389✔
703
}
704

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

708
        assert(m);
7,672✔
709

710
        if (m->state != state)
7,672✔
711
                bus_unit_send_pending_change_signal(UNIT(m), false);
7,645✔
712

713
        old_state = m->state;
7,672✔
714
        m->state = state;
7,672✔
715

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

723
        if (state != old_state)
7,672✔
724
                log_unit_debug(UNIT(m), "Changed %s -> %s", mount_state_to_string(old_state), mount_state_to_string(state));
15,157✔
725

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

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

733
        assert(m->state == MOUNT_DEAD);
17,307✔
734

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

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

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

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

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

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

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

761
        /* Adjust the deserialized state. See comments in mount_process_proc_self_mountinfo(). */
762
        if (m->from_proc_self_mountinfo)
17,307✔
763
                switch (m->state) {
4,189✔
764
                case MOUNT_DEAD:
765
                case MOUNT_FAILED:
766
                        assert(!pidref_is_set(&m->control_pid));
3,096✔
767
                        (void) unit_acquire_invocation_id(u);
3,096✔
768
                        mount_cycle_clear(m);
3,096✔
769
                        mount_enter_mounted(m, MOUNT_SUCCESS);
3,096✔
770
                        break;
3,096✔
771
                case MOUNT_MOUNTING:
772
                        assert(pidref_is_set(&m->control_pid));
3✔
773
                        mount_set_state(m, MOUNT_MOUNTING_DONE);
3✔
774
                        break;
3✔
775
                default:
776
                        break;
777
                }
778
        else
779
                switch (m->state) {
13,118✔
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:
789
                        break;
790
                }
791
}
17,307✔
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, special_glyph(SPECIAL_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) {
570✔
860
        ExecFlags flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN;
570✔
861

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

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

867
        return flags;
570✔
868
}
869

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

927
        unit_unref_uid_gid(UNIT(m), true);
923✔
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);
923✔
932
}
923✔
933

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

937
        if (m->result == MOUNT_SUCCESS)
4,527✔
938
                m->result = f;
4,527✔
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);
4,527✔
947

948
        mount_set_state(m, MOUNT_MOUNTED);
4,527✔
949
}
4,527✔
950

951
static void mount_enter_dead_or_mounted(Mount *m, MountResult f, bool flush_result) {
38✔
952
        assert(m);
38✔
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)
38✔
962
                mount_enter_mounted(m, f);
×
963
        else
964
                mount_enter_dead(m, f, flush_result);
38✔
965
}
38✔
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) {
38✔
1023
        int r;
38✔
1024

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

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

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

1038
        if (m->force_unmount) {
38✔
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) {
38✔
1048
        int r;
38✔
1049

1050
        assert(m);
38✔
1051

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

1059
        mount_unwatch_control_pid(m);
38✔
1060

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

1064
        r = mount_set_umount_command(m, m->control_command);
38✔
1065
        if (r < 0) {
38✔
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);
38✔
1071
        if (r < 0) {
38✔
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);
38✔
1077
        return;
38✔
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) {
532✔
1084
        _cleanup_strv_free_ char **graceful = NULL;
×
1085
        _cleanup_free_ char *filtered = NULL;
532✔
1086
        int r;
532✔
1087

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

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

1096
        if (!p->fstype) {
67✔
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) {
134✔
1102
                _cleanup_free_ char *k = NULL, *v = NULL;
67✔
1103

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

1108
                r = mount_option_supported(p->fstype, k ?: *o, v);
67✔
1109
                if (r == -EAGAIN) {
67✔
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)
67✔
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)
67✔
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);
134✔
1122

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

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

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

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

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

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

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

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

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

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

1169
        if (remount) {
532✔
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)) {
1,053✔
1179
                r = exec_command_append(c, "-o", opts, NULL);
521✔
1180
                if (r < 0)
521✔
1181
                        return r;
×
1182
        }
1183

1184
        return 0;
1185
}
1186

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

1192
        assert(m);
532✔
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);
532✔
1198
        if (fd == -EREMCHG) {
532✔
NEW
1199
                r = unit_log_noncanonical_mount_path(UNIT(m), m->where);
×
NEW
1200
                goto fail;
×
1201
        }
1202
        if (fd < 0) {
532✔
NEW
1203
                log_unit_error_errno(UNIT(m), fd, "Failed to resolve parent of mount point '%s': %m", m->where);
×
UNCOV
1204
                goto fail;
×
1205
        }
1206

1207
        MountParameters *p = get_mount_parameters_fragment(m);
532✔
1208
        if (!p) {
532✔
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;
532✔
1214
        if (mount_is_bind(p)) {
532✔
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(
532✔
1223
                        fd,
1224
                        fn,
1225
                        source_is_dir ? S_IFDIR : S_IFREG,
1226
                        m->directory_mode);
1227
        if (r < 0 && r != -EEXIST)
532✔
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")) {
532✔
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)
532✔
1259
                unit_warn_if_dir_nonempty(UNIT(m), m->where);
532✔
1260

1261
        /* Create the source directory for bind-mounts if needed */
1262
        if (mount_is_bind(p)) {
532✔
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);
532✔
1275
        unit_warn_leftover_processes(UNIT(m), /* start = */ true);
532✔
1276

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

1280
        r = mount_set_mount_command(m, m->control_command, p, /* remount = */ false);
532✔
1281
        if (r < 0) {
532✔
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);
532✔
1287
        if (r < 0) {
532✔
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);
532✔
1293
        return;
532✔
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) {
5,413✔
1348
        assert(m);
5,413✔
1349

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

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

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

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

1364
        /* We cannot fulfill this request right now, try again later
1365
         * please! */
1366
        if (IN_SET(m->state,
532✔
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))
532✔
1375
                return 0;
1376

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

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

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

1386
        return 1;
532✔
1387
}
1388

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

1392
        switch (m->state) {
38✔
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:
38✔
1418
                mount_enter_unmounting(m);
38✔
1419
                return 1;
38✔
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) {
77✔
1442
        Mount *m = ASSERT_PTR(MOUNT(u));
77✔
1443

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

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

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

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

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

1462
        return 0;
1,364✔
1463
}
1464

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1524
        return 0;
4,588✔
1525
}
1526

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

1530
        return state_translation_table[m->state];
377,013✔
1531
}
1532

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

1536
        return mount_state_to_string(m->state);
2,075✔
1537
}
1538

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

1542
        if (m->from_proc_self_mountinfo)
50,282✔
1543
                return false;
4,222✔
1544

1545
        return true;
1546
}
1547

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

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

1554
        if (pid != m->control_pid.pid)
569✔
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);
569✔
1572

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

1575
        if (is_clean_exit(code, status, EXIT_CLEAN_COMMAND, NULL))
569✔
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))
569✔
1587
                mount_set_reload_result(m, f);
×
1588
        else if (m->result == MOUNT_SUCCESS && !IN_SET(m->state, MOUNT_MOUNTING, MOUNT_UNMOUNTING))
569✔
1589
                /* MOUNT_MOUNTING and MOUNT_UNMOUNTING states need to be patched, see below. */
1590
                m->result = f;
531✔
1591

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

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

1599
        unit_log_process_exit(
569✔
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) {
569✔
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:
531✔
1624
                mount_enter_mounted(m, f);
531✔
1625
                break;
531✔
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:
38✔
1634
                if (f == MOUNT_SUCCESS && m->from_proc_self_mountinfo) {
38✔
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) {
38✔
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);
38✔
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);
569✔
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(
4,599✔
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;
4,599✔
1767
        Mount *mnt;
4,599✔
1768
        int r;
4,599✔
1769

1770
        assert(m);
4,599✔
1771
        assert(name);
4,599✔
1772
        assert(ret_flags);
4,599✔
1773
        assert(ret);
4,599✔
1774

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

1779
        mnt = ASSERT_PTR(MOUNT(u));
4,599✔
1780

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

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

1789
        r = update_parameters_proc_self_mountinfo(mnt, what, options, fstype);
4,599✔
1790
        if (r < 0)
4,599✔
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;
4,599✔
1797

1798
        r = mount_add_non_exec_dependencies(mnt);
4,599✔
1799
        if (r < 0)
4,599✔
1800
                return r;
1801

1802
        /* We have only allocated the stub now, let's enqueue this unit for loading now, so that everything
1803
         * else is loaded in now. */
1804
        unit_add_to_load_queue(u);
4,599✔
1805

1806
        *ret_flags = MOUNT_PROC_IS_MOUNTED | MOUNT_PROC_JUST_MOUNTED | MOUNT_PROC_JUST_CHANGED;
4,599✔
1807
        *ret = TAKE_PTR(u);
4,599✔
1808
        return 0;
4,599✔
1809
}
1810

1811
static int mount_setup_existing_unit(
46,471✔
1812
                Unit *u,
1813
                const char *what,
1814
                const char *where,
1815
                const char *options,
1816
                const char *fstype,
1817
                MountProcFlags *ret_flags) {
1818

1819
        Mount *m = ASSERT_PTR(MOUNT(u));
46,471✔
1820
        int r;
46,471✔
1821

1822
        assert(u);
46,471✔
1823
        assert(where);
46,471✔
1824
        assert(ret_flags);
46,471✔
1825

1826
        if (!m->where) {
46,471✔
1827
                m->where = strdup(where);
337✔
1828
                if (!m->where)
337✔
1829
                        return -ENOMEM;
1830
        }
1831

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

1838
        r = update_parameters_proc_self_mountinfo(m, what, options, fstype);
46,471✔
1839
        if (r < 0)
46,471✔
1840
                return r;
1841
        if (r > 0)
46,471✔
1842
                flags |= MOUNT_PROC_JUST_CHANGED;
1,055✔
1843

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

1854
        m->from_proc_self_mountinfo = true;
46,471✔
1855

1856
        if (UNIT_IS_LOAD_ERROR(u->load_state)) {
46,471✔
1857
                /* The unit was previously not found or otherwise not loaded. Now that the unit shows up in
1858
                 * /proc/self/mountinfo we should reconsider it this, hence set it to UNIT_LOADED. */
1859
                u->load_state = UNIT_LOADED;
52✔
1860
                u->load_error = 0;
52✔
1861

1862
                flags |= MOUNT_PROC_JUST_CHANGED;
52✔
1863
        }
1864

1865
        if (FLAGS_SET(flags, MOUNT_PROC_JUST_CHANGED)) {
46,471✔
1866
                /* If things changed, then make sure that all deps are regenerated. Let's
1867
                 * first remove all automatic deps, and then add in the new ones. */
1868
                r = mount_add_non_exec_dependencies(m);
1,081✔
1869
                if (r < 0)
1,081✔
1870
                        return r;
1871
        }
1872

1873
        *ret_flags = flags;
46,471✔
1874
        return 0;
46,471✔
1875
}
1876

1877
static int mount_setup_unit(
100,790✔
1878
                Manager *m,
1879
                const char *what,
1880
                const char *where,
1881
                const char *options,
1882
                const char *fstype,
1883
                bool set_flags) {
1884

1885
        _cleanup_free_ char *e = NULL;
100,790✔
1886
        MountProcFlags flags;
100,790✔
1887
        Unit *u;
100,790✔
1888
        int r;
100,790✔
1889

1890
        assert(m);
100,790✔
1891
        assert(what);
100,790✔
1892
        assert(where);
100,790✔
1893
        assert(options);
100,790✔
1894
        assert(fstype);
100,790✔
1895

1896
        /* Ignore API and credential mount points. They should never be referenced in dependencies ever.
1897
         * Furthermore, the lifetime of credential mounts is strictly bound to the owning services,
1898
         * so mount units make little sense for them. */
1899
        if (mount_point_is_api(where) || mount_point_ignore(where) ||
160,420✔
1900
            mount_point_is_credentials(m->prefix[EXEC_DIRECTORY_RUNTIME], where))
59,630✔
1901
                return 0;
46,228✔
1902

1903
        if (streq(fstype, "autofs"))
54,562✔
1904
                return 0;
1905

1906
        /* probably some kind of swap, ignore */
1907
        if (!is_path(where))
51,070✔
1908
                return 0;
1909

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

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

1929
        /* If the mount changed properties or state, let's notify our clients */
1930
        if (flags & (MOUNT_PROC_JUST_CHANGED|MOUNT_PROC_JUST_MOUNTED))
51,070✔
1931
                unit_add_to_dbus_queue(u);
5,680✔
1932

1933
        if (set_flags)
51,070✔
1934
                MOUNT(u)->proc_flags = flags;
93,456✔
1935

1936
        return 0;
1937
}
1938

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

1945
        assert(m);
3,362✔
1946

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

1951
        for (;;) {
104,152✔
1952
                struct libmnt_fs *fs;
104,152✔
1953
                const char *device, *path, *options, *fstype;
104,152✔
1954

1955
                r = mnt_table_next_fs(table, iter, &fs);
104,152✔
1956
                if (r == 1)
104,152✔
1957
                        break;
1958
                if (r < 0)
100,790✔
1959
                        return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
×
1960

1961
                device = mnt_fs_get_source(fs);
100,790✔
1962
                path = mnt_fs_get_target(fs);
100,790✔
1963
                options = mnt_fs_get_options(fs);
100,790✔
1964
                fstype = mnt_fs_get_fstype(fs);
100,790✔
1965

1966
                if (!device || !path)
100,790✔
1967
                        continue;
×
1968

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

1975
                (void) mount_setup_unit(m, device, path, options, fstype, set_flags);
100,790✔
1976
        }
1977

1978
        return 0;
3,362✔
1979
}
1980

1981
static void mount_shutdown(Manager *m) {
611✔
1982
        assert(m);
611✔
1983

1984
        m->mount_event_source = sd_event_source_disable_unref(m->mount_event_source);
611✔
1985

1986
        mnt_unref_monitor(m->mount_monitor);
611✔
1987
        m->mount_monitor = NULL;
611✔
1988
}
611✔
1989

1990
static void mount_handoff_timestamp(
1,140✔
1991
                Unit *u,
1992
                const struct ucred *ucred,
1993
                const dual_timestamp *ts) {
1994

1995
        Mount *m = ASSERT_PTR(MOUNT(u));
1,140✔
1996

1997
        assert(ucred);
1,140✔
1998
        assert(ts);
1,140✔
1999

2000
        if (m->control_pid.pid == ucred->pid && m->control_command) {
1,140✔
2001
                exec_status_handoff(&m->control_command->exec_status, ucred, ts);
1,140✔
2002
                unit_add_to_dbus_queue(u);
1,140✔
2003
        }
2004
}
1,140✔
2005

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

2011
        if (!m->timer_event_source)
×
2012
                return 0;
×
2013

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

2020
        *timeout = t;
×
2021
        return 1;
×
2022
}
2023

2024
static void mount_enumerate_perpetual(Manager *m) {
285✔
2025
        Unit *u;
285✔
2026
        int r;
285✔
2027

2028
        assert(m);
285✔
2029

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

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

2042
        u->perpetual = true;
285✔
2043
        MOUNT(u)->deserialized_state = MOUNT_MOUNTED;
285✔
2044

2045
        unit_add_to_load_queue(u);
285✔
2046
        unit_add_to_dbus_queue(u);
285✔
2047
}
2048

2049
static bool mount_is_mounted(Mount *m) {
112,696✔
2050
        assert(m);
112,696✔
2051

2052
        return UNIT(m)->perpetual || FLAGS_SET(m->proc_flags, MOUNT_PROC_IS_MOUNTED);
112,696✔
2053
}
2054

2055
static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) {
181✔
2056
        Manager *m = ASSERT_PTR(userdata);
181✔
2057
        Job *j;
181✔
2058

2059
        /* Let's enqueue all start jobs that were previously skipped because of active ratelimit. */
2060
        HASHMAP_FOREACH(j, m->jobs) {
5,207✔
2061
                if (j->unit->type != UNIT_MOUNT)
5,026✔
2062
                        continue;
4,858✔
2063

2064
                job_add_to_run_queue(j);
168✔
2065
        }
2066

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

2071
        return 0;
181✔
2072
}
2073

2074
static void mount_enumerate(Manager *m) {
285✔
2075
        int r;
285✔
2076

2077
        assert(m);
285✔
2078

2079
        mnt_init_debug(0);
285✔
2080

2081
        if (!m->mount_monitor) {
285✔
2082
                usec_t mount_rate_limit_interval = 1 * USEC_PER_SEC;
261✔
2083
                unsigned mount_rate_limit_burst = 5;
261✔
2084
                int fd;
261✔
2085

2086
                m->mount_monitor = mnt_new_monitor();
261✔
2087
                if (!m->mount_monitor) {
261✔
2088
                        log_oom();
×
2089
                        goto fail;
×
2090
                }
2091

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

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

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

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

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

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

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

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

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

2150
                (void) sd_event_source_set_description(m->mount_event_source, "mount-monitor-dispatch");
261✔
2151
        }
2152

2153
        r = mount_load_proc_self_mountinfo(m, false);
285✔
2154
        if (r < 0)
285✔
2155
                goto fail;
×
2156

2157
        return;
2158

2159
fail:
×
2160
        mount_shutdown(m);
×
2161
}
2162

2163
static int drain_libmount(Manager *m) {
3,622✔
2164
        bool rescan = false;
3,622✔
2165
        int r;
3,622✔
2166

2167
        assert(m);
3,622✔
2168

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

2183
        return rescan;
3,622✔
2184
}
2185

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

2191
        assert(m);
3,622✔
2192

2193
        r = drain_libmount(m);
3,622✔
2194
        if (r <= 0)
3,622✔
2195
                return r;
2196

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

2203
                return 0;
2204
        }
2205

2206
        manager_dispatch_load_queue(m);
3,077✔
2207

2208
        LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
59,425✔
2209
                Mount *mount = MOUNT(u);
56,348✔
2210

2211
                if (!mount_is_mounted(mount)) {
56,348✔
2212

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

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

2222
                        mount->from_proc_self_mountinfo = false;
10,570✔
2223
                        assert_se(update_parameters_proc_self_mountinfo(mount, NULL, NULL, NULL) >= 0);
10,570✔
2224

2225
                        switch (mount->state) {
10,570✔
2226

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

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

2244
                        default:
2245
                                break;
2246
                        }
2247

2248
                } else if (mount->proc_flags & (MOUNT_PROC_JUST_MOUNTED|MOUNT_PROC_JUST_CHANGED)) {
45,778✔
2249

2250
                        /* A mount point was added or changed */
2251

2252
                        switch (mount->state) {
1,455✔
2253

2254
                        case MOUNT_DEAD:
900✔
2255
                        case MOUNT_FAILED:
2256

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

2264
                        case MOUNT_MOUNTING:
528✔
2265
                                mount_set_state(mount, MOUNT_MOUNTING_DONE);
528✔
2266
                                break;
2267

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

2277
                if (mount_is_mounted(mount) &&
56,348✔
2278
                    mount->from_proc_self_mountinfo &&
45,778✔
2279
                    mount->parameters_proc_self_mountinfo.what)
45,778✔
2280
                        /* Track devices currently used */
2281
                        if (set_put_strdup_full(&around, &path_hash_ops_free, mount->parameters_proc_self_mountinfo.what) < 0)
45,778✔
2282
                                log_oom();
×
2283

2284
                /* Reset the flags for later calls */
2285
                mount->proc_flags = 0;
56,348✔
2286
        }
2287

2288
        SET_FOREACH(what, gone) {
3,945✔
2289
                if (set_contains(around, what))
868✔
2290
                        continue;
759✔
2291

2292
                /* Let the device units know that the device is no longer mounted */
2293
                device_found_node(m, what, DEVICE_NOT_FOUND, DEVICE_FOUND_MOUNT);
109✔
2294
        }
2295

2296
        return 0;
3,077✔
2297
}
2298

2299
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
3,053✔
2300
        Manager *m = ASSERT_PTR(userdata);
3,053✔
2301

2302
        assert(revents & EPOLLIN);
3,053✔
2303

2304
        return mount_process_proc_self_mountinfo(m);
3,053✔
2305
}
2306

2307
static void mount_reset_failed(Unit *u) {
×
2308
        Mount *m = MOUNT(u);
×
2309

2310
        assert(m);
×
2311

2312
        if (m->state == MOUNT_FAILED)
×
2313
                mount_set_state(m, MOUNT_DEAD);
×
2314

2315
        m->result = MOUNT_SUCCESS;
×
2316
        m->reload_result = MOUNT_SUCCESS;
×
2317
        m->clean_result = MOUNT_SUCCESS;
×
2318
}
×
2319

2320
static PidRef* mount_control_pid(Unit *u) {
×
2321
        return &ASSERT_PTR(MOUNT(u))->control_pid;
×
2322
}
2323

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

2329
        assert(m);
×
2330
        assert(mask != 0);
×
2331

2332
        if (m->state != MOUNT_DEAD)
×
2333
                return -EBUSY;
2334

2335
        r = exec_context_get_clean_directories(&m->exec_context, u->manager->prefix, mask, &l);
×
2336
        if (r < 0)
×
2337
                return r;
2338

2339
        if (strv_isempty(l))
×
2340
                return -EUNATCH;
2341

2342
        mount_unwatch_control_pid(m);
×
2343
        m->clean_result = MOUNT_SUCCESS;
×
2344
        m->control_command = NULL;
×
2345
        m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
×
2346

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

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

2359
        mount_set_state(m, MOUNT_CLEANING);
×
2360
        return 0;
2361

2362
fail:
×
2363
        m->clean_result = MOUNT_FAILURE_RESOURCES;
×
2364
        m->timer_event_source = sd_event_source_disable_unref(m->timer_event_source);
×
2365
        return r;
×
2366
}
2367

2368
static int mount_can_clean(Unit *u, ExecCleanMask *ret) {
74✔
2369
        Mount *m = ASSERT_PTR(MOUNT(u));
74✔
2370

2371
        return exec_context_get_clean_mask(&m->exec_context, ret);
74✔
2372
}
2373

2374
static int mount_can_start(Unit *u) {
532✔
2375
        Mount *m = ASSERT_PTR(MOUNT(u));
532✔
2376
        int r;
532✔
2377

2378
        r = unit_test_start_limit(u);
532✔
2379
        if (r < 0) {
532✔
2380
                mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT, /* flush_result = */ false);
×
2381
                return r;
×
2382
        }
2383

2384
        if (!get_mount_parameters_fragment(m))
532✔
2385
                return -ENOENT;
×
2386

2387
        return 1;
2388
}
2389

2390
static int mount_subsystem_ratelimited(Manager *m) {
705✔
2391
        assert(m);
705✔
2392

2393
        if (!m->mount_event_source)
705✔
2394
                return false;
2395

2396
        return sd_event_source_is_ratelimited(m->mount_event_source);
705✔
2397
}
2398

2399
char* mount_get_what_escaped(const Mount *m) {
1,726✔
2400
        _cleanup_free_ char *escaped = NULL;
3,452✔
2401
        const char *s = NULL;
1,726✔
2402

2403
        assert(m);
1,726✔
2404

2405
        if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
1,726✔
2406
                s = m->parameters_proc_self_mountinfo.what;
2407
        else if (m->from_fragment && m->parameters_fragment.what)
399✔
2408
                s = m->parameters_fragment.what;
2409

2410
        if (s) {
1,626✔
2411
                escaped = utf8_escape_invalid(s);
1,626✔
2412
                if (!escaped)
1,626✔
2413
                        return NULL;
×
2414
        }
2415

2416
        return escaped ? TAKE_PTR(escaped) : strdup("");
100✔
2417
}
2418

2419
char* mount_get_options_escaped(const Mount *m) {
1,726✔
2420
        _cleanup_free_ char *escaped = NULL;
3,452✔
2421
        const char *s = NULL;
1,726✔
2422

2423
        assert(m);
1,726✔
2424

2425
        if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options)
1,726✔
2426
                s = m->parameters_proc_self_mountinfo.options;
2427
        else if (m->from_fragment && m->parameters_fragment.options)
399✔
2428
                s = m->parameters_fragment.options;
2429

2430
        if (s) {
1,543✔
2431
                escaped = utf8_escape_invalid(s);
1,543✔
2432
                if (!escaped)
1,543✔
2433
                        return NULL;
×
2434
        }
2435

2436
        return escaped ? TAKE_PTR(escaped) : strdup("");
183✔
2437
}
2438

2439
const char* mount_get_fstype(const Mount *m) {
1,726✔
2440
        assert(m);
1,726✔
2441

2442
        if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype)
1,726✔
2443
                return m->parameters_proc_self_mountinfo.fstype;
2444

2445
        if (m->from_fragment && m->parameters_fragment.fstype)
399✔
2446
                return m->parameters_fragment.fstype;
119✔
2447

2448
        return NULL;
2449
}
2450

2451
static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
2452
        [MOUNT_EXEC_MOUNT]   = "ExecMount",
2453
        [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
2454
        [MOUNT_EXEC_REMOUNT] = "ExecRemount",
2455
};
2456

2457
DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
630✔
2458

2459
static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
2460
        [MOUNT_SUCCESS]                 = "success",
2461
        [MOUNT_FAILURE_RESOURCES]       = "resources",
2462
        [MOUNT_FAILURE_TIMEOUT]         = "timeout",
2463
        [MOUNT_FAILURE_EXIT_CODE]       = "exit-code",
2464
        [MOUNT_FAILURE_SIGNAL]          = "signal",
2465
        [MOUNT_FAILURE_CORE_DUMP]       = "core-dump",
2466
        [MOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
2467
        [MOUNT_FAILURE_PROTOCOL]        = "protocol",
2468
};
2469

2470
DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
11,443✔
2471

2472
const UnitVTable mount_vtable = {
2473
        .object_size = sizeof(Mount),
2474
        .exec_context_offset = offsetof(Mount, exec_context),
2475
        .cgroup_context_offset = offsetof(Mount, cgroup_context),
2476
        .kill_context_offset = offsetof(Mount, kill_context),
2477
        .exec_runtime_offset = offsetof(Mount, exec_runtime),
2478
        .cgroup_runtime_offset = offsetof(Mount, cgroup_runtime),
2479

2480
        .sections =
2481
                "Unit\0"
2482
                "Mount\0"
2483
                "Install\0",
2484
        .private_section = "Mount",
2485

2486
        .can_transient = true,
2487
        .can_fail = true,
2488
        .exclude_from_switch_root_serialization = true,
2489

2490
        .init = mount_init,
2491
        .load = mount_load,
2492
        .done = mount_done,
2493

2494
        .coldplug = mount_coldplug,
2495
        .catchup = mount_catchup,
2496

2497
        .dump = mount_dump,
2498

2499
        .start = mount_start,
2500
        .stop = mount_stop,
2501

2502
        .reload = mount_reload,
2503
        .can_reload = mount_can_reload,
2504

2505
        .clean = mount_clean,
2506
        .can_clean = mount_can_clean,
2507

2508
        .serialize = mount_serialize,
2509
        .deserialize_item = mount_deserialize_item,
2510

2511
        .active_state = mount_active_state,
2512
        .sub_state_to_string = mount_sub_state_to_string,
2513

2514
        .will_restart = unit_will_restart_default,
2515

2516
        .may_gc = mount_may_gc,
2517
        .is_extrinsic = mount_is_extrinsic,
2518

2519
        .sigchld_event = mount_sigchld_event,
2520

2521
        .reset_failed = mount_reset_failed,
2522

2523
        .notify_handoff_timestamp = mount_handoff_timestamp,
2524

2525
        .control_pid = mount_control_pid,
2526

2527
        .bus_set_property = bus_mount_set_property,
2528
        .bus_commit_properties = bus_mount_commit_properties,
2529

2530
        .get_timeout = mount_get_timeout,
2531

2532
        .enumerate_perpetual = mount_enumerate_perpetual,
2533
        .enumerate = mount_enumerate,
2534
        .shutdown = mount_shutdown,
2535
        .subsystem_ratelimited = mount_subsystem_ratelimited,
2536

2537
        .status_message_formats = {
2538
                .starting_stopping = {
2539
                        [0] = "Mounting %s...",
2540
                        [1] = "Unmounting %s...",
2541
                },
2542
                .finished_start_job = {
2543
                        [JOB_DONE]       = "Mounted %s.",
2544
                        [JOB_FAILED]     = "Failed to mount %s.",
2545
                        [JOB_TIMEOUT]    = "Timed out mounting %s.",
2546
                },
2547
                .finished_stop_job = {
2548
                        [JOB_DONE]       = "Unmounted %s.",
2549
                        [JOB_FAILED]     = "Failed unmounting %s.",
2550
                        [JOB_TIMEOUT]    = "Timed out unmounting %s.",
2551
                },
2552
        },
2553

2554
        .can_start = mount_can_start,
2555

2556
        .notify_plymouth = true,
2557
};
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