GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/cache_posix.h
Date: 2026-04-26 02:35:59
Exec Total Coverage
Lines: 28 33 84.8%
Branches: 6 12 50.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_CACHE_POSIX_H_
6 #define CVMFS_CACHE_POSIX_H_
7
8 #include <stdint.h>
9 #include <sys/types.h>
10
11 #include <string>
12
13 #include "cache.h"
14 #include "util/pointer.h"
15 #include "duplex_testing.h"
16 #include "fd_refcount_mgr.h"
17 #include "manifest_fetch.h"
18 #include "util/atomic.h"
19
20 namespace catalog {
21 class DirectoryEntry;
22 class Catalog;
23 } // namespace catalog
24
25 namespace download {
26 class DownloadManager;
27 }
28
29 /**
30 * Cache manager implementation using a file system (cache directory) as a
31 * backing storage.
32 */
33 class ListOpenHashesMagicXattr; // FD needed to access fd_mgr_
34 class PosixCacheManager : public CacheManager {
35 FRIEND_TEST(T_CacheManager, CommitTxnQuotaNotifications);
36 FRIEND_TEST(T_CacheManager, CommitTxnRenameFail);
37 FRIEND_TEST(T_CacheManager, Open);
38 FRIEND_TEST(T_CacheManager, OpenFromTxn);
39 FRIEND_TEST(T_CacheManager, OpenPinned);
40 FRIEND_TEST(T_CacheManager, Rename);
41 FRIEND_TEST(T_CacheManager, StartTxn);
42 FRIEND_TEST(T_CacheManager, TearDown2ReadOnly);
43 friend class ListOpenHashesMagicXattr;
44
45 public:
46 enum CacheModes {
47 kCacheReadWrite = 0,
48 kCacheReadOnly,
49 };
50
51 enum RenameWorkarounds {
52 kRenameNormal = 0,
53 kRenameLink,
54 kRenameSamedir
55 };
56
57 /**
58 * As of 25M, a file is considered a "big file", which means it is dangerous
59 * to apply asynchronous semantics. On start of a transaction with a big file
60 * the cache is cleaned up opportunistically.
61 */
62 static const uint64_t kBigFile;
63
64 1120 virtual CacheManagerIds id() { return kPosixCacheManager; }
65 virtual std::string Describe();
66
67 static PosixCacheManager *Create(
68 const std::string &cache_path, const bool alien_cache,
69 const RenameWorkarounds rename_workaround = kRenameNormal,
70 const bool do_refcount = true, const bool cleanup_unused_first = false);
71 24700 virtual ~PosixCacheManager() { }
72 virtual bool AcquireQuotaManager(QuotaManager *quota_mgr);
73
74 virtual int Open(const LabeledObject &object);
75 virtual int64_t GetSize(int fd);
76 virtual int Close(int fd);
77 virtual int64_t Pread(int fd, void *buf, uint64_t size, uint64_t offset);
78 virtual int Dup(int fd);
79 virtual int Readahead(int fd);
80
81 5384 virtual uint32_t SizeOfTxn() { return sizeof(Transaction); }
82 virtual int StartTxn(const shash::Any &id, uint64_t size, void *txn);
83 virtual void CtrlTxn(const Label &label, const int flags, void *txn);
84 virtual int64_t Write(const void *buf, uint64_t size, void *txn);
85 virtual int Reset(void *txn);
86 virtual int OpenFromTxn(void *txn);
87 virtual int AbortTxn(void *txn);
88 virtual int CommitTxn(void *txn);
89
90 virtual void Spawn() { }
91
92 virtual manifest::Breadcrumb LoadBreadcrumb(const std::string &fqrn);
93 virtual bool StoreBreadcrumb(const manifest::Manifest &manifest);
94 bool StoreBreadcrumb(std::string fqrn, manifest::Breadcrumb breadcrumb);
95
96 void TearDown2ReadOnly();
97 CacheModes cache_mode() { return cache_mode_; }
98 bool alien_cache() { return alien_cache_; }
99 81 std::string cache_path() { return cache_path_; }
100 940 bool is_tmpfs() { return is_tmpfs_; }
101 bool do_refcount() const { return do_refcount_; }
102 bool cleanup_unused_first() const { return cleanup_unused_first_; }
103
104 protected:
105 virtual void *DoSaveState();
106 virtual int DoRestoreState(void *data);
107 virtual bool DoFreeState(void *data);
108
109 private:
110 bool InitCacheDirectory(const std::string &cache_path);
111
112 struct Transaction {
113 6098 Transaction(const shash::Any &id, const std::string &final_path)
114 6098 : buf_pos(0)
115 6098 , size(0)
116 6098 , expected_size(kSizeUnknown)
117 6098 , fd(-1)
118 6098 , label()
119 6098 , tmp_path()
120
1/2
✓ Branch 1 taken 6098 times.
✗ Branch 2 not taken.
6098 , final_path(final_path)
121 6098 , id(id) { }
122
123 unsigned char buffer[4096];
124 unsigned buf_pos;
125 uint64_t size;
126 uint64_t expected_size;
127 int fd;
128 Label label;
129 std::string tmp_path;
130 std::string final_path;
131 shash::Any id;
132 };
133
134 6184 PosixCacheManager(const std::string &cache_path, const bool alien_cache,
135 const bool do_refcount = true,
136 const bool cleanup_unused_first = false)
137 12368 : cache_path_(cache_path)
138
1/2
✓ Branch 1 taken 6184 times.
✗ Branch 2 not taken.
6184 , txn_template_path_(cache_path_ + "/txn/fetchXXXXXX")
139 6184 , alien_cache_(alien_cache)
140 6184 , rename_workaround_(kRenameNormal)
141 6184 , cache_mode_(kCacheReadWrite)
142 6184 , reports_correct_filesize_(true)
143 6184 , is_tmpfs_(false)
144 6184 , do_refcount_(do_refcount)
145
3/6
✓ Branch 1 taken 6184 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6184 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6184 times.
✗ Branch 8 not taken.
6184 , fd_mgr_(new FdRefcountMgr())
146
1/2
✓ Branch 2 taken 6184 times.
✗ Branch 3 not taken.
6184 , cleanup_unused_first_(cleanup_unused_first) {
147 6184 atomic_init32(&no_inflight_txns_);
148 6184 }
149
150 std::string GetPathInCache(const shash::Any &id);
151 int Rename(const char *oldpath, const char *newpath);
152 int Flush(Transaction *transaction);
153
154
155 std::string cache_path_;
156 std::string txn_template_path_;
157 bool alien_cache_;
158 RenameWorkarounds rename_workaround_;
159 CacheModes cache_mode_;
160
161 /**
162 * The cache can only degrade to a read-only cache once all writable file
163 * descriptors from transactions are closed. This is indicated by a zero
164 * value in this variable.
165 */
166 atomic_int32 no_inflight_txns_;
167
168 static const char kMagicRefcount = 123;
169 static const char kMagicNoRefcount = '\0';
170 struct SavedState {
171 39 SavedState() : magic_number(kMagicRefcount), version(0), fd_mgr(NULL) { }
172 /// this helps to distinguish from the SavedState of the normal
173 /// posix cache manager
174 char magic_number;
175 unsigned int version;
176 UniquePtr<FdRefcountMgr> fd_mgr;
177 };
178
179 /**
180 * Hack for HDFS which writes file sizes asynchronously.
181 */
182 bool reports_correct_filesize_;
183
184 /**
185 * True if posixcache is on tmpfs (and with this already in RAM)
186 */
187 bool is_tmpfs_;
188 /**
189 * Refcount and return only unique file descriptors
190 */
191 bool do_refcount_;
192 UniquePtr<FdRefcountMgr> fd_mgr_;
193
194 bool cleanup_unused_first_;
195 }; // class PosixCacheManager
196
197 #endif // CVMFS_CACHE_POSIX_H_
198
199