GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/auto_umount.cc
Date: 2025-06-22 02:36:02
Exec Total Coverage
Lines: 0 39 0.0%
Branches: 0 55 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 <map>
14 #include <set>
15 #include <string>
16 #include <vector>
17
18 #include "util/logging.h"
19 #include "util/platform.h"
20 #include "util/posix.h"
21
22 using namespace std; // NOLINT
23
24 namespace auto_umount {
25
26 string *mountpoint_ = NULL;
27
28 void SetMountpoint(const string &mountpoint) {
29 if (mountpoint == "") {
30 delete mountpoint_;
31 mountpoint_ = NULL;
32 } else {
33 mountpoint_ = new string(mountpoint);
34 }
35 }
36
37
38 void UmountOnCrash() {
39 if (!mountpoint_) {
40 LogCvmfs(kLogCvmfs, kLogSyslogErr, "crash cleanup handler: no mountpoint");
41 return;
42 }
43
44 std::vector<std::string> all_mountpoints = platform_mountlist();
45 if (all_mountpoints.empty()) {
46 LogCvmfs(kLogCvmfs, kLogSyslogErr,
47 "crash cleanup handler: "
48 "failed to read mount point list");
49 return;
50 }
51
52 // Mitigate auto-mount - crash - umount - auto-mount loops
53 SafeSleepMs(2000);
54
55 // Check if *mountpoint_ is still mounted
56 // (we don't want to trigger a mount by immediately doing stat *mountpoint_)
57 bool still_mounted = false;
58 for (unsigned i = 0; i < all_mountpoints.size(); ++i) {
59 if (*mountpoint_ == all_mountpoints[i]) {
60 still_mounted = true;
61 break;
62 }
63 }
64 if (!still_mounted) {
65 LogCvmfs(kLogCvmfs, kLogSyslog, "crash cleanup handler: %s not mounted",
66 mountpoint_->c_str());
67 return;
68 }
69
70 // stat() might be served from caches. Opendir ensures fuse module is called.
71 int expected_error;
72 #ifdef __APPLE__
73 expected_error = ENXIO;
74 #else
75 expected_error = ENOTCONN;
76 #endif
77 DIR *dirp = opendir(mountpoint_->c_str());
78 if (dirp || (errno != expected_error)) {
79 if (dirp)
80 closedir(dirp);
81 LogCvmfs(kLogCvmfs, kLogSyslog,
82 "crash cleanup handler: "
83 "%s seems not to be stalled (%d)",
84 mountpoint_->c_str(), errno);
85 return;
86 }
87
88 // sudo umount -l *mountpoint_
89 if (!SwitchCredentials(0, getegid(), true)) {
90 LogCvmfs(kLogCvmfs, kLogSyslogErr,
91 "crash cleanup handler: "
92 "failed to re-gain root privileges");
93 return;
94 }
95 const bool lazy = true;
96 bool retval = platform_umount(mountpoint_->c_str(), lazy);
97 if (!retval) {
98 LogCvmfs(kLogCvmfs, kLogSyslogErr,
99 "crash cleanup handler: "
100 "failed to unmount %s",
101 mountpoint_->c_str());
102 return;
103 }
104
105 LogCvmfs(kLogCvmfs, kLogSyslog, "crash cleanup handler unmounted stalled %s",
106 mountpoint_->c_str());
107 }
108
109 } // namespace auto_umount
110