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 "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 uint64_t GetCleanupRate(uint64_t period_s) = 0; |
79 |
|
|
|
80 |
|
|
virtual void Spawn() = 0; |
81 |
|
|
virtual pid_t GetPid() = 0; |
82 |
|
|
virtual uint32_t GetProtocolRevision() = 0; |
83 |
|
|
|
84 |
|
|
virtual void RegisterBackChannel(int back_channel[2], |
85 |
|
|
const std::string &channel_id) = 0; |
86 |
|
|
virtual void UnregisterBackChannel(int back_channel[2], |
87 |
|
|
const std::string &channel_id) = 0; |
88 |
|
|
void BroadcastBackchannels(const std::string &message); |
89 |
|
|
|
90 |
|
|
protected: |
91 |
|
|
/** |
92 |
|
|
* Hashes over the channel identifier mapped to writing ends of pipes. |
93 |
|
|
*/ |
94 |
|
|
std::map<shash::Md5, int> back_channels_; |
95 |
|
|
pthread_mutex_t *lock_back_channels_; |
96 |
|
8 |
void LockBackChannels() { |
97 |
|
8 |
int retval = pthread_mutex_lock(lock_back_channels_); |
98 |
✗✓ |
8 |
assert(retval == 0); |
99 |
|
8 |
} |
100 |
|
8 |
void UnlockBackChannels() { |
101 |
|
8 |
int retval = pthread_mutex_unlock(lock_back_channels_); |
102 |
✗✓ |
8 |
assert(retval == 0); |
103 |
|
8 |
} |
104 |
|
|
|
105 |
|
|
/** |
106 |
|
|
* Protocol of the running cache manager instance. Needs to be figured out |
107 |
|
|
* and set during initialization of concrete instances. |
108 |
|
|
*/ |
109 |
|
|
uint32_t protocol_revision_; |
110 |
|
|
}; |
111 |
|
|
|
112 |
|
|
|
113 |
|
|
/** |
114 |
|
|
* No quota management. |
115 |
|
|
*/ |
116 |
|
393 |
class NoopQuotaManager : public QuotaManager { |
117 |
|
|
public: |
118 |
✗✓ |
646 |
virtual ~NoopQuotaManager() { } |
119 |
|
|
virtual bool HasCapability(Capabilities capability) { return false; } |
120 |
|
|
|
121 |
|
113 |
virtual void Insert(const shash::Any &hash, const uint64_t size, |
122 |
|
113 |
const std::string &description) { } |
123 |
|
|
virtual void InsertVolatile(const shash::Any &hash, const uint64_t size, |
124 |
|
|
const std::string &description) { } |
125 |
|
25 |
virtual bool Pin(const shash::Any &hash, const uint64_t size, |
126 |
|
|
const std::string &description, const bool is_catalog) |
127 |
|
|
{ |
128 |
|
25 |
return true; |
129 |
|
|
} |
130 |
|
9 |
virtual void Unpin(const shash::Any &hash) { } |
131 |
|
45 |
virtual void Touch(const shash::Any &hash) { } |
132 |
|
|
virtual void Remove(const shash::Any &file) { } |
133 |
|
|
virtual bool Cleanup(const uint64_t leave_size) { return false; } |
134 |
|
|
|
135 |
|
|
virtual void RegisterBackChannel(int back_channel[2], |
136 |
|
|
const std::string &channel_id) { } |
137 |
|
|
virtual void UnregisterBackChannel(int back_channel[2], |
138 |
|
|
const std::string &channel_id) { } |
139 |
|
|
|
140 |
|
|
virtual std::vector<std::string> List() { return std::vector<std::string>(); } |
141 |
|
|
virtual std::vector<std::string> ListPinned() { |
142 |
|
|
return std::vector<std::string>(); |
143 |
|
|
} |
144 |
|
|
virtual std::vector<std::string> ListCatalogs() { |
145 |
|
|
return std::vector<std::string>(); |
146 |
|
|
} |
147 |
|
|
virtual std::vector<std::string> ListVolatile() { |
148 |
|
|
return std::vector<std::string>(); |
149 |
|
|
} |
150 |
|
123 |
virtual uint64_t GetMaxFileSize() { return uint64_t(-1); } |
151 |
|
|
virtual uint64_t GetCapacity() { return uint64_t(-1); } |
152 |
|
|
virtual uint64_t GetSize() { return 0; } |
153 |
|
|
virtual uint64_t GetSizePinned() { return 0; } |
154 |
|
|
virtual uint64_t GetCleanupRate(uint64_t period_s) { return 0; } |
155 |
|
|
|
156 |
|
|
virtual void Spawn() { } |
157 |
|
|
virtual pid_t GetPid() { return getpid(); } |
158 |
|
|
virtual uint32_t GetProtocolRevision() { return 0; } |
159 |
|
|
}; |
160 |
|
|
|
161 |
|
|
#endif // CVMFS_QUOTA_H_ |