CernVM-FS  2.11.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cache.cc
Go to the documentation of this file.
1 
4 #include "cvmfs_config.h"
5 #include "cache.h"
6 
7 #include <alloca.h>
8 #include <errno.h>
9 
10 #include <cassert>
11 #include <cstdlib>
12 #include <string>
13 
14 #include "compression.h"
15 #include "crypto/hash.h"
16 #include "directory_entry.h"
17 #include "network/download.h"
18 #include "quota.h"
19 #include "util/posix.h"
20 #include "util/smalloc.h"
21 
22 using namespace std; // NOLINT
23 
24 const uint64_t CacheManager::kSizeUnknown = uint64_t(-1);
25 
26 
28 
29 
31  delete quota_mgr_;
32 }
33 
34 
40  shash::ContextPtr hash_context(id->algorithm);
41  hash_context.buffer = alloca(hash_context.size);
42  shash::Init(hash_context);
43 
44  z_stream strm;
45  zlib::CompressInit(&strm);
46  zlib::StreamStates retval;
47 
48  unsigned char buf[4096];
49  uint64_t pos = 0;
50  bool eof;
51 
52  do {
53  int64_t nbytes = Pread(fd, buf, 4096, pos);
54  if (nbytes < 0) {
55  zlib::CompressFini(&strm);
56  return nbytes;
57  }
58  pos += nbytes;
59  eof = nbytes < 4096;
60  retval = zlib::CompressZStream2Null(buf, nbytes, eof, &strm, &hash_context);
61  if (retval == zlib::kStreamDataError) {
62  zlib::CompressFini(&strm);
63  return -EINVAL;
64  }
65  } while (!eof);
66 
67  zlib::CompressFini(&strm);
68  if (retval != zlib::kStreamEnd)
69  return -EINVAL;
70  shash::Final(hash_context, id);
71  return 0;
72 }
73 
74 
80  const shash::Any &id,
81  const unsigned char *buffer,
82  const uint64_t size,
83  const string &description)
84 {
85  void *txn = alloca(this->SizeOfTxn());
86  int fd = this->StartTxn(id, size, txn);
87  if (fd < 0)
88  return false;
89  this->CtrlTxn(ObjectInfo(kTypeRegular, description), 0, txn);
90  int64_t retval = this->Write(buffer, size, txn);
91  if ((retval < 0) || (static_cast<uint64_t>(retval) != size)) {
92  this->AbortTxn(txn);
93  return false;
94  }
95  retval = this->CommitTxn(txn);
96  return retval == 0;
97 }
98 
99 
100 void CacheManager::FreeState(const int fd_progress, void *data) {
101  State *state = reinterpret_cast<State *>(data);
102  if (fd_progress >= 0)
103  SendMsg2Socket(fd_progress, "Releasing saved open files table\n");
104  assert(state->version == kStateVersion);
105  assert(state->manager_type == id());
106  bool result = DoFreeState(state->concrete_state);
107  if (!result) {
108  if (fd_progress >= 0) {
109  SendMsg2Socket(fd_progress,
110  " *** Releasing open files table failed!\n");
111  }
112  abort();
113  }
114  delete state;
115 }
116 
117 
128  const shash::Any &id,
129  const std::string &description,
130  unsigned char **buffer,
131  uint64_t *size)
132 {
133  *size = 0;
134  *buffer = NULL;
135 
136  int fd = this->Open(Bless(id, kTypeRegular, description));
137  if (fd < 0)
138  return false;
139 
140  int64_t s = this->GetSize(fd);
141  assert(s >= 0);
142  *size = static_cast<uint64_t>(s);
143 
144  int64_t retval = 0;
145  if (*size > 0) {
146  *buffer = static_cast<unsigned char *>(smalloc(*size));
147  retval = this->Pread(fd, *buffer, *size, 0);
148  } else {
149  *buffer = NULL;
150  }
151 
152  this->Close(fd);
153  if ((retval < 0) || (static_cast<uint64_t>(retval) != *size)) {
154  free(*buffer);
155  *buffer = NULL;
156  *size = 0;
157  return false;
158  }
159  return true;
160 }
161 
162 
171  const shash::Any &id,
172  const string &description,
173  bool is_catalog)
174 {
175  ObjectInfo object_info(is_catalog ? kTypeCatalog : kTypeRegular, description);
176  int fd = this->Open(Bless(id, object_info));
177  if (fd >= 0) {
178  int64_t size = this->GetSize(fd);
179  if (size < 0) {
180  this->Close(fd);
181  return size;
182  }
183  bool retval =
184  quota_mgr_->Pin(id, static_cast<uint64_t>(size), description, is_catalog);
185  if (!retval) {
186  this->Close(fd);
187  return -ENOSPC;
188  }
189  }
190  return fd;
191 }
192 
193 
194 int CacheManager::RestoreState(const int fd_progress, void *data) {
195  State *state = reinterpret_cast<State *>(data);
196  if (fd_progress >= 0)
197  SendMsg2Socket(fd_progress, "Restoring open files table... ");
198  if (state->version != kStateVersion) {
199  if (fd_progress >= 0)
200  SendMsg2Socket(fd_progress, "unsupported state version!\n");
201  abort();
202  }
203  if (state->manager_type != id()) {
204  if (fd_progress >= 0)
205  SendMsg2Socket(fd_progress, "switching cache manager unsupported!\n");
206  abort();
207  }
208  int new_root_fd = DoRestoreState(state->concrete_state);
209  if (new_root_fd < -1) {
210  if (fd_progress >= 0) SendMsg2Socket(fd_progress, "FAILED!\n");
211  abort();
212  }
213  if (fd_progress >= 0) SendMsg2Socket(fd_progress, "done\n");
214  return new_root_fd;
215 }
216 
217 
221 void *CacheManager::SaveState(const int fd_progress) {
222  if (fd_progress >= 0)
223  SendMsg2Socket(fd_progress, "Saving open files table\n");
224  State *state = new State();
225  state->manager_type = id();
226  state->concrete_state = DoSaveState();
227  if (state->concrete_state == NULL) {
228  if (fd_progress >= 0) {
229  SendMsg2Socket(fd_progress,
230  " *** This cache manager does not support saving state!\n");
231  }
232  abort();
233  }
234  return state;
235 }
int ChecksumFd(int fd, shash::Any *id)
Definition: cache.cc:39
virtual int64_t GetSize(int fd)=0
int OpenPinned(const shash::Any &id, const std::string &description, bool is_catalog)
Definition: cache.cc:170
int RestoreState(const int fd_progress, void *state)
Definition: cache.cc:194
virtual ~CacheManager()
Definition: cache.cc:30
CacheManagerIds manager_type
Definition: cache.h:254
void * SaveState(const int fd_progress)
Definition: cache.cc:221
unsigned version
Definition: cache.h:253
void SendMsg2Socket(const int fd, const std::string &msg)
Definition: posix.cc:656
assert((mem||(size==0))&&"Out Of Memory")
virtual int AbortTxn(void *txn)=0
StreamStates
Definition: compression.h:36
Algorithms algorithm
Definition: hash.h:125
virtual int Open(const BlessedObject &object)=0
virtual void * DoSaveState()
Definition: cache.h:230
virtual bool DoFreeState(void *data)
Definition: cache.h:232
virtual CacheManagerIds id()=0
void * concrete_state
Definition: cache.h:255
void Init(ContextPtr context)
Definition: hash.cc:164
StreamStates CompressZStream2Null(const void *buf, const int64_t size, const bool eof, z_stream *strm, shash::ContextPtr *hash_context)
Definition: compression.cc:206
virtual int DoRestoreState(void *data)
Definition: cache.h:231
virtual int CommitTxn(void *txn)=0
void CompressFini(z_stream *strm)
Definition: compression.cc:196
virtual bool Pin(const shash::Any &hash, const uint64_t size, const std::string &description, const bool is_catalog)=0
bool CommitFromMem(const shash::Any &id, const unsigned char *buffer, const uint64_t size, const std::string &description)
Definition: cache.cc:79
void Final(ContextPtr context, Any *any_digest)
Definition: hash.cc:221
bool Open2Mem(const shash::Any &id, const std::string &description, unsigned char **buffer, uint64_t *size)
Definition: cache.cc:127
void * buffer
Definition: hash.h:501
virtual int Close(int fd)=0
void CompressInit(z_stream *strm)
Definition: compression.cc:174
static const unsigned kStateVersion
Definition: cache.h:240
void FreeState(const int fd_progress, void *state)
Definition: cache.cc:100
static BlessedObject Bless(const shash::Any &id)
Definition: cache.h:125
CacheManager()
Definition: cache.cc:27
QuotaManager * quota_mgr_
Definition: cache.h:237
virtual uint32_t SizeOfTxn()=0
unsigned size
Definition: hash.h:502
virtual int StartTxn(const shash::Any &id, uint64_t size, void *txn)=0
static void size_t size
Definition: smalloc.h:54
virtual int64_t Pread(int fd, void *buf, uint64_t size, uint64_t offset)=0
virtual int64_t Write(const void *buf, uint64_t sz, void *txn)=0
static const uint64_t kSizeUnknown
Definition: cache.h:72
virtual void CtrlTxn(const ObjectInfo &object_info, const int flags, void *txn)=0