CernVM-FS  2.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
libcvmfs_int.cc
Go to the documentation of this file.
1 
9 #define ENOATTR ENODATA
11 #include <sys/xattr.h>
12 #include "cvmfs_config.h"
13 #include "libcvmfs_int.h"
14 
15 #include <dirent.h>
16 #include <errno.h>
17 #include <fcntl.h>
18 #include <google/dense_hash_map>
19 #include <openssl/crypto.h>
20 #include <pthread.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 #include <sys/errno.h>
24 #include <sys/file.h>
25 #include <sys/mount.h>
26 #include <sys/resource.h>
27 #include <sys/stat.h>
28 #ifndef __APPLE__
29 #include <sys/statfs.h>
30 #endif
31 #include <sys/time.h>
32 #include <sys/types.h>
33 #include <sys/wait.h>
34 #include <unistd.h>
35 
36 #include <cassert>
37 #include <csignal>
38 #include <cstdio>
39 #include <cstdlib>
40 #include <cstring>
41 #include <ctime>
42 
43 #include <algorithm>
44 #include <functional>
45 #include <map>
46 #include <string>
47 #include <vector>
48 
49 #include "atomic.h"
50 #include "cache_posix.h"
51 #include "catalog.h"
52 #include "catalog_mgr_client.h"
53 #include "clientctx.h"
54 #include "compression.h"
55 #include "directory_entry.h"
56 #include "download.h"
57 #include "duplex_sqlite3.h"
58 #include "fetch.h"
59 #include "globals.h"
60 #include "hash.h"
61 #include "libcvmfs.h"
62 #include "logging.h"
63 #include "lru_md.h"
64 #include "murmur.hxx"
65 #include "platform.h"
66 #include "quota.h"
67 #include "shortstring.h"
68 #include "signature.h"
69 #include "smalloc.h"
70 #include "sqlitemem.h"
71 #include "sqlitevfs.h"
72 #include "util/posix.h"
73 #include "util/string.h"
74 #include "xattr.h"
75 
76 using namespace std; // NOLINT
77 
78 // TODO(jblomer): remove. Only needed to satisfy monitor.cc
79 namespace cvmfs {
80  pid_t pid_ = 0;
81 }
82 
83 
87  return LibGlobals::instance_;
88 }
89 
90 
95  LogCvmfs(kLogCvmfs, kLogStdout, "LibCvmfs version %d.%d, revision %d",
97 
98  assert(options_mgr != NULL);
99  assert(instance_ == NULL);
100  instance_ = new LibGlobals();
101  assert(instance_ != NULL);
102 
103  // Multi-threaded libcrypto (otherwise done by the loader)
104  instance_->libcrypto_locks_ = static_cast<pthread_mutex_t *>(
105  OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)));
106  for (int i = 0; i < CRYPTO_num_locks(); ++i) {
107  int retval = pthread_mutex_init(&(instance_->libcrypto_locks_[i]), NULL);
108  assert(retval == 0);
109  }
110  CRYPTO_set_id_callback(LibGlobals::CallbackLibcryptoThreadId);
111  CRYPTO_set_locking_callback(LibGlobals::CallbackLibcryptoLock);
112 
114  fs_info.name = "libcvmfs";
115  fs_info.type = FileSystem::kFsLibrary;
116  fs_info.options_mgr = options_mgr;
117  instance_->file_system_ = FileSystem::Create(fs_info);
118 
119  if (instance_->file_system_->boot_status() != loader::kFailOk)
120  return instance_->file_system_->boot_status();
121 
122  // Maximum number of open files, handled otherwise as root by the fuse loader
123  string arg;
124  if (options_mgr->GetValue("CVMFS_NFILES", &arg)) {
125  int retval = SetLimitNoFile(String2Uint64(arg));
126  if (retval != 0) {
127  PrintError("Failed to set maximum number of open files, "
128  "insufficient permissions");
130  }
131  }
132 
133  return loader::kFailOk;
134 }
135 
136 
138  if (instance_ != NULL) {
139  delete instance_;
140  instance_ = NULL;
141  }
142  assert(instance_ == NULL);
143 }
144 
145 
147  : options_mgr_(NULL)
148  , file_system_(NULL)
149  , libcrypto_locks_(NULL)
150 { }
151 
152 
154  delete file_system_;
155  delete options_mgr_;
156 
157  if (libcrypto_locks_) {
158  CRYPTO_set_locking_callback(NULL);
159  for (int i = 0; i < CRYPTO_num_locks(); ++i)
160  pthread_mutex_destroy(&(libcrypto_locks_[i]));
161  OPENSSL_free(libcrypto_locks_);
162  }
163 }
164 
165 
167  int mode,
168  int type,
169  const char *file,
170  int line)
171 {
172  (void)file;
173  (void)line;
174 
175  int retval;
176  LibGlobals *globals = LibGlobals::GetInstance();
177  pthread_mutex_t *locks = globals->libcrypto_locks_;
178  pthread_mutex_t *lock = &(locks[type]);
179 
180  if (mode & CRYPTO_LOCK) {
181  retval = pthread_mutex_lock(lock);
182  } else {
183  retval = pthread_mutex_unlock(lock);
184  }
185  assert(retval == 0);
186 }
187 
188 
189 // Type unsigned long required by libcrypto (openssl)
190 unsigned long LibGlobals::CallbackLibcryptoThreadId() { // NOLINT
191  return platform_gettid();
192 }
193 
194 
195 //------------------------------------------------------------------------------
196 
197 
199  const string &fqrn,
200  OptionsManager *options_mgr)
201 {
202  assert(options_mgr != NULL);
203  LibContext *ctx = new LibContext();
204  assert(ctx != NULL);
205 
207  fqrn, LibGlobals::GetInstance()->file_system(), options_mgr);
208  return ctx;
209 }
210 
211 
213  : options_mgr_(NULL)
214  , mount_point_(NULL)
215 { }
216 
217 
219  delete mount_point_;
220  delete options_mgr_;
221 }
222 
225 }
226 
228  catalog::DirectoryEntry *dirent)
229 {
230  if (path.GetLength() == 1 && path.GetChars()[0] == '/') {
231  // root path is expected to be "", not "/"
232  PathString p;
233  return GetDirentForPath(p, dirent);
234  }
235  shash::Md5 md5path(path.GetChars(), path.GetLength());
236  if (mount_point_->md5path_cache()->Lookup(md5path, dirent))
237  return dirent->GetSpecial() != catalog::kDirentNegative;
238 
239  // TODO(jblomer): not twice md5 calculation
241  dirent))
242  {
243  mount_point_->md5path_cache()->Insert(md5path, *dirent);
244  return true;
245  }
246 
247  LogCvmfs(kLogCvmfs, kLogDebug, "GetDirentForPath, no entry");
248  // Only cache real ENOENT errors, not catalog load errors
249  if (dirent->GetSpecial() == catalog::kDirentNegative)
251 
252  return false;
253 }
254 
255 
256 void LibContext::AppendStringToList(char const *str,
257  char ***buf,
258  size_t *listlen,
259  size_t *buflen)
260 {
261  if (*listlen + 1 >= *buflen) {
262  size_t newbuflen = (*listlen)*2 + 5;
263  *buf = reinterpret_cast<char **>(
264  realloc(*buf, sizeof(char *) * newbuflen));
265  assert(*buf);
266  *buflen = newbuflen;
267  assert(*listlen < *buflen);
268  }
269  if (str) {
270  (*buf)[(*listlen)] = strdup(str);
271  // null-terminate the list
272  (*buf)[++(*listlen)] = NULL;
273  } else {
274  (*buf)[(*listlen)] = NULL;
275  }
276 }
277 
278 
280  cvmfs_stat_t **buf,
281  size_t *listlen,
282  size_t *buflen)
283 {
284  if (*listlen + 1 >= *buflen) {
285  size_t newbuflen = (*listlen)*2 + 5;
286  *buf = reinterpret_cast<cvmfs_stat_t *>(
287  realloc(*buf, sizeof(cvmfs_stat_t) * newbuflen));
288  assert(*buf);
289  *buflen = newbuflen;
290  assert(*listlen < *buflen);
291  }
292  (*buf)[(*listlen)].info = st.info;
293  (*buf)[(*listlen)++].name = st.name;
294 }
295 
296 int LibContext::GetAttr(const char *c_path, struct stat *info) {
297  perf::Inc(file_system()->n_fs_stat());
298  ClientCtxGuard ctxg(geteuid(), getegid(), getpid());
299 
300  LogCvmfs(kLogCvmfs, kLogDebug, "cvmfs_getattr (stat) for path: %s", c_path);
301 
302  PathString p;
303  p.Assign(c_path, strlen(c_path));
304 
306  const bool found = GetDirentForPath(p, &dirent);
307 
308  if (!found) {
309  return -ENOENT;
310  }
311 
312  *info = dirent.GetStatStructure();
313  return 0;
314 }
315 
317  const catalog::DirectoryEntry dirent,
318  struct cvmfs_attr *attr
319 ) {
320  attr->st_ino = dirent.inode();
321  attr->st_mode = dirent.mode();
322  attr->st_nlink = dirent.linkcount();
323  attr->st_uid = dirent.uid();
324  attr->st_gid = dirent.gid();
325  attr->st_rdev = dirent.rdev();
326  attr->st_size = dirent.size();
327  attr->mtime = dirent.mtime();
328  attr->cvm_checksum = strdup(dirent.checksum().ToString().c_str());
329  attr->cvm_symlink = strdup(dirent.symlink().c_str());
330  attr->cvm_name = strdup(dirent.name().c_str());
331  attr->cvm_xattrs = NULL;
332 }
333 
334 
335 int LibContext::GetExtAttr(const char *c_path, struct cvmfs_attr *info) {
336  ClientCtxGuard ctxg(geteuid(), getegid(), getpid());
337 
338  LogCvmfs(kLogCvmfs, kLogDebug, "cvmfs_getattr (stat) for path: %s", c_path);
339 
340  PathString p;
341  p.Assign(c_path, strlen(c_path));
342 
344  const bool found = GetDirentForPath(p, &dirent);
345 
346  if (!found) {
347  return -ENOENT;
348  }
349 
350  CvmfsAttrFromDirent(dirent, info);
351  // Chunked files without bulk hash need to be treated specially
352  info->cvm_nchunks = 0;
353  info->cvm_is_hash_artificial = 0;
354  if (dirent.IsRegular()) {
355  info->cvm_nchunks = 1;
356  if (dirent.IsChunkedFile()) {
357  FileChunkList *chunks = new FileChunkList();
359  p, dirent.hash_algorithm(), chunks);
360  assert(!chunks->IsEmpty());
361  info->cvm_nchunks = chunks->size();
362  if (dirent.checksum().IsNull()) {
363  info->cvm_is_hash_artificial = 1;
364  free(info->cvm_checksum);
365  FileChunkReflist chunks_reflist(
366  chunks, p, dirent.compression_algorithm(), dirent.IsExternalFile());
367  std::string hash_str = chunks_reflist.HashChunkList().ToString();
368  info->cvm_checksum = strdup(hash_str.c_str());
369  }
370  delete chunks;
371  }
372  }
373 
374  info->cvm_parent = strdup(GetParentPath(c_path).c_str());
375  if (dirent.HasXattrs()) {
376  XattrList *xattrs = new XattrList();
377  mount_point_->catalog_mgr()->LookupXattrs(p, xattrs);
378  info->cvm_xattrs = xattrs;
379  }
380  return 0;
381 }
382 
383 
384 int LibContext::Readlink(const char *c_path, char *buf, size_t size) {
385  perf::Inc(file_system()->n_fs_readlink());
386  LogCvmfs(kLogCvmfs, kLogDebug, "cvmfs_readlink on path: %s", c_path);
387  ClientCtxGuard ctxg(geteuid(), getegid(), getpid());
388 
389  PathString p;
390  p.Assign(c_path, strlen(c_path));
391 
393  const bool found = GetDirentForPath(p, &dirent);
394 
395  if (!found) {
396  return -ENOENT;
397  }
398 
399  if (!dirent.IsLink()) {
400  return -EINVAL;
401  }
402 
403  unsigned len = (dirent.symlink().GetLength() >= size) ?
404  size : dirent.symlink().GetLength() + 1;
405  strncpy(buf, dirent.symlink().c_str(), len-1);
406  buf[len-1] = '\0';
407 
408  return 0;
409 }
410 
412  const char *c_path,
413  char ***buf,
414  size_t *listlen,
415  size_t *buflen,
416  bool self_reference
417 ) {
418  LogCvmfs(kLogCvmfs, kLogDebug, "cvmfs_listdir on path: %s", c_path);
419  ClientCtxGuard ctxg(geteuid(), getegid(), getpid());
420 
421  if (c_path[0] == '/' && c_path[1] == '\0') {
422  // root path is expected to be "", not "/"
423  c_path = "";
424  }
425 
426  PathString path;
427  path.Assign(c_path, strlen(c_path));
428 
430  const bool found = GetDirentForPath(path, &d);
431 
432  if (!found) {
433  return -ENOENT;
434  }
435 
436  if (!d.IsDirectory()) {
437  return -ENOTDIR;
438  }
439 
440  AppendStringToList(NULL, buf, listlen, buflen);
441 
442  // Build listing
443 
444  if (self_reference) {
445  // Add current directory link
446  AppendStringToList(".", buf, listlen, buflen);
447 
448  // Add parent directory link
450  if (d.inode() != mount_point_->catalog_mgr()->GetRootInode()) {
451  AppendStringToList("..", buf, listlen, buflen);
452  }
453  }
454 
455  // Add all names
456  catalog::StatEntryList listing_from_catalog;
457  if (!mount_point_->catalog_mgr()->ListingStat(path, &listing_from_catalog)) {
458  return -EIO;
459  }
460  for (unsigned i = 0; i < listing_from_catalog.size(); ++i) {
461  AppendStringToList(listing_from_catalog.AtPtr(i)->name.c_str(),
462  buf, listlen, buflen);
463  }
464 
465  return 0;
466 }
467 
469  const char *c_path,
470  cvmfs_stat_t **buf,
471  size_t *listlen,
472  size_t *buflen) {
473  LogCvmfs(kLogCvmfs, kLogDebug, "cvmfs_listdir_stat on path: %s", c_path);
474  ClientCtxGuard ctxg(geteuid(), getegid(), getpid());
475 
476  if (c_path[0] == '/' && c_path[1] == '\0') {
477  // root path is expected to be "", not "/"
478  c_path = "";
479  }
480 
481  PathString path;
482  path.Assign(c_path, strlen(c_path));
483 
485  const bool found = GetDirentForPath(path, &d);
486 
487  if (!found) {
488  return -ENOENT;
489  }
490 
491  if (!d.IsDirectory()) {
492  return -ENOTDIR;
493  }
494 
495  // Build listing
496  catalog::StatEntryList listing_from_catalog;
497  if (!mount_point_->catalog_mgr()->ListingStat(path, &listing_from_catalog)) {
498  return -EIO;
499  }
500  for (unsigned i = 0; i < listing_from_catalog.size(); ++i) {
501  cvmfs_stat_t st;
502  st.info = listing_from_catalog.AtPtr(i)->info;
503  st.name = strdup(listing_from_catalog.AtPtr(i)->name.c_str());
504  AppendStatToList(st, buf, listlen, buflen);
505  }
506 
507  return 0;
508 }
509 
511  const char *c_path,
512  struct cvmfs_nc_attr *nc_attr
513 ) {
514  ClientCtxGuard ctxg(geteuid(), getegid(), getpid());
516  "cvmfs_stat_nc (cvmfs_nc_attr) : %s", c_path);
517 
518  PathString p;
519  p.Assign(c_path, strlen(c_path));
520 
521  PathString mountpoint;
522  shash::Any hash;
523  uint64_t size;
524 
525  // Find the nested catalog from the root catalog
526  const bool found =
527  mount_point_->catalog_mgr()->LookupNested(p, &mountpoint, &hash, &size);
528  if (!found) {
529  return -ENOENT;
530  }
531 
532  std::string subcat_path;
533  std::map<std::string, uint64_t> counters =
534  mount_point_->catalog_mgr()->LookupCounters(p, &subcat_path).GetValues();
535 
536  // Set values of the passed structure
537  nc_attr->mountpoint = strdup(mountpoint.ToString().c_str());
538  nc_attr->hash = strdup(hash.ToString().c_str());
539  nc_attr->size = size;
540 
541  nc_attr->ctr_regular = counters["regular"];
542  nc_attr->ctr_symlink = counters["symlink"];
543  nc_attr->ctr_special = counters["special"];
544  nc_attr->ctr_dir = counters["dir"];
545  nc_attr->ctr_nested = counters["nested"];
546  nc_attr->ctr_chunked = counters["chunked"];
547  nc_attr->ctr_chunks = counters["chunks"];
548  nc_attr->ctr_file_size = counters["file_size"];
549  nc_attr->ctr_chunked_size = counters["chunked_size"];
550  nc_attr->ctr_xattr = counters["xattr"];
551  nc_attr->ctr_external = counters["external"];
552  nc_attr->ctr_external_file_size = counters["external_file_size"];
553  return 0;
554 }
555 
556 
558  const char *c_path,
559  char ***buf,
560  size_t *buflen
561 ) {
562  ClientCtxGuard ctxg(geteuid(), getegid(), getpid());
564  "cvmfs_list_nc on path: %s", c_path);
565 
566  if (c_path[0] == '/' && c_path[1] == '\0') {
567  // root path is expected to be "", not "/"
568  c_path = "";
569  }
570 
571  PathString path;
572  path.Assign(c_path, strlen(c_path));
573 
574  std::vector<PathString> skein;
575  bool retval = mount_point_->catalog_mgr()->ListCatalogSkein(path, &skein);
576  if (!retval) {
578  "cvmfs_list_nc failed to find skein of path: %s", c_path);
579  return 1;
580  }
581 
582  size_t listlen = 0;
583  AppendStringToList(NULL, buf, &listlen, buflen);
584 
585  for (unsigned i = 0; i < skein.size(); i++) {
586  AppendStringToList(skein.at(i).c_str(), buf, &listlen, buflen);
587  }
588 
589  return 0;
590 }
591 
592 
593 int LibContext::Open(const char *c_path) {
594  LogCvmfs(kLogCvmfs, kLogDebug, "cvmfs_open on path: %s", c_path);
595  ClientCtxGuard ctxg(geteuid(), getegid(), getpid());
596 
597  int fd = -1;
599  PathString path;
600  path.Assign(c_path, strlen(c_path));
601 
602  const bool found = GetDirentForPath(path, &dirent);
603 
604  if (!found) {
605  return -ENOENT;
606  }
607 
608  if (dirent.IsChunkedFile()) {
610  "chunked file %s opened (download delayed to read() call)",
611  path.c_str());
612 
613  FileChunkList *chunks = new FileChunkList();
615  path, dirent.hash_algorithm(), chunks) ||
616  chunks->IsEmpty())
617  {
618  LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogErr, "file %s is marked as "
619  "'chunked', but no chunks found.", path.c_str());
620  perf::Inc(file_system()->n_io_error());
621  delete chunks;
622  return -EIO;
623  }
624 
626  FileChunkReflist(chunks, path, dirent.compression_algorithm(),
627  dirent.IsExternalFile()));
628  return fd | kFdChunked;
629  }
630 
631  cvmfs::Fetcher *this_fetcher = dirent.IsExternalFile()
633  : mount_point_->fetcher();
634  fd = this_fetcher->Fetch(
635  dirent.checksum(),
636  dirent.size(),
637  string(path.GetChars(), path.GetLength()),
638  dirent.compression_algorithm(),
640  perf::Inc(file_system()->n_fs_open());
641 
642  if (fd >= 0) {
643  LogCvmfs(kLogCvmfs, kLogDebug, "file %s opened (fd %d)",
644  path.c_str(), fd);
645  return fd;
646  } else {
648  "failed to open path: %s, CAS key %s, error code %d",
649  c_path, dirent.checksum().ToString().c_str(), errno);
650  if (errno == EMFILE) {
651  return -EMFILE;
652  }
653  }
654 
655  perf::Inc(file_system()->n_io_error());
656  return fd;
657 }
658 
659 
661  int fd,
662  void *buf,
663  uint64_t size,
664  uint64_t off)
665 {
666  if (fd & kFdChunked) {
667  ClientCtxGuard ctxg(geteuid(), getegid(), getpid());
668  const int chunk_handle = fd & ~kFdChunked;
669  SimpleChunkTables::OpenChunks open_chunks =
670  mount_point_->simple_chunk_tables()->Get(chunk_handle);
671  FileChunkList *chunk_list = open_chunks.chunk_reflist.list;
672  zlib::Algorithms compression_alg =
673  open_chunks.chunk_reflist.compression_alg;
674  if (chunk_list == NULL)
675  return -EBADF;
676 
677  // Fetch all needed chunks and read the requested data
678  unsigned chunk_idx = open_chunks.chunk_reflist.FindChunkIdx(off);
679  uint64_t overall_bytes_fetched = 0;
680  off_t offset_in_chunk = off - chunk_list->AtPtr(chunk_idx)->offset();
681  do {
682  // Open file descriptor to chunk
683  ChunkFd *chunk_fd = open_chunks.chunk_fd;
684  if ((chunk_fd->fd == -1) || (chunk_fd->chunk_idx != chunk_idx)) {
685  if (chunk_fd->fd != -1) file_system()->cache_mgr()->Close(chunk_fd->fd);
686  if (open_chunks.chunk_reflist.external_data) {
687  chunk_fd->fd = mount_point_->external_fetcher()->Fetch(
688  chunk_list->AtPtr(chunk_idx)->content_hash(),
689  chunk_list->AtPtr(chunk_idx)->size(),
690  "no path info",
691  compression_alg,
693  open_chunks.chunk_reflist.path.ToString(),
694  chunk_list->AtPtr(chunk_idx)->offset());
695  } else {
696  chunk_fd->fd = mount_point_->fetcher()->Fetch(
697  chunk_list->AtPtr(chunk_idx)->content_hash(),
698  chunk_list->AtPtr(chunk_idx)->size(),
699  "no path info",
700  compression_alg,
702  }
703  if (chunk_fd->fd < 0) {
704  chunk_fd->fd = -1;
705  return -EIO;
706  }
707  chunk_fd->chunk_idx = chunk_idx;
708  }
709 
710  LogCvmfs(kLogCvmfs, kLogDebug, "reading from chunk fd %d",
711  chunk_fd->fd);
712  // Read data from chunk
713  const size_t bytes_to_read = size - overall_bytes_fetched;
714  const size_t remaining_bytes_in_chunk =
715  chunk_list->AtPtr(chunk_idx)->size() - offset_in_chunk;
716  size_t bytes_to_read_in_chunk =
717  std::min(bytes_to_read, remaining_bytes_in_chunk);
718  const int64_t bytes_fetched = file_system()->cache_mgr()->Pread(
719  chunk_fd->fd,
720  reinterpret_cast<char *>(buf) + overall_bytes_fetched,
721  bytes_to_read_in_chunk,
722  offset_in_chunk);
723 
724  if (bytes_fetched < 0) {
725  LogCvmfs(kLogCvmfs, kLogSyslogErr, "read err no %d (%s)",
726  bytes_fetched,
727  open_chunks.chunk_reflist.path.ToString().c_str());
728  return -bytes_fetched;
729  }
730  overall_bytes_fetched += bytes_fetched;
731 
732  // Proceed to the next chunk to keep on reading data
733  ++chunk_idx;
734  offset_in_chunk = 0;
735  } while ((overall_bytes_fetched < size) &&
736  (chunk_idx < chunk_list->size()));
737  return overall_bytes_fetched;
738  } else {
739  return file_system()->cache_mgr()->Pread(fd, buf, size, off);
740  }
741 }
742 
743 
744 int LibContext::Close(int fd) {
745  LogCvmfs(kLogCvmfs, kLogDebug, "cvmfs_close on file number: %d", fd);
746  if (fd & kFdChunked) {
747  const int chunk_handle = fd & ~kFdChunked;
748  SimpleChunkTables::OpenChunks open_chunks =
749  mount_point_->simple_chunk_tables()->Get(chunk_handle);
750  if (open_chunks.chunk_reflist.list == NULL)
751  return -EBADF;
752  if (open_chunks.chunk_fd->fd != -1)
753  file_system()->cache_mgr()->Close(open_chunks.chunk_fd->fd);
754  mount_point_->simple_chunk_tables()->Release(chunk_handle);
755  } else {
756  file_system()->cache_mgr()->Close(fd);
757  }
758  return 0;
759 }
760 
762  LogCvmfs(kLogCvmfs, kLogDebug, "remounting root catalog");
763  catalog::LoadError retval =
764  mount_point_->catalog_mgr()->Remount(true /* dry_run */);
765  switch (retval) {
767  LogCvmfs(kLogCvmfs, kLogDebug, "catalog up to date");
768  return 0;
769 
770  case catalog::kLoadNew:
771  retval = mount_point_->catalog_mgr()->Remount(false /* dry_run */);
772  if (retval != catalog::kLoadNew)
773  return -1;
775  LogCvmfs(kLogCvmfs, kLogDebug, "switched to catalog revision %d",
777  return 0;
778 
779  default:
780  return -1;
781  }
782 }
783 
784 
786  return mount_point_->catalog_mgr()->GetRevision();
787 }
uint32_t linkcount() const
#define LogCvmfs(source, mask,...)
Definition: logging.h:20
nlink_t st_nlink
Definition: libcvmfs.h:157
char * cvm_symlink
Definition: libcvmfs.h:170
bool IsExternalFile() const
uint64_t GetRevision()
bool IsNull() const
Definition: hash.h:379
struct cvmcache_context * ctx
static LibContext * Create(const std::string &fqrn, OptionsManager *options_mgr)
bool InsertNegative(const shash::Md5 &hash)
Definition: lru_md.h:129
bool GetValue(const std::string &key, std::string *value)
Definition: options.cc:376
FileChunkReflist chunk_reflist
Definition: file_chunk.h:146
pthread_t platform_gettid()
void EnableMultiThreaded()
time_t mtime() const
bool IsDirectory() const
uint64_t ctr_external_file_size
Definition: libcvmfs.h:131
char * cvm_name
Definition: libcvmfs.h:172
char * mountpoint
Definition: libcvmfs.h:115
static const int kFdChunked
Definition: libcvmfs_int.h:132
int GetNestedCatalogAttr(const char *c_path, struct cvmfs_nc_attr *nc_attr)
cvmfs::Fetcher * fetcher()
Definition: mountpoint.h:418
bool IsChunkedFile() const
SpecialDirents GetSpecial() const
uint64_t size() const
std::string ToString(const bool with_suffix=false) const
Definition: hash.h:245
static unsigned long CallbackLibcryptoThreadId()
void Assign(const char *chars, const unsigned length)
Definition: shortstring.h:53
zlib::Algorithms compression_alg
Definition: file_chunk.h:71
OpenChunks Get(int fd)
Definition: file_chunk.cc:190
int Close(int fd)
bool Lookup(const shash::Md5 &hash, catalog::DirectoryEntry *dirent, bool update_lru=true)
Definition: lru_md.h:136
uint64_t ctr_external
Definition: libcvmfs.h:130
const shash::Any & content_hash() const
Definition: file_chunk.h:41
inode_t inode() const
bool ListingStat(const PathString &path, StatEntryList *listing)
assert((mem||(size==0))&&"Out Of Memory")
MountPoint * mount_point_
Definition: cvmfs.cc:121
static void CallbackLibcryptoLock(int mode, int type, const char *file, int line)
char * cvm_parent
Definition: libcvmfs.h:171
bool LookupPath(const PathString &path, const LookupOptions options, DirectoryEntry *entry)
int GetAttr(const char *c_path, struct stat *info)
std::string GetParentPath(const std::string &path)
Definition: posix.cc:131
int GetExtAttr(const char *c_path, struct cvmfs_attr *info)
int fd
Definition: file_chunk.h:82
lru::Md5PathCache * md5path_cache()
Definition: mountpoint.h:432
shash::Any checksum() const
void ReEvaluateAuthz()
Definition: mountpoint.cc:1711
OptionsManager * options_mgr_
Definition: libcvmfs_int.h:156
unsigned int mode() const
uint64_t ctr_xattr
Definition: libcvmfs.h:129
bool GetDirentForPath(const PathString &path, catalog::DirectoryEntry *dirent)
int SetLimitNoFile(unsigned limit_nofile)
Definition: posix.cc:1473
char * cvm_checksum
Definition: libcvmfs.h:169
LoadError Remount(const bool dry_run)
static LibGlobals * instance_
Definition: libcvmfs_int.h:77
#define LIBCVMFS_VERSION_MAJOR
Definition: libcvmfs.h:19
char * hash
Definition: libcvmfs.h:116
pid_t pid_
Definition: cvmfs.cc:146
uint64_t ctr_regular
Definition: libcvmfs.h:120
PathString path
Definition: file_chunk.h:70
std::map< std::string, FieldT > GetValues() const
NameString name() const
bool IsLink() const
Algorithms
Definition: compression.h:44
BigVector< FileChunk > FileChunkList
Definition: file_chunk.h:51
bool HasXattrs() const
catalog::ClientCatalogManager * catalog_mgr()
Definition: mountpoint.h:409
void * cvm_xattrs
Definition: libcvmfs.h:173
int64_t Pread(int fd, void *buf, uint64_t size, uint64_t off)
static loader::Failures Initialize(OptionsManager *options_mgr)
Definition: libcvmfs_int.cc:94
int ListNestedCatalogs(const char *path, char ***buf, size_t *buflen)
#define LIBCVMFS_REVISION
Definition: libcvmfs.h:45
bool IsRegular() const
#define LIBCVMFS_VERSION_MINOR
Definition: libcvmfs.h:20
MountPoint * mount_point_
Definition: libcvmfs_int.h:157
time_t mtime
Definition: libcvmfs.h:162
FileSystem * file_system()
Definition: libcvmfs_int.h:137
gid_t st_gid
Definition: libcvmfs.h:159
off_t offset() const
Definition: file_chunk.h:42
zlib::Algorithms compression_algorithm() const
CacheManager * cache_mgr()
Definition: mountpoint.h:174
unsigned chunk_idx
Definition: file_chunk.h:83
uint64_t ctr_chunked_size
Definition: libcvmfs.h:128
pthread_mutex_t * libcrypto_locks_
Definition: libcvmfs_int.h:86
off_t st_size
Definition: libcvmfs.h:161
unsigned FindChunkIdx(const uint64_t offset)
Definition: file_chunk.cc:23
int cvm_is_hash_artificial
Definition: libcvmfs.h:166
void AppendStatToList(const cvmfs_stat_t st, cvmfs_stat_t **buf, size_t *listlen, size_t *buflen)
LinkString symlink() const
download::DownloadManager * download_mgr()
Definition: mountpoint.h:411
char * name
Definition: libcvmfs.h:182
Failures
Definition: loader.h:27
int ListDirectoryStat(const char *c_path, cvmfs_stat_t **buf, size_t *listlen, size_t *buflen)
void Inc(class Counter *counter)
Definition: statistics.h:50
virtual int Close(int fd)=0
OptionsManager * options_mgr_
Definition: cvmfs.cc:145
shash::Algorithms hash_algorithm() const
static LibGlobals * GetInstance()
Definition: libcvmfs_int.cc:85
bool ListCatalogSkein(const PathString &path, std::vector< PathString > *result_list)
cvmfs::Fetcher * external_fetcher()
Definition: mountpoint.h:421
int Add(FileChunkReflist chunks)
Definition: file_chunk.cc:170
static FileSystem * Create(const FileSystemInfo &fs_info)
Definition: mountpoint.cc:144
bool IsEmpty() const
Definition: bigvector.h:67
uint64_t ctr_chunked
Definition: libcvmfs.h:125
int Open(const char *c_path)
std::string ToString() const
Definition: shortstring.h:114
int ListDirectory(const char *path, char ***buf, size_t *listlen, size_t *buflen, bool self_reference)
uint64_t String2Uint64(const string &value)
Definition: string.cc:228
bool ListFileChunks(const PathString &path, const shash::Algorithms interpret_hashes_as, FileChunkList *chunks)
ino_t st_ino
Definition: libcvmfs.h:155
uint64_t ctr_symlink
Definition: libcvmfs.h:121
uint64_t size
Definition: libcvmfs.h:117
shash::Any HashChunkList()
Definition: file_chunk.cc:49
size_t size() const
Definition: file_chunk.h:43
FileSystem * file_system_
Definition: libcvmfs_int.h:84
catalog::Counters LookupCounters(const PathString &path, std::string *subcatalog_path)
void AppendStringToList(char const *str, char ***buf, size_t *listlen, size_t *buflen)
uint64_t ctr_chunks
Definition: libcvmfs.h:126
uint64_t ctr_file_size
Definition: libcvmfs.h:127
FileSystem * file_system_
Definition: cvmfs.cc:120
int Readlink(const char *path, char *buf, size_t size)
SimpleChunkTables * simple_chunk_tables()
Definition: mountpoint.h:437
bool LookupXattrs(const PathString &path, XattrList *xattrs)
bool LookupNested(const PathString &path, PathString *mountpoint, shash::Any *hash, uint64_t *size)
uid_t st_uid
Definition: libcvmfs.h:158
uint64_t ctr_dir
Definition: libcvmfs.h:123
void Release(int fd)
Definition: file_chunk.cc:204
struct stat info
Definition: libcvmfs.h:183
uid_t uid() const
dev_t st_rdev
Definition: libcvmfs.h:160
void CvmfsAttrFromDirent(const catalog::DirectoryEntry dirent, struct cvmfs_attr *attr)
gid_t gid() const
OptionsManager * options_mgr_
Definition: libcvmfs_int.h:83
unsigned GetLength() const
Definition: shortstring.h:104
int cvm_nchunks
Definition: libcvmfs.h:165
uint64_t ctr_special
Definition: libcvmfs.h:122
void PrintError(const string &message)
Definition: logging.cc:465
const char * c_str() const
Definition: shortstring.h:118
const char * GetChars() const
Definition: shortstring.h:96
bool Insert(const shash::Md5 &hash, const catalog::DirectoryEntry &dirent)
Definition: lru_md.h:121
static void size_t size
Definition: smalloc.h:47
virtual int64_t Pread(int fd, void *buf, uint64_t size, uint64_t offset)=0
static void CleanupInstance()
FileChunkList * list
Definition: file_chunk.h:69
const Item * AtPtr(const size_t index) const
Definition: bigvector.h:55
struct stat GetStatStructure() const
dev_t rdev() const
size_t size() const
Definition: bigvector.h:100
mode_t st_mode
Definition: libcvmfs.h:156
int Fetch(const shash::Any &id, const uint64_t size, const std::string &name, const zlib::Algorithms compression_algorithm, const CacheManager::ObjectType object_type, const std::string &alt_url="", off_t range_offset=-1)
Definition: fetch.cc:81
static MountPoint * Create(const std::string &fqrn, FileSystem *file_system, OptionsManager *options_mgr=NULL)
Definition: mountpoint.cc:1136
uint64_t ctr_nested
Definition: libcvmfs.h:124
OptionsManager * options_mgr
Definition: mountpoint.h:136