GCC Code Coverage Report


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