CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cache.cc
Go to the documentation of this file.
1 
5 #include "cache.h"
6 
7 #include <alloca.h>
8 #include <errno.h>
9 
10 #include <cassert>
11 #include <cstdlib>
12 #include <string>
13 
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 
32 
38  shash::ContextPtr hash_context(id->algorithm);
39  hash_context.buffer = alloca(hash_context.size);
40  shash::Init(hash_context);
41 
42  z_stream strm;
43  zlib::CompressInit(&strm);
44  zlib::StreamStates retval;
45 
46  unsigned char buf[4096];
47  uint64_t pos = 0;
48  bool eof;
49 
50  do {
51  const int64_t nbytes = Pread(fd, buf, 4096, pos);
52  if (nbytes < 0) {
53  zlib::CompressFini(&strm);
54  return nbytes;
55  }
56  pos += nbytes;
57  eof = nbytes < 4096;
58  retval = zlib::CompressZStream2Null(buf, nbytes, eof, &strm, &hash_context);
59  if (retval == zlib::kStreamDataError) {
60  zlib::CompressFini(&strm);
61  return -EINVAL;
62  }
63  } while (!eof);
64 
65  zlib::CompressFini(&strm);
66  if (retval != zlib::kStreamEnd)
67  return -EINVAL;
68  shash::Final(hash_context, id);
69  return 0;
70 }
71 
72 
78  const unsigned char *buffer,
79  const uint64_t size) {
80  void *txn = alloca(this->SizeOfTxn());
81  const int fd = this->StartTxn(object.id, size, txn);
82  if (fd < 0)
83  return false;
84  this->CtrlTxn(object.label, 0, txn);
85  int64_t retval = this->Write(buffer, size, txn);
86  if ((retval < 0) || (static_cast<uint64_t>(retval) != size)) {
87  this->AbortTxn(txn);
88  return false;
89  }
90  retval = this->CommitTxn(txn);
91  return retval == 0;
92 }
93 
94 
95 void CacheManager::FreeState(const int fd_progress, void *data) {
96  State *state = reinterpret_cast<State *>(data);
97  if (fd_progress >= 0)
98  SendMsg2Socket(fd_progress, "Releasing saved open files table\n");
99  assert(state->version == kStateVersion);
100  assert(state->manager_type == id());
101  const bool result = DoFreeState(state->concrete_state);
102  if (!result) {
103  if (fd_progress >= 0) {
104  SendMsg2Socket(fd_progress,
105  " *** Releasing open files table failed!\n");
106  }
107  abort();
108  }
109  delete state;
110 }
111 
112 
123  unsigned char **buffer,
124  uint64_t *size) {
125  *size = 0;
126  *buffer = NULL;
127 
128  const int fd = this->Open(object);
129  if (fd < 0)
130  return false;
131 
132  const int64_t s = this->GetSize(fd);
133  assert(s >= 0);
134  *size = static_cast<uint64_t>(s);
135 
136  int64_t retval = 0;
137  if (*size > 0) {
138  *buffer = static_cast<unsigned char *>(smalloc(*size));
139  retval = this->Pread(fd, *buffer, *size, 0);
140  } else {
141  *buffer = NULL;
142  }
143 
144  this->Close(fd);
145  if ((retval < 0) || (static_cast<uint64_t>(retval) != *size)) {
146  free(*buffer);
147  *buffer = NULL;
148  *size = 0;
149  return false;
150  }
151  return true;
152 }
153 
154 
163  const int fd = this->Open(object);
164  if (fd >= 0) {
165  const int64_t size = this->GetSize(fd);
166  if (size < 0) {
167  this->Close(fd);
168  return size;
169  }
170  const bool retval = quota_mgr_->Pin(object.id, static_cast<uint64_t>(size),
171  object.label.GetDescription(),
172  object.label.IsCatalog());
173  if (!retval) {
174  this->Close(fd);
175  return -ENOSPC;
176  }
177  }
178  return fd;
179 }
180 
181 
182 int CacheManager::RestoreState(const int fd_progress, void *data) {
183  State *state = reinterpret_cast<State *>(data);
184  if (fd_progress >= 0)
185  SendMsg2Socket(fd_progress, "Restoring open files table... ");
186  if (state->version != kStateVersion) {
187  if (fd_progress >= 0)
188  SendMsg2Socket(fd_progress, "unsupported state version!\n");
189  abort();
190  }
191  if (state->manager_type != id()) {
192  if (fd_progress >= 0)
193  SendMsg2Socket(fd_progress, "switching cache manager unsupported!\n");
194  abort();
195  }
196  const int new_root_fd = DoRestoreState(state->concrete_state);
197  if (new_root_fd < -1) {
198  if (fd_progress >= 0)
199  SendMsg2Socket(fd_progress, "FAILED!\n");
200  abort();
201  }
202  if (fd_progress >= 0)
203  SendMsg2Socket(fd_progress, "done\n");
204  return new_root_fd;
205 }
206 
207 
211 void *CacheManager::SaveState(const int fd_progress) {
212  if (fd_progress >= 0)
213  SendMsg2Socket(fd_progress, "Saving open files table\n");
214  State *state = new State();
215  state->manager_type = id();
216  state->concrete_state = DoSaveState();
217  if (state->concrete_state == NULL) {
218  if (fd_progress >= 0) {
220  fd_progress,
221  " *** This cache manager does not support saving state!\n");
222  }
223  abort();
224  }
225  return state;
226 }
int ChecksumFd(int fd, shash::Any *id)
Definition: cache.cc:37
virtual int64_t GetSize(int fd)=0
int RestoreState(const int fd_progress, void *state)
Definition: cache.cc:182
int OpenPinned(const LabeledObject &object)
Definition: cache.cc:162
virtual ~CacheManager()
Definition: cache.cc:30
CacheManagerIds manager_type
Definition: cache.h:249
void * SaveState(const int fd_progress)
Definition: cache.cc:211
unsigned version
Definition: cache.h:248
void SendMsg2Socket(const int fd, const std::string &msg)
Definition: posix.cc:671
assert((mem||(size==0))&&"Out Of Memory")
virtual int AbortTxn(void *txn)=0
StreamStates
Definition: compression.h:36
Algorithms algorithm
Definition: hash.h:122
virtual void * DoSaveState()
Definition: cache.h:226
virtual bool DoFreeState(void *data)
Definition: cache.h:228
virtual CacheManagerIds id()=0
void * concrete_state
Definition: cache.h:250
virtual int Open(const LabeledObject &object)=0
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:207
virtual int DoRestoreState(void *data)
Definition: cache.h:227
virtual int CommitTxn(void *txn)=0
void CompressFini(z_stream *strm)
Definition: compression.cc:201
bool CommitFromMem(const LabeledObject &object, const unsigned char *buffer, const uint64_t size)
Definition: cache.cc:77
virtual bool Pin(const shash::Any &hash, const uint64_t size, const std::string &description, const bool is_catalog)=0
void Final(ContextPtr context, Any *any_digest)
Definition: hash.cc:221
void * buffer
Definition: hash.h:489
virtual int Close(int fd)=0
void CompressInit(z_stream *strm)
Definition: compression.cc:179
static const unsigned kStateVersion
Definition: cache.h:236
void FreeState(const int fd_progress, void *state)
Definition: cache.cc:95
CacheManager()
Definition: cache.cc:27
virtual void CtrlTxn(const Label &label, const int flags, void *txn)=0
QuotaManager * quota_mgr_
Definition: cache.h:233
virtual uint32_t SizeOfTxn()=0
bool Open2Mem(const LabeledObject &object, unsigned char **buffer, uint64_t *size)
Definition: cache.cc:122
unsigned size
Definition: hash.h:490
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:74