CernVM-FS  2.12.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 LabeledObject &object,
81  const unsigned char *buffer,
82  const uint64_t size)
83 {
84  void *txn = alloca(this->SizeOfTxn());
85  int fd = this->StartTxn(object.id, size, txn);
86  if (fd < 0)
87  return false;
88  this->CtrlTxn(object.label, 0, txn);
89  int64_t retval = this->Write(buffer, size, txn);
90  if ((retval < 0) || (static_cast<uint64_t>(retval) != size)) {
91  this->AbortTxn(txn);
92  return false;
93  }
94  retval = this->CommitTxn(txn);
95  return retval == 0;
96 }
97 
98 
99 void CacheManager::FreeState(const int fd_progress, void *data) {
100  State *state = reinterpret_cast<State *>(data);
101  if (fd_progress >= 0)
102  SendMsg2Socket(fd_progress, "Releasing saved open files table\n");
103  assert(state->version == kStateVersion);
104  assert(state->manager_type == id());
105  bool result = DoFreeState(state->concrete_state);
106  if (!result) {
107  if (fd_progress >= 0) {
108  SendMsg2Socket(fd_progress,
109  " *** Releasing open files table failed!\n");
110  }
111  abort();
112  }
113  delete state;
114 }
115 
116 
127  const LabeledObject &object,
128  unsigned char **buffer,
129  uint64_t *size)
130 {
131  *size = 0;
132  *buffer = NULL;
133 
134  int fd = this->Open(object);
135  if (fd < 0)
136  return false;
137 
138  int64_t s = this->GetSize(fd);
139  assert(s >= 0);
140  *size = static_cast<uint64_t>(s);
141 
142  int64_t retval = 0;
143  if (*size > 0) {
144  *buffer = static_cast<unsigned char *>(smalloc(*size));
145  retval = this->Pread(fd, *buffer, *size, 0);
146  } else {
147  *buffer = NULL;
148  }
149 
150  this->Close(fd);
151  if ((retval < 0) || (static_cast<uint64_t>(retval) != *size)) {
152  free(*buffer);
153  *buffer = NULL;
154  *size = 0;
155  return false;
156  }
157  return true;
158 }
159 
160 
169  int fd = this->Open(object);
170  if (fd >= 0) {
171  int64_t size = this->GetSize(fd);
172  if (size < 0) {
173  this->Close(fd);
174  return size;
175  }
176  bool retval = quota_mgr_->Pin(
177  object.id, static_cast<uint64_t>(size),
178  object.label.GetDescription(), object.label.IsCatalog());
179  if (!retval) {
180  this->Close(fd);
181  return -ENOSPC;
182  }
183  }
184  return fd;
185 }
186 
187 
188 int CacheManager::RestoreState(const int fd_progress, void *data) {
189  State *state = reinterpret_cast<State *>(data);
190  if (fd_progress >= 0)
191  SendMsg2Socket(fd_progress, "Restoring open files table... ");
192  if (state->version != kStateVersion) {
193  if (fd_progress >= 0)
194  SendMsg2Socket(fd_progress, "unsupported state version!\n");
195  abort();
196  }
197  if (state->manager_type != id()) {
198  if (fd_progress >= 0)
199  SendMsg2Socket(fd_progress, "switching cache manager unsupported!\n");
200  abort();
201  }
202  int new_root_fd = DoRestoreState(state->concrete_state);
203  if (new_root_fd < -1) {
204  if (fd_progress >= 0) SendMsg2Socket(fd_progress, "FAILED!\n");
205  abort();
206  }
207  if (fd_progress >= 0) SendMsg2Socket(fd_progress, "done\n");
208  return new_root_fd;
209 }
210 
211 
215 void *CacheManager::SaveState(const int fd_progress) {
216  if (fd_progress >= 0)
217  SendMsg2Socket(fd_progress, "Saving open files table\n");
218  State *state = new State();
219  state->manager_type = id();
220  state->concrete_state = DoSaveState();
221  if (state->concrete_state == NULL) {
222  if (fd_progress >= 0) {
223  SendMsg2Socket(fd_progress,
224  " *** This cache manager does not support saving state!\n");
225  }
226  abort();
227  }
228  return state;
229 }
int ChecksumFd(int fd, shash::Any *id)
Definition: cache.cc:39
virtual int64_t GetSize(int fd)=0
int RestoreState(const int fd_progress, void *state)
Definition: cache.cc:188
int OpenPinned(const LabeledObject &object)
Definition: cache.cc:168
virtual ~CacheManager()
Definition: cache.cc:30
CacheManagerIds manager_type
Definition: cache.h:252
void * SaveState(const int fd_progress)
Definition: cache.cc:215
unsigned version
Definition: cache.h:251
void SendMsg2Socket(const int fd, const std::string &msg)
Definition: posix.cc:659
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 void * DoSaveState()
Definition: cache.h:228
virtual bool DoFreeState(void *data)
Definition: cache.h:230
virtual CacheManagerIds id()=0
void * concrete_state
Definition: cache.h:253
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:206
virtual int DoRestoreState(void *data)
Definition: cache.h:229
virtual int CommitTxn(void *txn)=0
void CompressFini(z_stream *strm)
Definition: compression.cc:196
bool CommitFromMem(const LabeledObject &object, const unsigned char *buffer, const uint64_t size)
Definition: cache.cc:79
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:501
virtual int Close(int fd)=0
void CompressInit(z_stream *strm)
Definition: compression.cc:174
static const unsigned kStateVersion
Definition: cache.h:238
void FreeState(const int fd_progress, void *state)
Definition: cache.cc:99
CacheManager()
Definition: cache.cc:27
virtual void CtrlTxn(const Label &label, const int flags, void *txn)=0
QuotaManager * quota_mgr_
Definition: cache.h:235
virtual uint32_t SizeOfTxn()=0
bool Open2Mem(const LabeledObject &object, unsigned char **buffer, uint64_t *size)
Definition: cache.cc:126
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:74