GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/auto_umount.cc
Date: 2026-10-04 02:40:33
Exec Total Coverage
Lines: 0 49 0.0%
Branches: 0 71 0.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5
6 #include "auto_umount.h"
7
8 #include <dirent.h>
9 #include <errno.h>
10 #include <sys/types.h>
11 #include <unistd.h>
12
13 #include <string>
14 #include <vector>
15
16 #include "util/capabilities.h"
17 #include "util/logging.h"
18 #include "util/platform.h"
19 #include "util/posix.h"
20
21 using namespace std; // NOLINT
22
23 namespace auto_umount {
24
25 string *mountpoint_ = NULL;
26
27 ✗ void SetMountpoint(const string &mountpoint) {
28 ✗ if (mountpoint == "") {
29 ✗ delete mountpoint_;
30 ✗ mountpoint_ = NULL;
31 } else {
32 ✗ mountpoint_ = new string(mountpoint);
33 }
34 }
35
36
37 ✗ void UmountOnExit(const bool crashed) {
38 ✗ const char *cleanuptype = "exit";
39 ✗ if (crashed)
40 ✗ cleanuptype = "crash";
41
42 ✗ if (!mountpoint_) {
43 ✗ LogCvmfs(kLogCvmfs, kLogSyslogErr,
44 "%s cleanup handler: no mountpoint",
45 cleanuptype);
46 ✗ return;
47 }
48
49 ✗ std::vector<std::string> all_mountpoints = platform_mountlist();
50 ✗ if (all_mountpoints.empty()) {
51 ✗ LogCvmfs(kLogCvmfs, kLogSyslogErr,
52 "%s cleanup handler: "
53 "failed to read mount point list",
54 cleanuptype);
55 ✗ return;
56 }
57
58 ✗ if (crashed) {
59 // Mitigate auto-mount - crash - umount - auto-mount loops
60 ✗ SafeSleepMs(2000);
61 }
62
63 // Check if *mountpoint_ is still mounted
64 // (we don't want to trigger a mount by immediately doing stat *mountpoint_)
65 ✗ bool still_mounted = false;
66 ✗ for (unsigned i = 0; i < all_mountpoints.size(); ++i) {
67 ✗ if (*mountpoint_ == all_mountpoints[i]) {
68 ✗ still_mounted = true;
69 ✗ break;
70 }
71 }
72 ✗ if (!still_mounted) {
73 ✗ int logtype = kLogDebug;
74 ✗ if (crashed)
75 ✗ logtype = kLogSyslog;
76 ✗ LogCvmfs(kLogCvmfs, logtype,
77 "%s cleanup handler: %s not mounted",
78 cleanuptype, mountpoint_->c_str());
79 ✗ return;
80 }
81
82 ✗ if (crashed) {
83 // stat() might be served from caches. Opendir ensures fuse module is called.
84 int expected_error;
85 #ifdef __APPLE__
86 expected_error = ENXIO;
87 #else
88 ✗ expected_error = ENOTCONN;
89 #endif
90 ✗ DIR *dirp = opendir(mountpoint_->c_str());
91 ✗ if (dirp || (errno != expected_error)) {
92 ✗ if (dirp)
93 ✗ closedir(dirp);
94 ✗ LogCvmfs(kLogCvmfs, kLogSyslog, "crash cleanup handler: "
95 "%s seems not to be stalled (%d)",
96 ✗ mountpoint_->c_str(), errno);
97 ✗ return;
98 }
99 }
100
101 // sudo umount -l *mountpoint_
102 ✗ if (!ObtainSysAdminCapability()) {
103 ✗ LogCvmfs(kLogCvmfs, kLogSyslogErr,
104 "%s cleanup handler: "
105 "failed to re-gain sys_admin capability",
106 cleanuptype);
107 ✗ return;
108 }
109 ✗ const bool lazy = true;
110 ✗ bool const retval = platform_umount(mountpoint_->c_str(), lazy);
111 ✗ if (!retval) {
112 ✗ LogCvmfs(kLogCvmfs, kLogSyslogErr,
113 "%s cleanup handler: "
114 "failed to unmount %s",
115 cleanuptype, mountpoint_->c_str());
116 ✗ return;
117 }
118
119 ✗ if (crashed) {
120 ✗ LogCvmfs(kLogCvmfs, kLogSyslog,
121 "crash cleanup handler unmounted stalled %s",
122 mountpoint_->c_str());
123 } else {
124 ✗ LogCvmfs(kLogCvmfs, kLogSyslog,
125 "exit cleanup handler unmounted %s",
126 mountpoint_->c_str());
127 }
128 }
129
130 } // namespace auto_umount
131