GCC Code Coverage Report


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