GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/cache_posix.h
Date: 2024-04-21 02:33:16
Exec Total Coverage
Lines: 27 32 84.4%
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 }
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 38 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 = false);
77 668 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 145 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,
90 const int flags,
91 void *txn);
92 virtual int64_t Write(const void *buf, uint64_t size, void *txn);
93 virtual int Reset(void *txn);
94 virtual int OpenFromTxn(void *txn);
95 virtual int AbortTxn(void *txn);
96 virtual int CommitTxn(void *txn);
97
98 virtual void Spawn() { }
99
100 virtual manifest::Breadcrumb LoadBreadcrumb(const std::string &fqrn);
101 virtual bool StoreBreadcrumb(const manifest::Manifest &manifest);
102 bool StoreBreadcrumb(std::string fqrn, manifest::Breadcrumb breadcrumb);
103
104 void TearDown2ReadOnly();
105 CacheModes cache_mode() { return cache_mode_; }
106 bool alien_cache() { return alien_cache_; }
107 3 std::string cache_path() { return cache_path_; }
108 34 bool is_tmpfs() { return is_tmpfs_; }
109 bool do_refcount() const { return do_refcount_; }
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 162 Transaction(const shash::Any &id, const std::string &final_path)
121 162 : buf_pos(0)
122 162 , size(0)
123 162 , expected_size(kSizeUnknown)
124 162 , fd(-1)
125 162 , label()
126 162 , tmp_path()
127
1/2
✓ Branch 1 taken 162 times.
✗ Branch 2 not taken.
162 , final_path(final_path)
128 162 , id(id)
129 162 { }
130
131 unsigned char buffer[4096];
132 unsigned buf_pos;
133 uint64_t size;
134 uint64_t expected_size;
135 int fd;
136 Label label;
137 std::string tmp_path;
138 std::string final_path;
139 shash::Any id;
140 };
141
142 169 PosixCacheManager(const std::string &cache_path, const bool alien_cache,
143 const bool do_refcount = false)
144 338 : cache_path_(cache_path)
145
1/2
✓ Branch 1 taken 169 times.
✗ Branch 2 not taken.
169 , txn_template_path_(cache_path_ + "/txn/fetchXXXXXX")
146 169 , alien_cache_(alien_cache)
147 169 , rename_workaround_(kRenameNormal)
148 169 , cache_mode_(kCacheReadWrite)
149 169 , reports_correct_filesize_(true)
150 169 , is_tmpfs_(false)
151 169 , do_refcount_(do_refcount)
152
4/8
✓ Branch 2 taken 169 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 169 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 169 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 169 times.
✗ Branch 12 not taken.
338 , fd_mgr_(new FdRefcountMgr())
153 {
154 169 atomic_init32(&no_inflight_txns_);
155 169 }
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 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 }; // class PosixCacheManager
201
202 #endif // CVMFS_CACHE_POSIX_H_
203