CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
catalog_mgr.h
Go to the documentation of this file.
1 
5 #ifndef CVMFS_CATALOG_MGR_H_
6 #define CVMFS_CATALOG_MGR_H_
7 
8 #ifndef __STDC_FORMAT_MACROS
9 #define __STDC_FORMAT_MACROS
10 #endif
11 
12 #include <inttypes.h>
13 #include <pthread.h>
14 
15 #include <cassert>
16 #include <map>
17 #include <string>
18 #include <vector>
19 
20 #include "catalog.h"
21 #include "crypto/hash.h"
22 #include "directory_entry.h"
23 #include "file_chunk.h"
24 #include "manifest_fetch.h"
25 #include "statistics.h"
26 #include "util/algorithm.h"
27 #include "util/atomic.h"
28 #include "util/logging.h"
29 #include "util/platform.h"
30 
31 class XattrList;
32 namespace catalog {
33 
34 const unsigned kSqliteMemPerThread = 1 * 1024 * 1024;
35 
36 
42 typedef unsigned LookupOptions;
43 const unsigned kLookupDefault = 0b1;
44 const unsigned kLookupRawSymlink = 0b10;
45 
49 enum LoadReturn {
50  kLoadNew = 0,
54 
56 };
57 
67  kCtlgNoLocationNeeded = 0, // hash known, no location needed
68  kCtlgLocationMounted, // already loaded in mounted_catalogs_
71 };
72 
93  public:
95  : hash_(shash::Any())
96  , mountpoint_(PathString("invalid", 7))
97  , // empty str is root ctlg
98  sqlite_path_("")
99  , root_ctlg_revision_(-1ul)
101  , manifest_ensemble_(NULL) { }
103  : hash_(hash)
104  , mountpoint_(mountpoint)
105  , sqlite_path_("")
106  , root_ctlg_revision_(-1ul)
108  , manifest_ensemble_(NULL) { }
109 
111  const RootCatalogLocation location)
112  : hash_(hash)
113  , mountpoint_(mountpoint)
114  , sqlite_path_("")
115  , root_ctlg_revision_(-1ul)
116  , root_ctlg_location_(location)
117  , manifest_ensemble_(NULL) { }
118 
119  bool IsRootCatalog() { return mountpoint_.IsEmpty(); }
120 
121  std::string *GetSqlitePathPtr() { return &sqlite_path_; }
122  shash::Any *GetHashPtr() { return &hash_; }
123 
124  shash::Any hash() const { return hash_; }
125  PathString mountpoint() const { return mountpoint_; }
126  std::string sqlite_path() const { return sqlite_path_; }
127  uint64_t root_ctlg_revision() const { return root_ctlg_revision_; }
130  return manifest_ensemble_.weak_ref();
131  }
132 
135  void SetSqlitePath(const std::string &sqlite_path) {
137  }
140  }
143  }
149  }
150 
151 
152  private:
153  // mandatory for LoadCatalogByHash()
155  // mandatory for LoadCatalogByHash()
157  // out parameter, path name of the sqlite catalog
158  std::string sqlite_path_;
159  // root catalog: revision is needed for GetNewRootCatalogContext()
161  // root catalog: location is mandatory for LoadCatalogByHash()
163  // root catalog: if location = server mandatory for LoadCatalogByHash()
165 };
166 
167 inline const char *Code2Ascii(const LoadReturn error) {
168  const char *texts[kLoadNumEntries + 1];
169  texts[0] = "loaded new catalog";
170  texts[1] = "catalog was up to date";
171  texts[2] = "not enough space to load catalog";
172  texts[3] = "failed to load catalog";
173  texts[4] = "no text";
174  return texts[error];
175 }
176 
177 
178 struct Statistics {
188 
190 
191  explicit Statistics(perf::Statistics *statistics) {
192  n_lookup_inode = statistics->Register("catalog_mgr.n_lookup_inode",
193  "Number of inode lookups");
194  n_lookup_path = statistics->Register("catalog_mgr.n_lookup_path",
195  "Number of path lookups");
196  n_lookup_path_negative = statistics->Register(
197  "catalog_mgr.n_lookup_path_negative",
198  "Number of negative path lookups");
199  n_lookup_xattrs = statistics->Register("catalog_mgr.n_lookup_xattrs",
200  "Number of xattrs lookups");
201  n_listing = statistics->Register("catalog_mgr.n_listing",
202  "Number of listings");
203  n_nested_listing = statistics->Register(
204  "catalog_mgr.n_nested_listing",
205  "Number of listings of nested catalogs");
206  n_detach_siblings = statistics->Register(
207  "catalog_mgr.n_detach_siblings",
208  "Number of times the CVMFS_CATALOG_WATERMARK was hit");
209  n_write_lock = statistics->Register("catalog_mgr.n_write_lock",
210  "number of write lock calls");
211  ns_write_lock = statistics->Register("catalog_mgr.ns_write_lock",
212  "time spent in WriteLock() [ns]");
213  catalog_revision = statistics->Register(
214  "catalog_revision", "Revision number of the root file catalog");
215  }
216 };
217 
218 
219 template<class CatalogT>
220 class AbstractCatalogManager;
221 
222 
239 template<class CatalogT>
240 class AbstractCatalogManager : public SingleCopy {
241  public:
242  typedef std::vector<CatalogT *> CatalogList;
243  typedef CatalogT catalog_t;
244 
245  static const inode_t kInodeOffset = 255;
247  virtual ~AbstractCatalogManager();
248 
249  void SetInodeAnnotation(InodeAnnotation *new_annotation);
250  virtual bool Init();
253  LoadReturn ChangeRoot(const shash::Any &root_hash);
254  void DetachNested();
255 
256  bool LookupPath(const PathString &path, const LookupOptions options,
257  DirectoryEntry *entry);
258  bool LookupPath(const std::string &path, const LookupOptions options,
259  DirectoryEntry *entry) {
260  PathString p;
261  p.Assign(&path[0], path.length());
262  return LookupPath(p, options, entry);
263  }
264  bool LookupXattrs(const PathString &path, XattrList *xattrs);
265 
266  bool LookupNested(const PathString &path,
267  PathString *mountpoint,
268  shash::Any *hash,
269  uint64_t *size);
270  bool ListCatalogSkein(const PathString &path,
271  std::vector<PathString> *result_list);
272 
273  bool Listing(const PathString &path, DirectoryEntryList *listing,
274  const bool expand_symlink);
275  bool Listing(const PathString &path, DirectoryEntryList *listing) {
276  return Listing(path, listing, true);
277  }
278  bool Listing(const std::string &path, DirectoryEntryList *listing) {
279  PathString p;
280  p.Assign(&path[0], path.length());
281  return Listing(p, listing);
282  }
283  bool ListingStat(const PathString &path, StatEntryList *listing);
284 
285  bool ListFileChunks(const PathString &path,
286  const shash::Algorithms interpret_hashes_as,
287  FileChunkList *chunks);
288  void SetOwnerMaps(const OwnerMap &uid_map, const OwnerMap &gid_map);
289  void SetCatalogWatermark(unsigned limit);
290 
291  shash::Any GetNestedCatalogHash(const PathString &mountpoint);
292 
293  Statistics statistics() const { return statistics_; }
294  uint64_t inode_gauge() {
295  ReadLock();
296  uint64_t r = inode_gauge_;
297  Unlock();
298  return r;
299  }
300  bool volatile_flag() const { return volatile_flag_; }
301  uint64_t GetRevision() const;
302  uint64_t GetTimestamp() const;
303  uint64_t GetTTL() const;
304  bool HasExplicitTTL() const;
305  bool GetVOMSAuthz(std::string *authz) const;
306  int GetNumCatalogs() const;
307  std::string PrintHierarchy() const;
308  std::string PrintAllMemStatistics() const;
309 
315  inline inode_t GetRootInode() const {
317  : kInodeOffset + 1;
318  }
319  inline CatalogT *GetRootCatalog() const { return catalogs_.front(); }
326  inline inode_t MangleInode(const inode_t inode) const {
327  return (inode <= kInodeOffset) ? GetRootInode() : inode;
328  }
329 
331  std::string *subcatalog_path,
332  shash::Any *hash);
333 
334  protected:
347  virtual LoadReturn LoadCatalogByHash(CatalogContext *ctlg_context) = 0;
348  virtual void UnloadCatalog(const CatalogT *catalog) { }
349  virtual void ActivateCatalog(CatalogT *catalog) { }
350  const std::vector<CatalogT *> &GetCatalogs() const { return catalogs_; }
351 
360  virtual void StageNestedCatalogByHash(const shash::Any & /*hash*/,
361  const PathString & /*mountpoint*/) { }
366  void StageNestedCatalogAndUnlock(const PathString &path,
367  const CatalogT *parent,
368  bool is_listable);
369 
379  virtual CatalogT *CreateCatalog(const PathString &mountpoint,
380  const shash::Any &catalog_hash,
381  CatalogT *parent_catalog) = 0;
382 
383  CatalogT *MountCatalog(const PathString &mountpoint, const shash::Any &hash,
384  CatalogT *parent_catalog);
385  bool MountSubtree(const PathString &path,
386  const CatalogT *entry_point,
387  bool can_listing,
388  CatalogT **leaf_catalog);
389 
390  CatalogT *LoadFreeCatalog(const PathString &mountpoint,
391  const shash::Any &hash);
392 
393  bool AttachCatalog(const std::string &db_path, CatalogT *new_catalog);
394  void DetachCatalog(CatalogT *catalog);
395  void DetachSubtree(CatalogT *catalog);
396  void DetachSiblings(const PathString &current_tree);
397  void DetachAll() {
398  if (!catalogs_.empty())
400  }
401  bool IsAttached(const PathString &root_path,
402  CatalogT **attached_catalog) const;
403 
404  CatalogT *FindCatalog(const PathString &path) const;
405 
406  uint64_t GetRevisionNoLock() const;
407  uint64_t GetTimestampNoLock() const;
408  inline void ReadLock() const {
409  int retval = pthread_rwlock_rdlock(rwlock_);
410  assert(retval == 0);
411  }
412  inline void WriteLock() const {
413  uint64_t timestamp = platform_monotonic_time_ns();
414  int retval = pthread_rwlock_wrlock(rwlock_);
415  assert(retval == 0);
417  uint64_t duration = platform_monotonic_time_ns() - timestamp;
419  }
420  inline void Unlock() const {
421  int retval = pthread_rwlock_unlock(rwlock_);
422  assert(retval == 0);
423  }
424  virtual void EnforceSqliteMemLimit();
425 
426  private:
427  void CheckInodeWatermark();
428 
434  uint64_t inode_gauge_;
435  uint64_t revision_cache_;
455  std::string authz_cache_;
459  uint64_t incarnation_;
460  // TODO(molina) we could just add an atomic global counter instead
462  pthread_rwlock_t *rwlock_;
464  pthread_key_t pkey_sqlitemem_;
467 
468  // Not needed anymore since there are the glue buffers
469  // Catalog *Inode2Catalog(const inode_t inode);
470  std::string PrintHierarchyRecursively(const CatalogT *catalog,
471  const int level) const;
472  std::string PrintMemStatsRecursively(const CatalogT *catalog) const;
473 
474  InodeRange AcquireInodes(uint64_t size);
475  void ReleaseInodes(const InodeRange chunk);
476 }; // class CatalogManager
477 
479  public:
482  virtual bool ValidInode(const uint64_t inode) {
483  return inode >= inode_offset_;
484  }
485  virtual inode_t Annotate(const inode_t raw_inode) {
486  return raw_inode + inode_offset_;
487  }
488  virtual inode_t Strip(const inode_t annotated_inode) {
489  return annotated_inode - inode_offset_;
490  }
491  virtual void IncGeneration(const uint64_t by) {
492  inode_offset_ += by;
493  LogCvmfs(kLogCatalog, kLogDebug, "set inode generation to %lu",
494  inode_offset_);
495  }
496  virtual inode_t GetGeneration() { return inode_offset_; }
497 
498  private:
499  uint64_t inode_offset_;
500 };
501 
508  public:
511  virtual bool ValidInode(const uint64_t inode) {
512  return (inode >= inode_offset_) || (inode == kRootInode);
513  }
514  virtual inode_t Annotate(const inode_t raw_inode) {
515  if (raw_inode <= kRootInode)
516  return kRootInode;
517  return raw_inode + inode_offset_;
518  }
519  virtual inode_t Strip(const inode_t annotated_inode) {
520  if (annotated_inode == kRootInode)
521  return annotated_inode;
522  return annotated_inode - inode_offset_;
523  }
524  virtual void IncGeneration(const uint64_t by) {
525  inode_offset_ += by;
526  LogCvmfs(kLogCatalog, kLogDebug, "set inode generation to %lu",
527  inode_offset_);
528  }
529  virtual inode_t GetGeneration() { return inode_offset_; }
530 
531  private:
532  static const uint64_t
534  uint64_t inode_offset_;
535 };
536 
537 } // namespace catalog
538 
539 #include "catalog_mgr_impl.h"
540 
541 #endif // CVMFS_CATALOG_MGR_H_
shash::Any hash() const
Definition: catalog_mgr.h:124
void DetachSubtree(CatalogT *catalog)
bool Listing(const std::string &path, DirectoryEntryList *listing)
Definition: catalog_mgr.h:278
bool GetVOMSAuthz(std::string *authz) const
Counter * Register(const std::string &name, const std::string &desc)
Definition: statistics.cc:163
catalog::Counters LookupCounters(const PathString &path, std::string *subcatalog_path, shash::Any *hash)
int64_t Xadd(class Counter *counter, const int64_t delta)
Definition: statistics.h:51
Statistics(perf::Statistics *statistics)
Definition: catalog_mgr.h:191
virtual inode_t Annotate(const inode_t raw_inode)
Definition: catalog_mgr.h:514
CatalogT * LoadFreeCatalog(const PathString &mountpoint, const shash::Any &hash)
T * weak_ref() const
Definition: pointer.h:46
perf::Counter * n_lookup_inode
Definition: catalog_mgr.h:179
void StageNestedCatalogAndUnlock(const PathString &path, const CatalogT *parent, bool is_listable)
perf::Counter * catalog_revision
Definition: catalog_mgr.h:189
bool MountSubtree(const PathString &path, const CatalogT *entry_point, bool can_listing, CatalogT **leaf_catalog)
void DetachSiblings(const PathString &current_tree)
virtual inode_t Annotate(const inode_t raw_inode)
Definition: catalog_mgr.h:485
InodeAnnotation * inode_annotation_
Definition: catalog_mgr.h:461
RootCatalogLocation root_ctlg_location_
Definition: catalog_mgr.h:162
void Assign(const char *chars, const unsigned length)
Definition: shortstring.h:61
std::string PrintHierarchyRecursively(const CatalogT *catalog, const int level) const
unsigned LookupOptions
Definition: catalog_mgr.h:42
shash::Any * GetHashPtr()
Definition: catalog_mgr.h:122
RootCatalogLocation root_ctlg_location() const
Definition: catalog_mgr.h:128
perf::Counter * n_nested_listing
Definition: catalog_mgr.h:184
std::vector< CatalogT * > CatalogList
Definition: catalog_mgr.h:242
void DetachCatalog(CatalogT *catalog)
bool IsAttached(const PathString &root_path, CatalogT **attached_catalog) const
virtual inode_t Strip(const inode_t annotated_inode)
Definition: catalog_mgr.h:519
uint64_t inode_t
assert((mem||(size==0))&&"Out Of Memory")
bool ListingStat(const PathString &path, StatEntryList *listing)
uint64_t platform_monotonic_time_ns()
bool LookupPath(const PathString &path, const LookupOptions options, DirectoryEntry *entry)
virtual inode_t Strip(const inode_t annotated_inode)
Definition: catalog_mgr.h:488
const unsigned kLookupDefault
Definition: catalog_mgr.h:43
bool Listing(const PathString &path, DirectoryEntryList *listing)
Definition: catalog_mgr.h:275
IntegerMap< uint64_t > OwnerMap
Definition: catalog.h:41
std::string sqlite_path() const
Definition: catalog_mgr.h:126
perf::Counter * n_lookup_path_negative
Definition: catalog_mgr.h:181
manifest::ManifestEnsemble * manifest_ensemble() const
Definition: catalog_mgr.h:129
virtual LoadReturn GetNewRootCatalogContext(CatalogContext *result)=0
Algorithms
Definition: hash.h:41
bool Listing(const PathString &path, DirectoryEntryList *listing, const bool expand_symlink)
void SetMountpoint(const PathString &mountpoint)
Definition: catalog_mgr.h:134
perf::Counter * n_detach_siblings
Definition: catalog_mgr.h:185
virtual void UnloadCatalog(const CatalogT *catalog)
Definition: catalog_mgr.h:348
std::vector< DirectoryEntry > DirectoryEntryList
void TakeManifestEnsemble(manifest::ManifestEnsemble *manifest_ensemble)
Definition: catalog_mgr.h:147
bool AttachCatalog(const std::string &db_path, CatalogT *new_catalog)
RootCatalogLocation
Definition: catalog_mgr.h:66
LoadReturn ChangeRoot(const shash::Any &root_hash)
const unsigned kSqliteMemPerThread
Definition: catalog_mgr.h:34
static const uint64_t kRootInode
Definition: catalog_mgr.h:533
CatalogContext(const shash::Any &hash, const PathString &mountpoint)
Definition: catalog_mgr.h:102
virtual bool ValidInode(const uint64_t inode)
Definition: catalog_mgr.h:482
shash::Any GetNestedCatalogHash(const PathString &mountpoint)
Statistics statistics() const
Definition: catalog_mgr.h:293
virtual CatalogT * CreateCatalog(const PathString &mountpoint, const shash::Any &catalog_hash, CatalogT *parent_catalog)=0
perf::Counter * n_listing
Definition: catalog_mgr.h:183
UniquePtr< manifest::ManifestEnsemble > manifest_ensemble_
Definition: catalog_mgr.h:164
perf::Counter * n_write_lock
Definition: catalog_mgr.h:186
virtual void StageNestedCatalogByHash(const shash::Any &, const PathString &)
Definition: catalog_mgr.h:360
void Inc(class Counter *counter)
Definition: statistics.h:50
const unsigned kLookupRawSymlink
Definition: catalog_mgr.h:44
uint64_t root_ctlg_revision() const
Definition: catalog_mgr.h:127
void SetRootCtlgLocation(RootCatalogLocation root_ctlg_location)
Definition: catalog_mgr.h:141
bool ListCatalogSkein(const PathString &path, std::vector< PathString > *result_list)
InodeRange AcquireInodes(uint64_t size)
CatalogT * GetRootCatalog() const
Definition: catalog_mgr.h:319
pthread_rwlock_t * rwlock_
Definition: catalog_mgr.h:462
std::string * GetSqlitePathPtr()
Definition: catalog_mgr.h:121
bool IsEmpty() const
Definition: shortstring.h:137
bool LookupPath(const std::string &path, const LookupOptions options, DirectoryEntry *entry)
Definition: catalog_mgr.h:258
bool ListFileChunks(const PathString &path, const shash::Algorithms interpret_hashes_as, FileChunkList *chunks)
perf::Counter * ns_write_lock
Definition: catalog_mgr.h:187
perf::Counter * n_lookup_xattrs
Definition: catalog_mgr.h:182
virtual bool ValidInode(const uint64_t inode)
Definition: catalog_mgr.h:511
virtual inode_t Annotate(const inode_t raw_inode)=0
virtual void IncGeneration(const uint64_t by)
Definition: catalog_mgr.h:491
perf::Counter * n_lookup_path
Definition: catalog_mgr.h:180
const std::vector< CatalogT * > & GetCatalogs() const
Definition: catalog_mgr.h:350
const char * Code2Ascii(const LoadReturn error)
Definition: catalog_mgr.h:167
virtual void IncGeneration(const uint64_t by)
Definition: catalog_mgr.h:524
bool LookupXattrs(const PathString &path, XattrList *xattrs)
PathString mountpoint() const
Definition: catalog_mgr.h:125
std::string sqlite_path_
Definition: catalog_mgr.h:158
bool LookupNested(const PathString &path, PathString *mountpoint, shash::Any *hash, uint64_t *size)
CatalogT * MountCatalog(const PathString &mountpoint, const shash::Any &hash, CatalogT *parent_catalog)
void SetCatalogWatermark(unsigned limit)
CatalogContext(const shash::Any &hash, const PathString &mountpoint, const RootCatalogLocation location)
Definition: catalog_mgr.h:110
virtual void ActivateCatalog(CatalogT *catalog)
Definition: catalog_mgr.h:349
void SetHash(shash::Any hash)
Definition: catalog_mgr.h:133
void SetOwnerMaps(const OwnerMap &uid_map, const OwnerMap &gid_map)
void ReleaseInodes(const InodeRange chunk)
CatalogT * FindCatalog(const PathString &path) const
inode_t MangleInode(const inode_t inode) const
Definition: catalog_mgr.h:326
AbstractCatalogManager(perf::Statistics *statistics)
std::string PrintHierarchy() const
std::string PrintMemStatsRecursively(const CatalogT *catalog) const
std::string PrintAllMemStatistics() const
static void size_t size
Definition: smalloc.h:54
void SetSqlitePath(const std::string &sqlite_path)
Definition: catalog_mgr.h:135
static const inode_t kInodeOffset
Definition: catalog_mgr.h:245
virtual LoadReturn LoadCatalogByHash(CatalogContext *ctlg_context)=0
void SetInodeAnnotation(InodeAnnotation *new_annotation)
void SetRootCtlgRevision(uint64_t root_ctlg_revision)
Definition: catalog_mgr.h:138
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:545