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

systemd / systemd / 17281840010

27 Aug 2025 01:33PM UTC coverage: 72.231% (-0.001%) from 72.232%
17281840010

push

github

yuwata
test: ensure that reload updates DNSSEC and DNSOverTLS on link scopes

302510 of 418810 relevant lines covered (72.23%)

652751.72 hits per line

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

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

3
#include <signal.h>
4
#include <stdio.h>
5
#include <stdlib.h>
6
#include <sys/socket.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 "errno-util.h"
16
#include "exec-credential.h"
17
#include "exit-status.h"
18
#include "fd-util.h"
19
#include "format-util.h"
20
#include "fstab-util.h"
21
#include "glyph-util.h"
22
#include "initrd-util.h"
23
#include "libmount-util.h"
24
#include "log.h"
25
#include "manager.h"
26
#include "mkdir-label.h"
27
#include "mount-util.h"
28
#include "mount.h"
29
#include "mount-setup.h"
30
#include "mountpoint-util.h"
31
#include "parse-util.h"
32
#include "path-util.h"
33
#include "process-util.h"
34
#include "serialize.h"
35
#include "set.h"
36
#include "special.h"
37
#include "stat-util.h"
38
#include "string-table.h"
39
#include "string-util.h"
40
#include "strv.h"
41
#include "unit.h"
42
#include "unit-name.h"
43
#include "utf8.h"
44

45
#define RETRY_UMOUNT_MAX 32
46

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

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

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

82
static MountParameters* get_mount_parameters_fragment(Mount *m) {
20,734✔
83
        assert(m);
20,734✔
84

85
        if (m->from_fragment)
20,734✔
86
                return &m->parameters_fragment;
4,429✔
87

88
        return NULL;
89
}
90

91
static MountParameters* get_mount_parameters(Mount *m) {
12,968✔
92
        assert(m);
12,968✔
93

94
        if (m->from_proc_self_mountinfo)
12,968✔
95
                return &m->parameters_proc_self_mountinfo;
9,192✔
96

97
        return get_mount_parameters_fragment(m);
3,776✔
98
}
99

100
static bool mount_is_network(const MountParameters *p) {
829✔
101
        assert(p);
829✔
102

103
        if (fstab_test_option(p->options, "_netdev\0"))
829✔
104
                return true;
105

106
        if (p->fstype && fstype_is_network(p->fstype))
829✔
107
                return true;
×
108

109
        return false;
110
}
111

112
static bool mount_is_nofail(const Mount *m) {
395✔
113
        assert(m);
395✔
114

115
        if (!m->from_fragment)
395✔
116
                return false;
117

118
        return fstab_test_yes_no_option(m->parameters_fragment.options, "nofail\0" "fail\0");
229✔
119
}
120

121
static bool mount_is_loop(const MountParameters *p) {
171✔
122
        assert(p);
171✔
123

124
        if (fstab_test_option(p->options, "loop\0"))
171✔
125
                return true;
110✔
126

127
        return false;
128
}
129

130
static bool mount_is_bind(const MountParameters *p) {
7,967✔
131
        assert(p);
7,967✔
132
        return fstab_is_bind(p->options, p->fstype);
7,967✔
133
}
134

135
static int mount_is_bound_to_device(Mount *m) {
518✔
136
        _cleanup_free_ char *value = NULL;
518✔
137
        const MountParameters *p;
518✔
138
        int r;
518✔
139

140
        assert(m);
518✔
141

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

147
        p = get_mount_parameters(m);
518✔
148
        if (!p)
518✔
149
                return false;
150

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

157
        if (isempty(value))
518✔
158
                return true;
159

160
        return parse_boolean(value);
×
161
}
162

163
static bool mount_propagate_stop(Mount *m) {
259✔
164
        int r;
259✔
165

166
        assert(m);
259✔
167

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

176
        return m->from_fragment; /* let's propagate stop whenever this is an explicitly configured unit,
259✔
177
                                  * otherwise let's not bother. */
178
}
179

180
static void mount_init(Unit *u) {
27,565✔
181
        Mount *m = ASSERT_PTR(MOUNT(u));
27,565✔
182

183
        assert(u->load_state == UNIT_STUB);
27,565✔
184

185
        m->timeout_usec = u->manager->defaults.timeout_start_usec;
27,565✔
186

187
        m->exec_context.std_output = u->manager->defaults.std_output;
27,565✔
188
        m->exec_context.std_error = u->manager->defaults.std_error;
27,565✔
189

190
        m->directory_mode = 0755;
27,565✔
191

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

198
        m->control_pid = PIDREF_NULL;
27,565✔
199
        m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
27,565✔
200

201
        u->ignore_on_isolate = true;
27,565✔
202
}
27,565✔
203

204
static int mount_arm_timer(Mount *m, bool relative, usec_t usec) {
202✔
205
        assert(m);
202✔
206

207
        return unit_arm_timer(UNIT(m), &m->timer_event_source, relative, usec, mount_dispatch_timer);
202✔
208
}
209

210
static void mount_unwatch_control_pid(Mount *m) {
36,089✔
211
        assert(m);
36,089✔
212
        unit_unwatch_pidref_done(UNIT(m), &m->control_pid);
36,089✔
213
}
36,089✔
214

215
static void mount_parameters_done(MountParameters *p) {
55,130✔
216
        assert(p);
55,130✔
217

218
        p->what = mfree(p->what);
55,130✔
219
        p->options = mfree(p->options);
55,130✔
220
        p->fstype = mfree(p->fstype);
55,130✔
221
}
55,130✔
222

223
static void mount_done(Unit *u) {
27,565✔
224
        Mount *m = ASSERT_PTR(MOUNT(u));
27,565✔
225

226
        m->where = mfree(m->where);
27,565✔
227

228
        mount_parameters_done(&m->parameters_proc_self_mountinfo);
27,565✔
229
        mount_parameters_done(&m->parameters_fragment);
27,565✔
230

231
        m->exec_runtime = exec_runtime_free(m->exec_runtime);
27,565✔
232

233
        exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
27,565✔
234
        m->control_command = NULL;
27,565✔
235

236
        mount_unwatch_control_pid(m);
27,565✔
237

238
        m->timer_event_source = sd_event_source_disable_unref(m->timer_event_source);
27,565✔
239
}
27,565✔
240

241
static int update_parameters_proc_self_mountinfo(
84,881✔
242
                Mount *m,
243
                const char *what,
244
                const char *options,
245
                const char *fstype) {
246

247
        MountParameters *p;
84,881✔
248
        int r, q, w;
84,881✔
249

250
        assert(m);
84,881✔
251

252
        p = &m->parameters_proc_self_mountinfo;
84,881✔
253

254
        r = free_and_strdup(&p->what, what);
84,881✔
255
        if (r < 0)
84,881✔
256
                return r;
257

258
        q = free_and_strdup(&p->options, options);
84,881✔
259
        if (q < 0)
84,881✔
260
                return q;
261

262
        w = free_and_strdup(&p->fstype, fstype);
84,881✔
263
        if (w < 0)
84,881✔
264
                return w;
265

266
        return r > 0 || q > 0 || w > 0;
84,881✔
267
}
268

269
static int mount_add_mount_dependencies(Mount *m) {
9,279✔
270
        MountParameters *pm;
9,279✔
271
        int r;
9,279✔
272

273
        assert(m);
9,279✔
274

275
        if (!path_equal(m->where, "/")) {
9,279✔
276
                _cleanup_free_ char *parent = NULL;
8,863✔
277

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

280
                r = path_extract_directory(m->where, &parent);
8,863✔
281
                if (r < 0)
8,863✔
282
                        return r;
283

284
                r = unit_add_mounts_for(UNIT(m), parent, UNIT_DEPENDENCY_IMPLICIT, UNIT_MOUNT_REQUIRES);
8,863✔
285
                if (r < 0)
8,863✔
286
                        return r;
287
        }
288

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

296
                r = unit_add_mounts_for(UNIT(m), pm->what, UNIT_DEPENDENCY_FILE, UNIT_MOUNT_REQUIRES);
171✔
297
                if (r < 0)
171✔
298
                        return r;
299
        }
300

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

306
                SET_FOREACH(other, s) {
32,552✔
307
                        if (other->load_state != UNIT_LOADED)
13,994✔
308
                                continue;
×
309

310
                        if (other == UNIT(m))
13,994✔
311
                                continue;
210✔
312

313
                        r = unit_add_dependency(
27,568✔
314
                                        other,
315
                                        UNIT_AFTER,
316
                                        UNIT(m),
13,784✔
317
                                        /* add_reference= */ true,
318
                                        UNIT_DEPENDENCY_PATH);
319
                        if (r < 0)
13,784✔
320
                                return r;
×
321

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

336
        return 0;
337
}
338

339
static int mount_add_device_dependencies(Mount *m) {
9,279✔
340
        UnitDependencyMask mask;
9,279✔
341
        MountParameters *p;
9,279✔
342
        UnitDependency dep;
9,279✔
343
        int r;
9,279✔
344

345
        assert(m);
9,279✔
346

347
        log_unit_trace(UNIT(m), "Processing implicit device dependencies");
9,279✔
348

349
        p = get_mount_parameters(m);
9,279✔
350
        if (!p) {
9,279✔
351
                log_unit_trace(UNIT(m), "Missing mount parameters, skipping implicit device dependencies");
352
                return 0;
353
        }
354

355
        if (!p->what) {
7,480✔
356
                log_unit_trace(UNIT(m), "Missing mount source, skipping implicit device dependencies");
357
                return 0;
358
        }
359

360
        if (mount_is_bind(p)) {
7,480✔
361
                log_unit_trace(UNIT(m), "Mount unit is a bind mount, skipping implicit device dependencies");
362
                return 0;
363
        }
364

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

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

377
        if (path_equal(m->where, "/")) {
368✔
378
                log_unit_trace(UNIT(m), "Mount destination is '/', skipping implicit device dependencies");
379
                return 0;
380
        }
381

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

389
        /* We always use 'what' from /proc/self/mountinfo if mounted */
390
        mask = m->from_proc_self_mountinfo ? UNIT_DEPENDENCY_MOUNTINFO : UNIT_DEPENDENCY_MOUNT_FILE;
259✔
391

392
        r = unit_add_node_dependency(UNIT(m), p->what, dep, mask);
259✔
393
        if (r < 0)
259✔
394
                return r;
395
        if (r > 0)
259✔
396
                log_unit_trace(UNIT(m), "Added %s dependency on %s", unit_dependency_to_string(dep), p->what);
259✔
397

398
        if (mount_propagate_stop(m)) {
259✔
399
                r = unit_add_node_dependency(UNIT(m), p->what, UNIT_STOP_PROPAGATED_FROM, mask);
58✔
400
                if (r < 0)
58✔
401
                        return r;
402
                if (r > 0)
403
                        log_unit_trace(UNIT(m), "Added %s dependency on %s",
259✔
404
                                       unit_dependency_to_string(UNIT_STOP_PROPAGATED_FROM), p->what);
405
        }
406

407
        r = unit_add_blockdev_dependency(UNIT(m), p->what, mask);
259✔
408
        if (r > 0)
259✔
409
                log_unit_trace(UNIT(m), "Added %s dependency on %s", unit_dependency_to_string(UNIT_AFTER), p->what);
259✔
410

411
        return 0;
259✔
412
}
413

414
static bool mount_is_extrinsic(Unit *u) {
14,859✔
415
        Mount *m = ASSERT_PTR(MOUNT(u));
14,859✔
416
        MountParameters *p;
14,859✔
417

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

423
        /* We only automatically manage mounts if we are in system mode */
424
        if (MANAGER_IS_USER(u->manager))
14,859✔
425
                return true;
426

427
        p = get_mount_parameters(m);
2,597✔
428
        if (p && fstab_is_extrinsic(m->where, p->options))
2,597✔
429
                return true;
1,716✔
430

431
        return false;
432
}
433

434
static int mount_add_default_ordering_dependencies(Mount *m, MountParameters *p, UnitDependencyMask mask) {
395✔
435
        const char *after, *before, *e;
395✔
436
        int r;
395✔
437

438
        assert(m);
395✔
439

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

449
                after = SPECIAL_LOCAL_FS_PRE_TARGET;
22✔
450
                before = isempty(e) ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_INITRD_FS_TARGET;
22✔
451

452
        } else if (in_initrd() && path_startswith(m->where, "/sysusr/usr")) {
373✔
453
                after = SPECIAL_LOCAL_FS_PRE_TARGET;
454
                before = SPECIAL_INITRD_USR_FS_TARGET;
455

456
        } else if (mount_is_network(p)) {
373✔
457
                after = SPECIAL_REMOTE_FS_PRE_TARGET;
458
                before = SPECIAL_REMOTE_FS_TARGET;
459

460
        } else {
461
                after = SPECIAL_LOCAL_FS_PRE_TARGET;
462
                before = SPECIAL_LOCAL_FS_TARGET;
463
        }
464

465
        if (before && !mount_is_nofail(m)) {
395✔
466
                r = unit_add_dependency_by_name(UNIT(m), UNIT_BEFORE, before, /* add_reference= */ true, mask);
388✔
467
                if (r < 0)
388✔
468
                        return r;
469
        }
470

471
        if (after) {
395✔
472
                r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, /* add_reference= */ true, mask);
395✔
473
                if (r < 0)
395✔
474
                        return r;
475
        }
476

477
        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET,
395✔
478
                                              /* add_reference= */ true, mask);
479
        if (r < 0)
395✔
480
                return r;
481

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

490
        return 0;
491
}
492

493
static int mount_add_default_network_dependencies(Mount *m, MountParameters *p, UnitDependencyMask mask) {
395✔
494
        int r;
395✔
495

496
        assert(m);
395✔
497

498
        if (!mount_is_network(p))
395✔
499
                return 0;
500

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

505
        r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET,
×
506
                                        /* add_reference= */ true, mask);
507
        if (r < 0)
×
508
                return r;
509

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

514
        return unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET,
×
515
                                                 /* add_reference= */ true, mask);
516
}
517

518
static int mount_add_default_dependencies(Mount *m) {
9,279✔
519
        UnitDependencyMask mask;
9,279✔
520
        MountParameters *p;
9,279✔
521
        int r;
9,279✔
522

523
        assert(m);
9,279✔
524

525
        if (!UNIT(m)->default_dependencies)
9,279✔
526
                return 0;
527

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

535
        p = get_mount_parameters(m);
442✔
536
        if (!p)
442✔
537
                return 0;
538

539
        mask = m->from_proc_self_mountinfo ? UNIT_DEPENDENCY_MOUNTINFO : UNIT_DEPENDENCY_MOUNT_FILE;
395✔
540

541
        r = mount_add_default_ordering_dependencies(m, p, mask);
395✔
542
        if (r < 0)
395✔
543
                return r;
544

545
        r = mount_add_default_network_dependencies(m, p, mask);
395✔
546
        if (r < 0)
395✔
547
                return r;
×
548

549
        return 0;
550
}
551

552
static int mount_verify(Mount *m) {
7,288✔
553
        _cleanup_free_ char *e = NULL;
7,288✔
554
        MountParameters *p;
7,288✔
555
        int r;
7,288✔
556

557
        assert(m);
7,288✔
558
        assert(UNIT(m)->load_state == UNIT_LOADED);
7,288✔
559

560
        if (!m->from_fragment && !m->from_proc_self_mountinfo && !UNIT(m)->perpetual)
7,288✔
561
                return -ENOENT;
562

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

567
        if (!unit_has_name(UNIT(m), e))
7,288✔
568
                return log_unit_error_errno(UNIT(m), SYNTHETIC_ERRNO(ENOEXEC), "Where= setting doesn't match unit name. Refusing.");
×
569

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

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

578
        p = get_mount_parameters_fragment(m);
7,288✔
579
        if (p && !p->what && !UNIT(m)->perpetual)
7,288✔
580
                return log_unit_error_errno(UNIT(m), SYNTHETIC_ERRNO(ENOEXEC), "What= setting is missing. Refusing.");
×
581

582
        return 0;
583
}
584

585
static int mount_add_non_exec_dependencies(Mount *m) {
9,279✔
586
        int r;
9,279✔
587

588
        assert(m);
9,279✔
589

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

595
        if (!m->where)
9,279✔
596
                return 0;
597

598
        /* Adds in all dependencies directly responsible for ordering the mount, as opposed to dependencies
599
         * resulting from the ExecContext and such. */
600

601
        r = mount_add_device_dependencies(m);
9,279✔
602
        if (r < 0)
9,279✔
603
                return r;
604

605
        r = mount_add_mount_dependencies(m);
9,279✔
606
        if (r < 0)
9,279✔
607
                return r;
608

609
        r = mount_add_default_dependencies(m);
9,279✔
610
        if (r < 0)
9,279✔
611
                return r;
×
612

613
        return 0;
614
}
615

616
static int mount_add_extras(Mount *m) {
7,288✔
617
        Unit *u = UNIT(ASSERT_PTR(m));
7,288✔
618
        int r;
7,288✔
619

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

624
        if (u->fragment_path)
7,288✔
625
                m->from_fragment = true;
1,012✔
626

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

636
        path_simplify(m->where);
7,288✔
637

638
        if (!u->description) {
7,288✔
639
                _cleanup_free_ char *w = mount_get_where_escaped(m);
11,826✔
640
                if (!w)
5,913✔
641
                        return log_oom();
×
642

643
                r = unit_set_description(u, w);
5,913✔
644
                if (r < 0)
5,913✔
645
                        return r;
646
        }
647

648
        r = unit_patch_contexts(u);
7,288✔
649
        if (r < 0)
7,288✔
650
                return r;
651

652
        r = unit_add_exec_dependencies(u, &m->exec_context);
7,288✔
653
        if (r < 0)
7,288✔
654
                return r;
655

656
        r = unit_set_default_slice(u);
7,288✔
657
        if (r < 0)
7,288✔
658
                return r;
659

660
        r = mount_add_non_exec_dependencies(m);
7,288✔
661
        if (r < 0)
7,288✔
662
                return r;
×
663

664
        return 0;
665
}
666

667
static void mount_load_root_mount(Unit *u) {
27,565✔
668
        Mount *m = ASSERT_PTR(MOUNT(u));
27,565✔
669

670
        if (!unit_has_name(u, SPECIAL_ROOT_MOUNT))
27,565✔
671
                return;
672

673
        u->perpetual = true;
416✔
674
        u->default_dependencies = false;
416✔
675

676
        /* The stdio/kmsg bridge socket is on /, in order to avoid a dep loop, don't use kmsg logging for -.mount */
677
        m->exec_context.std_output = EXEC_OUTPUT_NULL;
416✔
678
        m->exec_context.std_input = EXEC_INPUT_NULL;
416✔
679

680
        if (!u->description)
416✔
681
                u->description = strdup("Root Mount");
416✔
682
}
683

684
static int mount_load(Unit *u) {
27,565✔
685
        Mount *m = ASSERT_PTR(MOUNT(u));
27,565✔
686
        int r;
27,565✔
687

688
        assert(u->load_state == UNIT_STUB);
27,565✔
689

690
        mount_load_root_mount(u);
27,565✔
691

692
        bool from_kernel = m->from_proc_self_mountinfo || u->perpetual;
27,565✔
693

694
        r = unit_load_fragment_and_dropin(u, /* fragment_required = */ !from_kernel);
27,565✔
695

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

703
        if (r < 0)
27,565✔
704
                return r;
20,277✔
705

706
        if (u->load_state != UNIT_LOADED)
7,288✔
707
                return 0;
708

709
        return mount_verify(m);
7,288✔
710
}
711

712
static void mount_set_state(Mount *m, MountState state) {
8,686✔
713
        MountState old_state;
8,686✔
714

715
        assert(m);
8,686✔
716

717
        if (m->state != state)
8,686✔
718
                bus_unit_send_pending_change_signal(UNIT(m), false);
8,598✔
719

720
        old_state = m->state;
8,686✔
721
        m->state = state;
8,686✔
722

723
        if (!MOUNT_STATE_WITH_PROCESS(state)) {
8,686✔
724
                m->timer_event_source = sd_event_source_disable_unref(m->timer_event_source);
8,326✔
725
                mount_unwatch_control_pid(m);
8,326✔
726
                m->control_command = NULL;
8,326✔
727
                m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
8,326✔
728
        }
729

730
        if (state != old_state)
8,686✔
731
                log_unit_debug(UNIT(m), "Changed %s -> %s", mount_state_to_string(old_state), mount_state_to_string(state));
8,598✔
732

733
        unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
8,686✔
734
}
8,686✔
735

736
static int mount_coldplug(Unit *u) {
13,670✔
737
        Mount *m = ASSERT_PTR(MOUNT(u));
13,670✔
738
        int r;
13,670✔
739

740
        assert(m->state == MOUNT_DEAD);
13,670✔
741

742
        if (m->deserialized_state == m->state)
13,670✔
743
                return 0;
744

745
        if (pidref_is_set(&m->control_pid) &&
923✔
746
            pidref_is_unwaited(&m->control_pid) > 0 &&
4✔
747
            MOUNT_STATE_WITH_PROCESS(m->deserialized_state)) {
4✔
748

749
                r = unit_watch_pidref(UNIT(m), &m->control_pid, /* exclusive= */ false);
4✔
750
                if (r < 0)
4✔
751
                        return r;
752

753
                r = mount_arm_timer(m, /* relative= */ false, usec_add(u->state_change_timestamp.monotonic, m->timeout_usec));
8✔
754
                if (r < 0)
4✔
755
                        return r;
756
        }
757

758
        if (!IN_SET(m->deserialized_state, MOUNT_DEAD, MOUNT_FAILED))
919✔
759
                (void) unit_setup_exec_runtime(u);
919✔
760

761
        mount_set_state(m, m->deserialized_state);
919✔
762
        return 0;
919✔
763
}
764

765
static void mount_catchup(Unit *u) {
13,670✔
766
        Mount *m = ASSERT_PTR(MOUNT(u));
13,670✔
767

768
        /* Adjust the deserialized state. See comments in mount_process_proc_self_mountinfo(). */
769
        if (m->from_proc_self_mountinfo)
13,670✔
770
                switch (m->state) {
4,731✔
771
                case MOUNT_DEAD:
772
                case MOUNT_FAILED:
773
                        assert(!pidref_is_set(&m->control_pid));
3,813✔
774
                        (void) unit_acquire_invocation_id(u);
3,813✔
775
                        mount_cycle_clear(m);
3,813✔
776
                        mount_enter_mounted(m, MOUNT_SUCCESS);
3,813✔
777
                        break;
3,813✔
778
                case MOUNT_MOUNTING:
779
                        assert(pidref_is_set(&m->control_pid));
3✔
780
                        mount_set_state(m, MOUNT_MOUNTING_DONE);
3✔
781
                        break;
3✔
782
                default:
783
                        ;
784
                }
785
        else
786
                switch (m->state) {
8,939✔
787
                case MOUNT_MOUNTING_DONE:
788
                        assert(pidref_is_set(&m->control_pid));
×
789
                        mount_set_state(m, MOUNT_MOUNTING);
×
790
                        break;
×
791
                case MOUNT_MOUNTED:
792
                        assert(!pidref_is_set(&m->control_pid));
×
793
                        mount_enter_dead(m, MOUNT_SUCCESS, /* flush_result = */ false);
×
794
                        break;
×
795
                default:
13,670✔
796
                        ;
13,670✔
797
                }
798
}
13,670✔
799

800
static void mount_dump(Unit *u, FILE *f, const char *prefix) {
132✔
801
        Mount *m = ASSERT_PTR(MOUNT(u));
132✔
802
        MountParameters *p;
132✔
803
        const char *prefix2;
132✔
804

805
        assert(f);
132✔
806

807
        prefix = strempty(prefix);
132✔
808
        prefix2 = strjoina(prefix, "\t");
660✔
809

810
        p = get_mount_parameters(m);
132✔
811

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

846
        if (pidref_is_set(&m->control_pid))
132✔
847
                fprintf(f,
×
848
                        "%sControl PID: "PID_FMT"\n",
849
                        prefix, m->control_pid.pid);
850

851
        exec_context_dump(&m->exec_context, f, prefix);
132✔
852
        kill_context_dump(&m->kill_context, f, prefix);
132✔
853
        cgroup_context_dump(UNIT(m), f, prefix);
132✔
854

855
        for (MountExecCommand c = 0; c < _MOUNT_EXEC_COMMAND_MAX; c++) {
528✔
856
                if (!m->exec_command[c].argv)
396✔
857
                        continue;
396✔
858

859
                fprintf(f, "%s%s %s:\n",
×
860
                        prefix, glyph(GLYPH_ARROW_RIGHT), mount_exec_command_to_string(c));
861

862
                exec_command_dump(m->exec_command + c, f, prefix2);
×
863
        }
864
}
132✔
865

866
static ExecFlags mount_exec_flags(MountState state) {
198✔
867
        ExecFlags flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN;
198✔
868

869
        assert(IN_SET(state, MOUNT_MOUNTING, MOUNT_REMOUNTING, MOUNT_UNMOUNTING));
198✔
870

871
        if (IN_SET(state, MOUNT_MOUNTING, MOUNT_REMOUNTING))
198✔
872
                flags |= EXEC_SETUP_CREDENTIALS;
873

874
        return flags;
198✔
875
}
876

877
static int mount_spawn(Mount *m, ExecCommand *c, ExecFlags flags, PidRef *ret_pid) {
198✔
878
        _cleanup_(exec_params_shallow_clear) ExecParameters exec_params = EXEC_PARAMETERS_INIT(flags);
198✔
879
        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
198✔
880
        int r;
198✔
881

882
        assert(m);
198✔
883
        assert(c);
198✔
884
        assert(ret_pid);
198✔
885

886
        r = unit_prepare_exec(UNIT(m));
198✔
887
        if (r < 0)
198✔
888
                return r;
889

890
        r = mount_arm_timer(m, /* relative= */ true, m->timeout_usec);
198✔
891
        if (r < 0)
198✔
892
                return r;
893

894
        r = unit_set_exec_params(UNIT(m), &exec_params);
198✔
895
        if (r < 0)
198✔
896
                return r;
897

898
        /* Assume the label inherited from systemd as the fallback */
899
        exec_params.fallback_smack_process_label = NULL;
198✔
900

901
        r = exec_spawn(UNIT(m),
396✔
902
                       c,
903
                       &m->exec_context,
198✔
904
                       &exec_params,
905
                       m->exec_runtime,
906
                       &m->cgroup_context,
198✔
907
                       &pidref);
908
        if (r < 0)
198✔
909
                return r;
910

911
        r = unit_watch_pidref(UNIT(m), &pidref, /* exclusive= */ true);
198✔
912
        if (r < 0)
198✔
913
                return r;
914

915
        *ret_pid = TAKE_PIDREF(pidref);
198✔
916
        return 0;
198✔
917
}
918

919
static void mount_enter_dead(Mount *m, MountResult f, bool flush_result) {
1,687✔
920
        assert(m);
1,687✔
921

922
        if (m->result == MOUNT_SUCCESS || flush_result)
1,687✔
923
                m->result = f;
1,687✔
924

925
        unit_log_result(UNIT(m), m->result == MOUNT_SUCCESS, mount_result_to_string(m->result));
1,687✔
926
        unit_warn_leftover_processes(UNIT(m), /* start = */ false);
1,687✔
927

928
        mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
3,374✔
929

930
        m->exec_runtime = exec_runtime_destroy(m->exec_runtime);
1,687✔
931

932
        unit_destroy_runtime_data(UNIT(m), &m->exec_context, /* destroy_runtime_dir = */ true);
1,687✔
933

934
        unit_unref_uid_gid(UNIT(m), true);
1,687✔
935

936
        /* Any dependencies based on /proc/self/mountinfo are now stale. Let's re-generate dependencies from
937
         * .mount unit. */
938
        (void) mount_add_non_exec_dependencies(m);
1,687✔
939
}
1,687✔
940

941
static void mount_enter_mounted(Mount *m, MountResult f) {
5,636✔
942
        assert(m);
5,636✔
943

944
        if (m->result == MOUNT_SUCCESS)
5,636✔
945
                m->result = f;
5,636✔
946

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

955
        mount_set_state(m, MOUNT_MOUNTED);
5,636✔
956
}
5,636✔
957

958
static void mount_enter_dead_or_mounted(Mount *m, MountResult f, bool flush_result) {
40✔
959
        assert(m);
40✔
960

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

968
        if (m->from_proc_self_mountinfo)
40✔
969
                mount_enter_mounted(m, f);
×
970
        else
971
                mount_enter_dead(m, f, flush_result);
40✔
972
}
40✔
973

974
static int state_to_kill_operation(MountState state) {
×
975
        switch (state) {
×
976

977
        case MOUNT_REMOUNTING_SIGTERM:
978
                return KILL_RESTART;
979

980
        case MOUNT_UNMOUNTING_SIGTERM:
×
981
                return KILL_TERMINATE;
×
982

983
        case MOUNT_REMOUNTING_SIGKILL:
×
984
        case MOUNT_UNMOUNTING_SIGKILL:
985
                return KILL_KILL;
×
986

987
        default:
×
988
                return _KILL_OPERATION_INVALID;
×
989
        }
990
}
991

992
static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
×
993
        int r;
×
994

995
        assert(m);
×
996

997
        if (m->result == MOUNT_SUCCESS)
×
998
                m->result = f;
×
999

1000
        r = unit_kill_context(UNIT(m), state_to_kill_operation(state));
×
1001
        if (r < 0) {
×
1002
                log_unit_warning_errno(UNIT(m), r, "Failed to kill processes: %m");
×
1003
                goto fail;
×
1004
        }
1005

1006
        if (r > 0) {
×
1007
                r = mount_arm_timer(m, /* relative= */ true, m->timeout_usec);
×
1008
                if (r < 0) {
×
1009
                        log_unit_warning_errno(UNIT(m), r, "Failed to install timer: %m");
×
1010
                        goto fail;
×
1011
                }
1012

1013
                mount_set_state(m, state);
×
1014
        } else if (state == MOUNT_REMOUNTING_SIGTERM && m->kill_context.send_sigkill)
×
1015
                mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_SUCCESS);
×
1016
        else if (IN_SET(state, MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL))
×
1017
                mount_enter_mounted(m, MOUNT_SUCCESS);
×
1018
        else if (state == MOUNT_UNMOUNTING_SIGTERM && m->kill_context.send_sigkill)
×
1019
                mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_SUCCESS);
×
1020
        else
1021
                mount_enter_dead_or_mounted(m, MOUNT_SUCCESS, /* flush_result = */ false);
×
1022

1023
        return;
1024

1025
fail:
×
1026
        mount_enter_dead_or_mounted(m, MOUNT_FAILURE_RESOURCES, /* flush_result = */ false);
×
1027
}
1028

1029
static int mount_set_umount_command(Mount *m, ExecCommand *c) {
40✔
1030
        int r;
40✔
1031

1032
        assert(m);
40✔
1033
        assert(c);
40✔
1034

1035
        r = exec_command_set(c, UMOUNT_PATH, m->where, "-c", NULL);
40✔
1036
        if (r < 0)
40✔
1037
                return r;
1038

1039
        if (m->lazy_unmount) {
40✔
1040
                r = exec_command_append(c, "-l", NULL);
×
1041
                if (r < 0)
×
1042
                        return r;
1043
        }
1044

1045
        if (m->force_unmount) {
40✔
1046
                r = exec_command_append(c, "-f", NULL);
×
1047
                if (r < 0)
×
1048
                        return r;
×
1049
        }
1050

1051
        return 0;
1052
}
1053

1054
static void mount_enter_unmounting(Mount *m) {
40✔
1055
        int r;
40✔
1056

1057
        assert(m);
40✔
1058

1059
        /* Start counting our attempts */
1060
        if (!IN_SET(m->state,
40✔
1061
                    MOUNT_UNMOUNTING,
1062
                    MOUNT_UNMOUNTING_SIGTERM,
1063
                    MOUNT_UNMOUNTING_SIGKILL))
1064
                m->n_retry_umount = 0;
40✔
1065

1066
        mount_unwatch_control_pid(m);
40✔
1067

1068
        m->control_command_id = MOUNT_EXEC_UNMOUNT;
40✔
1069
        m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
40✔
1070

1071
        r = mount_set_umount_command(m, m->control_command);
40✔
1072
        if (r < 0) {
40✔
1073
                log_unit_warning_errno(UNIT(m), r, "Failed to prepare umount command line: %m");
×
1074
                goto fail;
×
1075
        }
1076

1077
        r = mount_spawn(m, m->control_command, mount_exec_flags(MOUNT_UNMOUNTING), &m->control_pid);
40✔
1078
        if (r < 0) {
40✔
1079
                log_unit_warning_errno(UNIT(m), r, "Failed to spawn 'umount' task: %m");
×
1080
                goto fail;
×
1081
        }
1082

1083
        mount_set_state(m, MOUNT_UNMOUNTING);
40✔
1084
        return;
40✔
1085

1086
fail:
×
1087
        mount_enter_dead_or_mounted(m, MOUNT_FAILURE_RESOURCES, /* flush_result = */ false);
×
1088
}
1089

1090
static int mount_apply_graceful_options(Mount *m, const MountParameters *p, char **opts) {
158✔
1091
        _cleanup_strv_free_ char **graceful = NULL;
×
1092
        _cleanup_free_ char *filtered = NULL;
158✔
1093
        int r;
158✔
1094

1095
        assert(m);
158✔
1096
        assert(p);
158✔
1097
        assert(opts);
158✔
1098

1099
        r = fstab_filter_options(*opts, "x-systemd.graceful-option\0", NULL, NULL, &graceful, &filtered);
158✔
1100
        if (r <= 0)
158✔
1101
                return r;
1102

1103
        if (!p->fstype) {
18✔
1104
                log_unit_warning(UNIT(m), "x-systemd.graceful-option= used but file system type not known, suppressing all graceful options.");
×
1105
                return 0;
×
1106
        }
1107

1108
        STRV_FOREACH(o, graceful) {
36✔
1109
                _cleanup_free_ char *k = NULL, *v = NULL;
18✔
1110

1111
                r = split_pair(*o, "=", &k, &v);
18✔
1112
                if (r < 0 && r != -EINVAL) /* EINVAL → not a key/value pair */
18✔
1113
                        return r;
1114

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

1130
                        if (!strextend_with_separator(&filtered, ",", *o))
18✔
1131
                                return -ENOMEM;
1132
                }
1133
        }
1134

1135
        return free_and_replace(*opts, filtered);
18✔
1136
}
1137

1138
static int mount_set_mount_command(Mount *m, ExecCommand *c, const MountParameters *p, bool remount) {
158✔
1139
        int r;
158✔
1140

1141
        assert(m);
158✔
1142
        assert(c);
158✔
1143
        assert(p);
158✔
1144

1145
        r = exec_command_set(c, MOUNT_PATH, p->what, m->where, NULL);
158✔
1146
        if (r < 0)
158✔
1147
                return r;
158✔
1148

1149
        if (m->sloppy_options) {
158✔
1150
                r = exec_command_append(c, "-s", NULL);
×
1151
                if (r < 0)
×
1152
                        return r;
1153
        }
1154

1155
        if (m->read_write_only) {
158✔
1156
                r = exec_command_append(c, "-w", NULL);
×
1157
                if (r < 0)
×
1158
                        return r;
1159
        }
1160

1161
        if (p->fstype) {
158✔
1162
                r = exec_command_append(c, "-t", p->fstype, NULL);
146✔
1163
                if (r < 0)
146✔
1164
                        return r;
1165
        }
1166

1167
        _cleanup_free_ char *opts = NULL;
158✔
1168
        r = fstab_filter_options(p->options, "nofail\0" "fail\0" "noauto\0" "auto\0", NULL, NULL, NULL, &opts);
158✔
1169
        if (r < 0)
158✔
1170
                return r;
1171

1172
        r = mount_apply_graceful_options(m, p, &opts);
158✔
1173
        if (r < 0)
158✔
1174
                return r;
1175

1176
        if (remount)
158✔
1177
                if (!strprepend_with_separator(&opts, ",", "remount"))
×
1178
                        return -ENOMEM;
1179

1180
        if (!isempty(opts)) {
305✔
1181
                r = exec_command_append(c, "-o", opts, NULL);
147✔
1182
                if (r < 0)
147✔
1183
                        return r;
×
1184
        }
1185

1186
        return 0;
1187
}
1188

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

1194
        assert(m);
158✔
1195

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

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

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

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

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

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

1260
        if (source_is_dir)
158✔
1261
                unit_warn_if_dir_nonempty(UNIT(m), m->where);
158✔
1262

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

1276
        mount_unwatch_control_pid(m);
158✔
1277
        unit_warn_leftover_processes(UNIT(m), /* start = */ true);
158✔
1278

1279
        m->control_command_id = MOUNT_EXEC_MOUNT;
158✔
1280
        m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
158✔
1281

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

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

1294
        mount_set_state(m, MOUNT_MOUNTING);
158✔
1295
        return;
158✔
1296

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

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

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

1308
        m->reload_result = result;
×
1309
}
1310

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

1315
        assert(m);
×
1316

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

1323
        mount_unwatch_control_pid(m);
×
1324
        m->reload_result = MOUNT_SUCCESS;
×
1325

1326
        m->control_command_id = MOUNT_EXEC_REMOUNT;
×
1327
        m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
×
1328

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

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

1341
        mount_set_state(m, MOUNT_REMOUNTING);
×
1342
        return;
×
1343

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

1349
static void mount_cycle_clear(Mount *m) {
7,283✔
1350
        assert(m);
7,283✔
1351

1352
        /* Clear all state we shall forget for this new cycle */
1353

1354
        m->result = MOUNT_SUCCESS;
7,283✔
1355
        m->reload_result = MOUNT_SUCCESS;
7,283✔
1356
        exec_command_reset_status_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
7,283✔
1357

1358
        if (m->cgroup_runtime)
7,283✔
1359
                m->cgroup_runtime->reset_accounting = true;
3✔
1360
}
7,283✔
1361

1362
static int mount_start(Unit *u) {
158✔
1363
        Mount *m = ASSERT_PTR(MOUNT(u));
158✔
1364
        int r;
158✔
1365

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

1375
        /* Already on it! */
1376
        if (IN_SET(m->state, MOUNT_MOUNTING, MOUNT_MOUNTING_DONE))
158✔
1377
                return 0;
1378

1379
        assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED));
158✔
1380

1381
        r = unit_acquire_invocation_id(u);
158✔
1382
        if (r < 0)
158✔
1383
                return r;
1384

1385
        mount_cycle_clear(m);
158✔
1386
        mount_enter_mounting(m);
158✔
1387

1388
        return 1;
158✔
1389
}
1390

1391
static int mount_stop(Unit *u) {
40✔
1392
        Mount *m = ASSERT_PTR(MOUNT(u));
40✔
1393

1394
        switch (m->state) {
40✔
1395

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

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

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

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

1419
        case MOUNT_MOUNTED:
40✔
1420
                mount_enter_unmounting(m);
40✔
1421
                return 1;
40✔
1422

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

1428
        default:
×
1429
                assert_not_reached();
×
1430
        }
1431
}
1432

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

1436
        assert(m->state == MOUNT_MOUNTED);
×
1437

1438
        mount_enter_remounting(m);
×
1439

1440
        return 1;
×
1441
}
1442

1443
static bool mount_can_reload(Unit *u) {
75✔
1444
        Mount *m = ASSERT_PTR(MOUNT(u));
75✔
1445

1446
        return get_mount_parameters_fragment(m);
75✔
1447
}
1448

1449
static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
1,124✔
1450
        Mount *m = ASSERT_PTR(MOUNT(u));
1,124✔
1451

1452
        assert(f);
1,124✔
1453
        assert(fds);
1,124✔
1454

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

1461
        if (m->control_command_id >= 0)
1,124✔
1462
                (void) serialize_item(f, "control-command", mount_exec_command_to_string(m->control_command_id));
4✔
1463

1464
        return 0;
1,124✔
1465
}
1466

1467
static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
3,616✔
1468
        Mount *m = ASSERT_PTR(MOUNT(u));
3,616✔
1469
        int r;
3,616✔
1470

1471
        assert(key);
3,616✔
1472
        assert(value);
3,616✔
1473
        assert(fds);
3,616✔
1474

1475
        if (streq(key, "state")) {
3,616✔
1476
                MountState state;
901✔
1477

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

1484
        } else if (streq(key, "result")) {
2,715✔
1485
                MountResult f;
901✔
1486

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

1493
        } else if (streq(key, "reload-result")) {
1,814✔
1494
                MountResult f;
901✔
1495

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

1502
        } else if (streq(key, "n-retry-umount")) {
913✔
1503

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

1508
        } else if (streq(key, "control-pid")) {
12✔
1509

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

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

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

1526
        return 0;
3,616✔
1527
}
1528

1529
static UnitActiveState mount_active_state(Unit *u) {
343,200✔
1530
        Mount *m = ASSERT_PTR(MOUNT(u));
343,200✔
1531

1532
        return state_translation_table[m->state];
343,200✔
1533
}
1534

1535
static const char *mount_sub_state_to_string(Unit *u) {
1,568✔
1536
        Mount *m = ASSERT_PTR(MOUNT(u));
1,568✔
1537

1538
        return mount_state_to_string(m->state);
1,568✔
1539
}
1540

1541
static bool mount_may_gc(Unit *u) {
51,991✔
1542
        Mount *m = ASSERT_PTR(MOUNT(u));
51,991✔
1543

1544
        if (m->from_proc_self_mountinfo)
51,991✔
1545
                return false;
5,636✔
1546

1547
        return true;
1548
}
1549

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

1554
        assert(pid >= 0);
198✔
1555

1556
        if (pid != m->control_pid.pid)
198✔
1557
                return;
1558

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

1575
        pidref_done(&m->control_pid);
198✔
1576

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

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

1594
        if (m->control_command) {
198✔
1595
                exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
198✔
1596

1597
                m->control_command = NULL;
198✔
1598
                m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
198✔
1599
        }
1600

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

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

1611
        switch (m->state) {
198✔
1612

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

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

1625
        case MOUNT_MOUNTING_DONE:
158✔
1626
                mount_enter_mounted(m, f);
158✔
1627
                break;
158✔
1628

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

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

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

1662
                break;
1663

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

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

1673
                mount_enter_dead(m, MOUNT_SUCCESS, /* flush_result = */ false);
×
1674
                break;
×
1675

1676
        default:
×
1677
                assert_not_reached();
×
1678
        }
1679

1680
        /* Notify clients about changed exit status */
1681
        unit_add_to_dbus_queue(u);
198✔
1682
}
1683

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

1687
        assert(m->timer_event_source == source);
×
1688

1689
        switch (m->state) {
×
1690

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

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

1703
        case MOUNT_REMOUNTING_SIGTERM:
×
1704
                mount_set_reload_result(m, MOUNT_FAILURE_TIMEOUT);
×
1705

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

1715
        case MOUNT_REMOUNTING_SIGKILL:
×
1716
                mount_set_reload_result(m, MOUNT_FAILURE_TIMEOUT);
×
1717

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

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

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

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

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

1745
                if (m->clean_result == MOUNT_SUCCESS)
×
1746
                        m->clean_result = MOUNT_FAILURE_TIMEOUT;
×
1747

1748
                mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, 0);
×
1749
                break;
×
1750

1751
        default:
×
1752
                assert_not_reached();
×
1753
        }
1754

1755
        return 0;
×
1756
}
1757

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

1768
        _cleanup_(unit_freep) Unit *u = NULL;
6,123✔
1769
        Mount *mnt;
6,123✔
1770
        int r;
6,123✔
1771

1772
        assert(m);
6,123✔
1773
        assert(name);
6,123✔
1774
        assert(ret_flags);
6,123✔
1775
        assert(ret);
6,123✔
1776

1777
        r = unit_new_for_name(m, sizeof(Mount), name, &u);
6,123✔
1778
        if (r < 0)
6,123✔
1779
                return r;
1780

1781
        mnt = ASSERT_PTR(MOUNT(u));
6,123✔
1782

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

1787
        r = free_and_strdup(&mnt->where, where);
6,123✔
1788
        if (r < 0)
6,123✔
1789
                return r;
1790

1791
        r = update_parameters_proc_self_mountinfo(mnt, what, options, fstype);
6,123✔
1792
        if (r < 0)
6,123✔
1793
                return r;
1794

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

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

1804
        *ret_flags = MOUNT_PROC_IS_MOUNTED | MOUNT_PROC_JUST_MOUNTED | MOUNT_PROC_JUST_CHANGED;
6,123✔
1805
        *ret = TAKE_PTR(u);
6,123✔
1806
        return 0;
6,123✔
1807
}
1808

1809
static int mount_setup_existing_unit(
67,798✔
1810
                Unit *u,
1811
                const char *what,
1812
                const char *where,
1813
                const char *options,
1814
                const char *fstype,
1815
                MountProcFlags *ret_flags) {
1816

1817
        Mount *m = ASSERT_PTR(MOUNT(u));
67,798✔
1818
        int r;
67,798✔
1819

1820
        assert(u);
67,798✔
1821
        assert(where);
67,798✔
1822
        assert(ret_flags);
67,798✔
1823

1824
        if (!m->where) {
67,798✔
1825
                m->where = strdup(where);
273✔
1826
                if (!m->where)
273✔
1827
                        return -ENOMEM;
1828
        }
1829

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

1836
        r = update_parameters_proc_self_mountinfo(m, what, options, fstype);
67,798✔
1837
        if (r < 0)
67,798✔
1838
                return r;
1839
        if (r > 0)
67,798✔
1840
                flags |= MOUNT_PROC_JUST_CHANGED;
541✔
1841

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

1852
        m->from_proc_self_mountinfo = true;
67,798✔
1853

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

1862
                flags |= MOUNT_PROC_JUST_CHANGED;
×
1863
        }
1864

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

1873
        *ret_flags = flags;
67,798✔
1874
        return 0;
67,798✔
1875
}
1876

1877
static int mount_setup_unit(
133,399✔
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;
133,399✔
1886
        MountProcFlags flags;
133,399✔
1887
        Unit *u;
133,399✔
1888
        int r;
133,399✔
1889

1890
        assert(m);
133,399✔
1891
        assert(what);
133,399✔
1892
        assert(where);
133,399✔
1893
        assert(options);
133,399✔
1894
        assert(fstype);
133,399✔
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) ||
215,513✔
1900
            mount_point_is_credentials(m->prefix[EXEC_DIRECTORY_RUNTIME], where))
82,114✔
1901
                return 0;
53,848✔
1902

1903
        if (streq(fstype, "autofs"))
79,551✔
1904
                return 0;
1905

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

1910
        r = unit_name_from_path(where, ".mount", &e);
73,921✔
1911
        if (r < 0)
73,921✔
1912
                return log_struct_errno(
×
1913
                                LOG_WARNING, r,
1914
                                LOG_MESSAGE_ID(SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE_STR),
1915
                                LOG_ITEM("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);
73,921✔
1920
        if (u)
73,921✔
1921
                r = mount_setup_existing_unit(u, what, where, options, fstype, &flags);
67,798✔
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);
6,123✔
1926
        if (r < 0)
73,921✔
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))
73,921✔
1931
                unit_add_to_dbus_queue(u);
6,723✔
1932

1933
        if (set_flags)
73,921✔
1934
                MOUNT(u)->proc_flags = flags;
138,072✔
1935

1936
        return 0;
1937
}
1938

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

1945
        assert(m);
4,198✔
1946

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

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

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

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

1966
                if (!device || !path)
133,399✔
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)
133,399✔
1973
                        device_found_node(m, device, DEVICE_FOUND_MOUNT, DEVICE_FOUND_MOUNT);
67,144✔
1974

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

1978
        return 0;
4,198✔
1979
}
1980

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

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

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

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

1995
        Mount *m = ASSERT_PTR(MOUNT(u));
396✔
1996

1997
        assert(ucred);
396✔
1998
        assert(ts);
396✔
1999

2000
        if (m->control_pid.pid == ucred->pid && m->control_command) {
396✔
2001
                exec_status_handoff(&m->control_command->exec_status, ucred, ts);
396✔
2002
                unit_add_to_dbus_queue(u);
396✔
2003
        }
2004
}
396✔
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) {
273✔
2025
        Unit *u;
273✔
2026
        int r;
273✔
2027

2028
        assert(m);
273✔
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);
273✔
2034
        if (!u) {
273✔
2035
                r = unit_new_for_name(m, sizeof(Mount), SPECIAL_ROOT_MOUNT, &u);
273✔
2036
                if (r < 0)
273✔
2037
                        return (void) log_error_errno(r, "Failed to allocate the special %s unit: %m",
×
2038
                                                      SPECIAL_ROOT_MOUNT);
2039
        }
2040

2041
        u->perpetual = true;
273✔
2042
        MOUNT(u)->deserialized_state = MOUNT_MOUNTED;
273✔
2043

2044
        unit_add_to_load_queue(u);
273✔
2045
        unit_add_to_dbus_queue(u);
273✔
2046
}
2047

2048
static bool mount_is_mounted(Mount *m) {
157,540✔
2049
        assert(m);
157,540✔
2050

2051
        return UNIT(m)->perpetual || FLAGS_SET(m->proc_flags, MOUNT_PROC_IS_MOUNTED);
157,540✔
2052
}
2053

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

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

2063
                job_add_to_run_queue(j);
56✔
2064
        }
2065

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

2070
        return 0;
206✔
2071
}
2072

2073
static void mount_enumerate(Manager *m) {
273✔
2074
        int r;
273✔
2075

2076
        assert(m);
273✔
2077

2078
        mnt_init_debug(0);
273✔
2079

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

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

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

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

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

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

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

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

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

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

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

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

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

2156
        return;
2157

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

2162
static int drain_libmount(Manager *m) {
4,125✔
2163
        bool rescan = false;
4,125✔
2164
        int r;
4,125✔
2165

2166
        assert(m);
4,125✔
2167

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

2182
        return rescan;
4,125✔
2183
}
2184

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

2190
        assert(m);
4,125✔
2191

2192
        r = drain_libmount(m);
4,125✔
2193
        if (r <= 0)
4,125✔
2194
                return r;
2195

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

2202
                return 0;
2203
        }
2204

2205
        manager_dispatch_load_queue(m);
3,925✔
2206

2207
        LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
82,695✔
2208
                Mount *mount = MOUNT(u);
78,770✔
2209

2210
                if (!mount_is_mounted(mount)) {
78,770✔
2211

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

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

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

2224
                        switch (mount->state) {
10,960✔
2225

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

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

2243
                        default:
2244
                                ;
2245
                        }
2246

2247
                } else if (mount->proc_flags & (MOUNT_PROC_JUST_MOUNTED|MOUNT_PROC_JUST_CHANGED)) {
67,810✔
2248

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

2251
                        switch (mount->state) {
1,908✔
2252

2253
                        case MOUNT_DEAD:
1,665✔
2254
                        case MOUNT_FAILED:
2255

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

2263
                        case MOUNT_MOUNTING:
155✔
2264
                                mount_set_state(mount, MOUNT_MOUNTING_DONE);
155✔
2265
                                break;
2266

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

2275
                if (mount_is_mounted(mount) &&
78,770✔
2276
                    mount->from_proc_self_mountinfo &&
67,810✔
2277
                    mount->parameters_proc_self_mountinfo.what)
67,810✔
2278
                        /* Track devices currently used */
2279
                        if (set_put_strdup_full(&around, &path_hash_ops_free, mount->parameters_proc_self_mountinfo.what) < 0)
67,810✔
2280
                                log_oom();
×
2281

2282
                /* Reset the flags for later calls */
2283
                mount->proc_flags = 0;
78,770✔
2284
        }
2285

2286
        SET_FOREACH(what, gone) {
5,552✔
2287
                if (set_contains(around, what))
1,627✔
2288
                        continue;
1,422✔
2289

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

2294
        return 0;
3,925✔
2295
}
2296

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

2300
        assert(revents & EPOLLIN);
3,927✔
2301

2302
        return mount_process_proc_self_mountinfo(m);
3,927✔
2303
}
2304

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

2308
        assert(m);
×
2309

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2382
        if (!get_mount_parameters_fragment(m))
158✔
2383
                return -ENOENT;
×
2384

2385
        return 1;
2386
}
2387

2388
static int mount_subsystem_ratelimited(Manager *m) {
286✔
2389
        assert(m);
286✔
2390

2391
        if (!m->mount_event_source)
286✔
2392
                return false;
2393

2394
        return sd_event_source_is_ratelimited(m->mount_event_source);
286✔
2395
}
2396

2397
char* mount_get_where_escaped(const Mount *m) {
5,965✔
2398
        assert(m);
5,965✔
2399

2400
        if (!m->where)
5,965✔
2401
                return strdup("");
2✔
2402

2403
        return utf8_escape_invalid(m->where);
5,963✔
2404
}
2405

2406
char* mount_get_what_escaped(const Mount *m) {
1,245✔
2407
        _cleanup_free_ char *escaped = NULL;
2,490✔
2408
        const char *s = NULL;
1,245✔
2409

2410
        assert(m);
1,245✔
2411

2412
        if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
1,245✔
2413
                s = m->parameters_proc_self_mountinfo.what;
2414
        else if (m->from_fragment && m->parameters_fragment.what)
271✔
2415
                s = m->parameters_fragment.what;
2416

2417
        if (s) {
1,115✔
2418
                escaped = utf8_escape_invalid(s);
1,115✔
2419
                if (!escaped)
1,115✔
2420
                        return NULL;
×
2421
        }
2422

2423
        return escaped ? TAKE_PTR(escaped) : strdup("");
130✔
2424
}
2425

2426
char* mount_get_options_escaped(const Mount *m) {
1,245✔
2427
        const char *s = NULL;
1,245✔
2428

2429
        assert(m);
1,245✔
2430

2431
        if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options)
1,245✔
2432
                s = m->parameters_proc_self_mountinfo.options;
2433
        else if (m->from_fragment && m->parameters_fragment.options)
271✔
2434
                s = m->parameters_fragment.options;
2435
        if (!s)
1,028✔
2436
                return strdup("");
217✔
2437

2438
        return utf8_escape_invalid(s);
1,028✔
2439
}
2440

2441
const char* mount_get_fstype(const Mount *m) {
1,245✔
2442
        assert(m);
1,245✔
2443

2444
        if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype)
1,245✔
2445
                return m->parameters_proc_self_mountinfo.fstype;
2446

2447
        if (m->from_fragment && m->parameters_fragment.fstype)
271✔
2448
                return m->parameters_fragment.fstype;
117✔
2449

2450
        return NULL;
2451
}
2452

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

2459
DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
258✔
2460

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

2472
DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
9,798✔
2473

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

2482
        .sections =
2483
                "Unit\0"
2484
                "Mount\0"
2485
                "Install\0",
2486
        .private_section = "Mount",
2487

2488
        .can_transient = true,
2489
        .can_fail = true,
2490
        .exclude_from_switch_root_serialization = true,
2491

2492
        .init = mount_init,
2493
        .load = mount_load,
2494
        .done = mount_done,
2495

2496
        .coldplug = mount_coldplug,
2497
        .catchup = mount_catchup,
2498

2499
        .dump = mount_dump,
2500

2501
        .start = mount_start,
2502
        .stop = mount_stop,
2503

2504
        .reload = mount_reload,
2505
        .can_reload = mount_can_reload,
2506

2507
        .clean = mount_clean,
2508
        .can_clean = mount_can_clean,
2509

2510
        .serialize = mount_serialize,
2511
        .deserialize_item = mount_deserialize_item,
2512

2513
        .active_state = mount_active_state,
2514
        .sub_state_to_string = mount_sub_state_to_string,
2515

2516
        .will_restart = unit_will_restart_default,
2517

2518
        .may_gc = mount_may_gc,
2519
        .is_extrinsic = mount_is_extrinsic,
2520

2521
        .sigchld_event = mount_sigchld_event,
2522

2523
        .reset_failed = mount_reset_failed,
2524

2525
        .notify_handoff_timestamp = mount_handoff_timestamp,
2526

2527
        .control_pid = mount_control_pid,
2528

2529
        .bus_set_property = bus_mount_set_property,
2530
        .bus_commit_properties = bus_mount_commit_properties,
2531

2532
        .get_timeout = mount_get_timeout,
2533

2534
        .enumerate_perpetual = mount_enumerate_perpetual,
2535
        .enumerate = mount_enumerate,
2536
        .shutdown = mount_shutdown,
2537
        .subsystem_ratelimited = mount_subsystem_ratelimited,
2538

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

2556
        .can_start = mount_can_start,
2557

2558
        .notify_plymouth = true,
2559
};
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