GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/auto_umount.cc
Date: 2024-04-28 02:33:07
Exec Total Coverage
Lines: 0 38 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 #include "cvmfs_config.h"
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, "crash cleanup handler: "
47 "failed to read mount point list");
48 return;
49 }
50
51 // Mitigate auto-mount - crash - umount - auto-mount loops
52 SafeSleepMs(2000);
53
54 // Check if *mountpoint_ is still mounted
55 // (we don't want to trigger a mount by immediately doing stat *mountpoint_)
56 bool still_mounted = false;
57 for (unsigned i = 0; i < all_mountpoints.size(); ++i) {
58 if (*mountpoint_ == all_mountpoints[i]) {
59 still_mounted = true;
60 break;
61 }
62 }
63 if (!still_mounted) {
64 LogCvmfs(kLogCvmfs, kLogSyslog, "crash cleanup handler: %s not mounted",
65 mountpoint_->c_str());
66 return;
67 }
68
69 // stat() might be served from caches. Opendir ensures fuse module is called.
70 int expected_error;
71 #ifdef __APPLE__
72 expected_error = ENXIO;
73 #else
74 expected_error = ENOTCONN;
75 #endif
76 DIR *dirp = opendir(mountpoint_->c_str());
77 if (dirp || (errno != expected_error)) {
78 if (dirp) closedir(dirp);
79 LogCvmfs(kLogCvmfs, kLogSyslog, "crash cleanup handler: "
80 "%s seems not to be stalled (%d)", mountpoint_->c_str(), errno);
81 return;
82 }
83
84 // sudo umount -l *mountpoint_
85 if (!SwitchCredentials(0, getegid(), true)) {
86 LogCvmfs(kLogCvmfs, kLogSyslogErr, "crash cleanup handler: "
87 "failed to re-gain root privileges");
88 return;
89 }
90 const bool lazy = true;
91 bool retval = platform_umount(mountpoint_->c_str(), lazy);
92 if (!retval) {
93 LogCvmfs(kLogCvmfs, kLogSyslogErr, "crash cleanup handler: "
94 "failed to unmount %s", mountpoint_->c_str());
95 return;
96 }
97
98 LogCvmfs(kLogCvmfs, kLogSyslog, "crash cleanup handler unmounted stalled %s",
99 mountpoint_->c_str());
100 }
101
102 } // namespace auto_umount
103