Directory: | cvmfs/ |
---|---|
File: | cvmfs/quota.h |
Date: | 2025-02-09 02:34:19 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 16 | 40 | 40.0% |
Branches: | 2 | 4 | 50.0% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * This file is part of the CernVM File System. | ||
3 | */ | ||
4 | |||
5 | #ifndef CVMFS_QUOTA_H_ | ||
6 | #define CVMFS_QUOTA_H_ | ||
7 | |||
8 | #include <pthread.h> | ||
9 | #include <stdint.h> | ||
10 | #include <unistd.h> | ||
11 | |||
12 | #include <map> | ||
13 | #include <string> | ||
14 | #include <vector> | ||
15 | |||
16 | #include "crypto/hash.h" | ||
17 | #include "util/single_copy.h" | ||
18 | |||
19 | /** | ||
20 | * The QuotaManager keeps track of the cache contents. It is informed by the | ||
21 | * cache manager about opens and inserts. The cache manager picks a quota | ||
22 | * manager that fits to the backend storage (e.g. POSIX, key-value store). File | ||
23 | * catalogs are "pinned" in the quota manager. Since they remain loaded | ||
24 | * (virtual file descriptor stays open), it does not make sense to remove them. | ||
25 | * Regular files might get pinned occasionally as well, for instance for the | ||
26 | * CernVM "core files". | ||
27 | * | ||
28 | * Multiple cache managers can share a single quota manager instance, as it is | ||
29 | * done for the local shared hard disk cache. | ||
30 | * | ||
31 | * Sometimes it is necessary that a quota manager instance gives feedback to its | ||
32 | * users. This is where back channels are used. Users can register a back | ||
33 | * channel, which gets informed for instance if the number of pinned catalogs | ||
34 | * get large and should be released. | ||
35 | */ | ||
36 | class QuotaManager : SingleCopy { | ||
37 | public: | ||
38 | /** | ||
39 | * Quota manager protocol revision. | ||
40 | * Revision 1: | ||
41 | * - backchannel command 'R': release pinned files if possible | ||
42 | * Revision 2: | ||
43 | * - add kCleanupRate command | ||
44 | */ | ||
45 | static const uint32_t kProtocolRevision; | ||
46 | |||
47 | enum Capabilities { | ||
48 | kCapIntrospectSize = 0, | ||
49 | kCapIntrospectCleanupRate, | ||
50 | kCapList, | ||
51 | kCapShrink, | ||
52 | kCapListeners, | ||
53 | }; | ||
54 | |||
55 | QuotaManager(); | ||
56 | virtual ~QuotaManager(); | ||
57 | virtual bool HasCapability(Capabilities capability) = 0; | ||
58 | |||
59 | virtual void Insert(const shash::Any &hash, const uint64_t size, | ||
60 | const std::string &description) = 0; | ||
61 | virtual void InsertVolatile(const shash::Any &hash, const uint64_t size, | ||
62 | const std::string &description) = 0; | ||
63 | virtual bool Pin(const shash::Any &hash, const uint64_t size, | ||
64 | const std::string &description, const bool is_catalog) = 0; | ||
65 | virtual void Unpin(const shash::Any &hash) = 0; | ||
66 | virtual void Touch(const shash::Any &hash) = 0; | ||
67 | virtual void Remove(const shash::Any &file) = 0; | ||
68 | virtual bool Cleanup(const uint64_t leave_size) = 0; | ||
69 | |||
70 | virtual std::vector<std::string> List() = 0; | ||
71 | virtual std::vector<std::string> ListPinned() = 0; | ||
72 | virtual std::vector<std::string> ListCatalogs() = 0; | ||
73 | virtual std::vector<std::string> ListVolatile() = 0; | ||
74 | virtual uint64_t GetMaxFileSize() = 0; | ||
75 | virtual uint64_t GetCapacity() = 0; | ||
76 | virtual uint64_t GetSize() = 0; | ||
77 | virtual uint64_t GetSizePinned() = 0; | ||
78 | virtual bool SetLimit(uint64_t limit) = 0; | ||
79 | virtual uint64_t GetCleanupRate(uint64_t period_s) = 0; | ||
80 | |||
81 | virtual void Spawn() = 0; | ||
82 | virtual pid_t GetPid() = 0; | ||
83 | virtual uint32_t GetProtocolRevision() = 0; | ||
84 | |||
85 | virtual void RegisterBackChannel(int back_channel[2], | ||
86 | const std::string &channel_id) = 0; | ||
87 | virtual void UnregisterBackChannel(int back_channel[2], | ||
88 | const std::string &channel_id) = 0; | ||
89 | void BroadcastBackchannels(const std::string &message); | ||
90 | |||
91 | protected: | ||
92 | /** | ||
93 | * Hashes over the channel identifier mapped to writing ends of pipes. | ||
94 | */ | ||
95 | std::map<shash::Md5, int> back_channels_; | ||
96 | pthread_mutex_t *lock_back_channels_; | ||
97 | 8 | void LockBackChannels() { | |
98 | 8 | int retval = pthread_mutex_lock(lock_back_channels_); | |
99 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | assert(retval == 0); |
100 | 8 | } | |
101 | 8 | void UnlockBackChannels() { | |
102 | 8 | int retval = pthread_mutex_unlock(lock_back_channels_); | |
103 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | assert(retval == 0); |
104 | 8 | } | |
105 | |||
106 | /** | ||
107 | * Protocol of the running cache manager instance. Needs to be figured out | ||
108 | * and set during initialization of concrete instances. | ||
109 | */ | ||
110 | uint32_t protocol_revision_; | ||
111 | }; | ||
112 | |||
113 | |||
114 | /** | ||
115 | * No quota management. | ||
116 | */ | ||
117 | class NoopQuotaManager : public QuotaManager { | ||
118 | public: | ||
119 | 872 | virtual ~NoopQuotaManager() { } | |
120 | ✗ | virtual bool HasCapability(Capabilities capability) { return false; } | |
121 | |||
122 | 94 | virtual void Insert(const shash::Any &hash, const uint64_t size, | |
123 | 94 | const std::string &description) { } | |
124 | ✗ | virtual void InsertVolatile(const shash::Any &hash, const uint64_t size, | |
125 | ✗ | const std::string &description) { } | |
126 | 19 | virtual bool Pin(const shash::Any &hash, const uint64_t size, | |
127 | const std::string &description, const bool is_catalog) | ||
128 | { | ||
129 | 19 | return true; | |
130 | } | ||
131 | 13 | virtual void Unpin(const shash::Any &hash) { } | |
132 | 29 | virtual void Touch(const shash::Any &hash) { } | |
133 | ✗ | virtual void Remove(const shash::Any &file) { } | |
134 | ✗ | virtual bool Cleanup(const uint64_t leave_size) { return false; } | |
135 | |||
136 | ✗ | virtual void RegisterBackChannel(int back_channel[2], | |
137 | ✗ | const std::string &channel_id) { } | |
138 | ✗ | virtual void UnregisterBackChannel(int back_channel[2], | |
139 | ✗ | const std::string &channel_id) { } | |
140 | |||
141 | ✗ | virtual std::vector<std::string> List() { return std::vector<std::string>(); } | |
142 | ✗ | virtual std::vector<std::string> ListPinned() { | |
143 | ✗ | return std::vector<std::string>(); | |
144 | } | ||
145 | ✗ | virtual std::vector<std::string> ListCatalogs() { | |
146 | ✗ | return std::vector<std::string>(); | |
147 | } | ||
148 | ✗ | virtual std::vector<std::string> ListVolatile() { | |
149 | ✗ | return std::vector<std::string>(); | |
150 | } | ||
151 | 107 | virtual uint64_t GetMaxFileSize() { return uint64_t(-1); } | |
152 | ✗ | virtual uint64_t GetCapacity() { return uint64_t(-1); } | |
153 | ✗ | virtual uint64_t GetSize() { return 0; } | |
154 | ✗ | virtual uint64_t GetSizePinned() { return 0; } | |
155 | ✗ | virtual bool SetLimit(uint64_t) {return false;} | |
156 | ✗ | virtual uint64_t GetCleanupRate(uint64_t period_s) { return 0; } | |
157 | |||
158 | ✗ | virtual void Spawn() { } | |
159 | ✗ | virtual pid_t GetPid() { return getpid(); } | |
160 | ✗ | virtual uint32_t GetProtocolRevision() { return 0; } | |
161 | }; | ||
162 | |||
163 | #endif // CVMFS_QUOTA_H_ | ||
164 |