5 #define __STDC_FORMAT_MACROS
31 WritableCatalogManager::WritableCatalogManager(
33 const std::string &stratum0,
34 const string &dir_temp,
38 const unsigned nested_kcatalog_limit,
39 const unsigned root_kcatalog_limit,
40 const unsigned file_mbyte_limit,
45 const std::string &dir_cache)
47 statistics, false, dir_cache,
50 , enforce_limits_(enforce_limits)
51 , nested_kcatalog_limit_(nested_kcatalog_limit)
52 , root_kcatalog_limit_(root_kcatalog_limit)
53 , file_mbyte_limit_(file_mbyte_limit)
54 , is_balanceable_(is_balanceable)
55 , max_weight_(max_weight)
56 , min_weight_(min_weight)
57 , balance_weight_(max_weight / 2) {
58 sync_lock_ =
reinterpret_cast<pthread_mutex_t *
>(
59 smalloc(
sizeof(pthread_mutex_t)));
60 int retval = pthread_mutex_init(
sync_lock_, NULL);
63 smalloc(
sizeof(pthread_mutex_t)));
90 mountpoint.
ToString(), catalog_hash, parent_catalog);
106 const string &dir_temp,
107 const bool volatile_content,
108 const std::string &voms_authz,
111 const string file_path = dir_temp +
"/new_root_catalog";
119 root_entry.
mode_ = 16877;
120 root_entry.
size_ = 4096;
121 root_entry.
mtime_ = time(NULL);
122 root_entry.
uid_ = getuid();
123 root_entry.
gid_ = getgid();
126 const string root_path =
"";
133 || !new_clg_db->InsertInitialValues(
134 root_path, volatile_content, voms_authz, root_entry)) {
142 const int64_t catalog_size =
GetFileSize(file_path);
143 if (catalog_size < 0) {
144 unlink(file_path.c_str());
147 const string file_path_compressed = file_path +
".compressed";
154 unlink(file_path.c_str());
157 unlink(file_path.c_str());
160 const string manifest_path = dir_temp +
"/manifest";
163 if (!voms_authz.empty()) {
168 spooler->Upload(file_path_compressed,
"data/" + hash_catalog.
MakePath());
169 spooler->WaitForUpload();
170 unlink(file_path_compressed.c_str());
171 if (spooler->GetNumberOfErrors() > 0) {
173 file_path_compressed.c_str());
207 if (NULL == dirent) {
210 const bool found = catalog->
LookupPath(ps_path, dirent);
220 const std::string &path) {
262 if (!
FindCatalog(parent_path, &catalog, &parent_entry)) {
264 directory_path.c_str());
273 parent_path.c_str());
278 parent_catalog->UpdateEntry(parent_entry, parent_path);
292 const std::string
source) {
307 const bool destination_already_present =
309 if (destination_already_present) {
314 std::string destination_dirname;
315 std::string destination_filename;
316 SplitPath(destination, &destination_dirname, &destination_filename);
319 NameString(destination_filename.c_str(), destination_filename.length()));
334 const std::string &to_dir) {
336 if (from_dir.empty() || to_dir.empty())
342 if (relative_source == relative_dest) {
343 PANIC(
kLogStderr,
"cannot clone tree into itself ('%s')", to_dir.c_str());
345 if (
HasPrefix(relative_dest, relative_source +
"/",
false )) {
347 "cannot clone tree into sub directory of source '%s' --> '%s'",
348 from_dir.c_str(), to_dir.c_str());
353 PANIC(
kLogStderr,
"path '%s' cannot be found, aborting", from_dir.c_str());
362 PANIC(
kLogStderr,
"destination '%s' exists, aborting", to_dir.c_str());
365 const std::string dest_parent =
GetParentPath(relative_dest);
383 const std::string &dest_parent_dir,
386 dest_parent_dir.c_str(), dest_name.
ToString().c_str());
395 dest_dirent.name_.Assign(dest_name);
397 dest_dirent.set_is_nested_catalog_mountpoint(
false);
398 dest_dirent.set_is_nested_catalog_root(
false);
407 std::string dest_dir = dest_parent_dir;
408 if (!dest_dir.empty())
409 dest_dir.push_back(
'/');
417 retval =
Listing(relative_source, &ls,
false );
419 for (
unsigned i = 0; i < ls.size(); ++i) {
423 sub_path.
Append(ls[i].name().GetChars(), ls[i].name().GetLength());
425 if (ls[i].IsDirectory()) {
431 ls[i].set_hardlink_group(0);
432 ls[i].set_linkcount(1);
435 if (ls[i].HasXattrs()) {
440 if (ls[i].IsChunkedFile()) {
442 const std::string relative_sub_path =
445 ls[i].hash_algorithm(), &chunks);
449 AddFile(ls[i], xattrs, dest_dir);
464 const std::string &parent_directory) {
466 string directory_path = parent_path +
"/";
472 if (!
FindCatalog(parent_path, &catalog, &parent_entry)) {
474 directory_path.c_str());
479 catalog->
AddEntry(fixed_hardlink_count, xattrs, directory_path, parent_path);
485 parent_path.c_str());
490 parent_catalog->UpdateEntry(parent_entry, parent_path);
504 const std::string &parent_directory) {
506 const string file_path = entry.
GetFullPath(parent_path);
520 const unsigned mbytes = entry.
size() / (1024 * 1024);
523 "%s: file at %s is larger than %u megabytes (%u). "
524 "CernVM-FS works best with small files. "
525 "Please remove the file or increase the limit.",
533 catalog->
AddEntry(entry, xattrs, file_path, parent_path);
540 const std::string &parent_directory,
545 full_entry.set_is_chunked_file(
true);
547 AddFile(full_entry, xattrs, parent_directory);
550 const string file_path = entry.
GetFullPath(parent_path);
559 for (
unsigned i = 0; i < file_chunks.
size(); ++i) {
576 const std::string &parent_directory,
578 assert(entries.size() >= 1);
580 if (entries.size() == 1) {
584 return AddFile(fix_linkcount, xattrs, parent_directory);
585 return AddChunkedFile(fix_linkcount, xattrs, parent_directory, file_chunks);
589 parent_directory.c_str(), entries[0].name().c_str());
596 const unsigned mbytes = entries[0].size() / (1024 * 1024);
599 "%s: hard link at %s is larger than %u megabytes (%u). "
600 "CernVM-FS works best with small files. "
601 "Please remove the file or increase the limit.",
603 (parent_path + entries[0].name().ToString()).c_str(),
607 (parent_path + entries[0].name().ToString()).c_str(),
615 "catalog for hardlink group containing '%s' cannot be found",
616 parent_path.c_str());
621 const uint32_t new_group_id = catalog->
GetMaxLinkId() + 1;
627 for (DirectoryEntryBaseList::const_iterator i = entries.begin(),
628 iEnd = entries.end();
631 string file_path = parent_path +
"/";
632 file_path.append(i->name().GetChars(), i->name().GetLength());
641 catalog->
AddEntry(hardlink, xattrs, file_path, parent_path);
643 for (
unsigned i = 0; i < file_chunks.
size(); ++i) {
659 "catalog for hardlink group containing '%s' cannot be found",
660 remove_path.c_str());
678 const std::string &directory_path) {
692 catalog->
TouchEntry(entry, xattrs, entry_path);
702 const PathString transition_path(entry_path.data(), entry_path.length());
703 bool retval = catalog->
LookupPath(transition_path,
704 &potential_transition_point);
712 uint64_t nested_size;
713 retval = catalog->
FindNested(transition_path, &nested_hash, &nested_size);
716 nested_catalog =
MountCatalog(transition_path, nested_hash, catalog);
717 assert(nested_catalog != NULL);
721 ->TouchEntry(entry, xattrs, entry_path);
735 const std::string &mountpoint) {
737 const PathString ps_nested_root_path(nested_root_path);
745 if (!
FindCatalog(nested_root_path, &old_catalog, &new_root_entry)) {
747 "failed to create nested catalog '%s': "
748 "mountpoint was not found in current catalog structure",
749 nested_root_path.c_str());
756 const bool volatile_content =
false;
758 assert(NULL != new_catalog_db);
769 delete new_catalog_db;
770 new_catalog_db = NULL;
785 wr_new_catalog->TouchEntry(new_root_entry, xattrs, nested_root_path);
802 &grand_nested = wr_new_catalog->ListOwnNestedCatalogs();
804 for (Catalog::NestedCatalogList::const_iterator i = grand_nested.begin(),
805 iEnd = grand_nested.end();
809 retval =
FindCatalog(i->mountpoint.ToString(), &grand_catalog);
814 const DeltaCounters save_counters = wr_new_catalog->delta_counters_;
815 wr_new_catalog->delta_counters_ = fix_subtree_counters;
816 wr_new_catalog->UpdateCounters();
817 wr_new_catalog->delta_counters_ = save_counters;
841 if (!
FindCatalog(nested_root_path, &nested_catalog)) {
843 "failed to remove nested catalog '%s': "
844 "mountpoint was not found in current catalog structure",
845 nested_root_path.c_str());
862 "unable to delete the removed nested catalog database file '%s'",
885 const uint64_t new_size) {
897 "failed to swap nested catalog '%s': could not find parent '%s'",
898 nested_root_path.c_str(), parent_path.c_str());
904 if (old_attached_catalog) {
912 "failed to swap nested catalog '%s': already modified",
913 nested_root_path.c_str());
915 old_counters = old_attached_catalog->
GetCounters();
923 const bool old_found = parent->
FindNested(nested_root_ps, &old_hash,
928 "failed to swap nested catalog '%s': not found in parent",
929 nested_root_path.c_str());
933 if (!old_free_catalog.
IsValid()) {
936 "failed to swap nested catalog '%s': failed to load old catalog",
937 nested_root_path.c_str());
939 old_counters = old_free_catalog->GetCounters();
948 "failed to swap nested catalog '%s': failed to load new catalog",
949 nested_root_path.c_str());
955 const bool dirent_found = new_catalog->LookupPath(nested_root_ps, &dirent);
959 "failed to swap nested catalog '%s': missing dirent in new catalog",
960 nested_root_path.c_str());
963 const bool xattrs_found = new_catalog->LookupXattrsPath(nested_root_ps,
968 "failed to swap nested catalog '%s': missing xattrs in new catalog",
969 nested_root_path.c_str());
981 parent->
TouchEntry(dirent, xattrs, nested_root_path);
1005 const uint64_t new_size) {
1010 assert(!nested_root_path.empty());
1015 if (!new_catalog.IsValid()) {
1017 "failed to graft nested catalog '%s': failed to load new catalog",
1018 nested_root_path.c_str());
1020 if (new_catalog->root_prefix() != nested_root_ps) {
1022 "invalid nested catalog for grafting at '%s': catalog rooted at '%s'",
1023 nested_root_path.c_str(),
1024 new_catalog->root_prefix().ToString().c_str());
1030 const bool dirent_found = new_catalog->LookupPath(nested_root_ps, &dirent);
1031 if (!dirent_found) {
1033 "failed to swap nested catalog '%s': missing dirent in new catalog",
1034 nested_root_path.c_str());
1037 const bool xattrs_found = new_catalog->LookupXattrsPath(nested_root_ps,
1039 if (!xattrs_found) {
1041 "failed to swap nested catalog '%s': missing xattrs in new catalog",
1042 nested_root_path.c_str());
1055 if (!
FindCatalog(parent_path, &parent_catalog, &parent_entry)) {
1058 parent_path.c_str());
1060 if (parent_catalog->
LookupPath(nested_root_ps, NULL)) {
1063 "invalid attempt to graft nested catalog into existing "
1065 nested_root_path.c_str());
1067 parent_catalog->
AddEntry(dirent, xattrs, nested_root_path, parent_path);
1069 parent_catalog->
UpdateEntry(parent_entry, parent_path);
1072 parent_catalog->
parent());
1075 grand_parent_catalog->
UpdateEntry(parent_entry, parent_path);
1132 const uint64_t manual_revision,
1139 if (manual_revision > 0) {
1140 const uint64_t revision = root_catalog->
GetRevision();
1141 if (revision >= manual_revision) {
1143 "Manual revision (%" PRIu64
") must not be "
1144 "smaller than the current root catalog's (%" PRIu64
1146 manual_revision, revision);
1155 if (getenv(
"_CVMFS_SERIALIZED_CATALOG_PROCESSING_") == NULL)
1159 if (
spooler_->GetNumberOfErrors() > 0) {
1205 const bool stop_for_tweaks) {
1213 this, upload_context);
1221 WritableCatalogList::const_iterator i = leafs_to_snapshot.begin();
1222 const WritableCatalogList::const_iterator iend = leafs_to_snapshot.end();
1223 for (; i != iend; ++i) {
1229 const CatalogInfo &root_catalog_info = root_catalog_info_future.
Get();
1233 return root_catalog_info;
1238 const bool stop_for_tweaks) {
1250 "setting '%s' as previous revision "
1252 base_hash().ToStringWithSuffix().c_str());
1258 uint64_t size_previous;
1260 catalog->
mountpoint(), &hash_previous, &size_previous);
1265 "found '%s' as previous revision "
1266 "for nested catalog '%s'",
1274 const uint64_t catalog_limit =
1277 if ((catalog_limit > 0)
1280 "%s: catalog at %s has more than %lu entries (%lu). "
1281 "Large catalogs stress the CernVM-FS transport infrastructure. "
1282 "Please split it into nested catalogs or increase the limit.",
1293 if (stop_for_tweaks) {
1295 "Allowing for tweaks in %s at %s "
1296 "(hit return to continue)",
1298 const int read_char = getchar();
1299 assert(read_char != EOF);
1327 std::string tmp_catalog_path;
1328 const std::string cache_catalog_path =
dir_cache_ +
"/"
1335 "Creating file for temporary catalog failed: %s",
1336 tmp_catalog_path.c_str());
1339 (void)fclose(fcatalog);
1341 if (rename(tmp_catalog_path.c_str(), cache_catalog_path.c_str()) != 0) {
1343 result.
local_path.c_str(), cache_catalog_path.c_str());
1361 const std::map<std::string, WritableCatalog *>::iterator c =
1364 catalog = c->second;
1368 assert(catalog_size > 0);
1394 if (remaining_dirty_children == 0) {
1399 }
else if (catalog->
IsRoot()) {
1403 root_catalog_info.
size = catalog_size;
1404 root_catalog_info.
ttl = catalog->
GetTTL();
1430 int dirty_children = 0;
1432 CatalogList::const_iterator i = children.begin();
1433 const CatalogList::const_iterator iend = children.end();
1434 for (; i != iend; ++i) {
1443 const bool is_dirty = wr_catalog->
IsDirty() || dirty_children > 0;
1444 const bool is_leaf = dirty_children == 0;
1445 if (is_dirty && is_leaf) {
1446 result->push_back(const_cast<WritableCatalog *>(wr_catalog));
1455 reverse(catalog_list.begin(), catalog_list.end());
1456 for (
unsigned i = 0; i < catalog_list.size(); ++i) {
1457 FixWeight(static_cast<WritableCatalog *>(catalog_list[i]));
1466 "Deleting an autogenerated catalog in '%s'",
1471 catalog->
RemoveEntry(path +
"/.cvmfsautocatalog");
1477 catalog_balancer.
Balance(catalog);
1494 int dirty_catalogs = (wr_catalog->
IsDirty()) ? 1 : 0;
1498 for (CatalogList::const_iterator i = children.begin(), iEnd = children.end();
1505 if (dirty_catalogs > 0)
1506 result->push_back(const_cast<WritableCatalog *>(wr_catalog));
1509 return dirty_catalogs;
1541 WritableCatalogList::const_iterator i = catalogs_to_snapshot.begin();
1542 const WritableCatalogList::const_iterator iend = catalogs_to_snapshot.end();
1543 for (; i != iend; ++i) {
1551 (*i)->mountpoint().ToString().c_str());
1554 const int64_t catalog_size =
GetFileSize((*i)->database_path());
1555 assert(catalog_size > 0);
1557 if ((*i)->HasParent()) {
1561 catalog_size, (*i)->delta_counters_);
1562 (*i)->delta_counters_.SetZero();
1563 }
else if ((*i)->IsRoot()) {
1564 root_catalog_info.
size = catalog_size;
1565 root_catalog_info.
ttl = (*i)->GetTTL();
1567 root_catalog_info.
revision = (*i)->GetRevision();
1572 spooler_->ProcessCatalog((*i)->database_path());
1577 return root_catalog_info;
1608 if ((*it)->dirty_children() == 0) {
1633 std::map<std::string, WritableCatalog*>::iterator
const c =
1636 catalog = c->second;
1640 assert(catalog_size > 0);
1668 context.
dirs = &dirs;
1674 for (
auto it = nested_catalogs.begin(); it != nested_catalogs.end(); ++it) {
1676 std::string
const mountpoint = it->mountpoint.ToString();
1677 if (dirs.find(mountpoint) != dirs.end()) {
1695 bool const exists =
LookupPath(path, options, dirent);
1716 downloaded_catalog = it->second;
1721 delete downloaded_catalog;
1726 for (
auto it = nested_catalogs.begin(); it != nested_catalogs.end(); ++it) {
1728 if (context.
dirs->find(it->mountpoint.ToString()) != context.
dirs->end()) {
1737 delete downloaded_catalog;
bool CompressPath2Null(const string &src, shash::Any *compressed_hash)
uint32_t linkcount() const
int return_code
the return value of the spooler operation
void DetachSubtree(Catalog *catalog)
bool IsExternalFile() const
CallbackPtr RegisterListener(typename BoundClosure< ParamT, DelegateT, ClosureDataT >::CallbackMethod method, DelegateT *delegate, ClosureDataT data)
const Counters & GetCounters() const
void AddChunkedFile(const DirectoryEntryBase &entry, const XattrList &xattrs, const std::string &parent_directory, const FileChunkList &file_chunks)
const manifest::Manifest * manifest() const
void set_base_hash(const shash::Any &hash)
ShortString< kDefaultMaxName, 1 > NameString
void CloneTree(const std::string &from_dir, const std::string &to_dir)
void AddHardlinkGroup(const DirectoryEntryBaseList &entries, const XattrList &xattrs, const std::string &parent_directory, const FileChunkList &file_chunks)
void set_dirty_children(const int count)
void set_is_chunked_file(const bool val)
void AddDirectory(const DirectoryEntryBase &entry, const XattrList &xattrs, const std::string &parent_directory)
std::string database_path() const
bool UseLocalCache() const
void set_catalog_hash(const shash::Any &catalog_hash)
std::unordered_map< std::string, Catalog * > catalog_download_map_
NameString GetFileName(const PathString &path)
Catalog * LoadFreeCatalog(const PathString &mountpoint, const shash::Any &hash)
bool IsChunkedFile() const
unsigned nested_kcatalog_limit_
void SingleCatalogUploadCallback(const upload::SpoolerResult &result)
bool MountSubtree(const PathString &path, const Catalog *entry_point, bool can_listing, Catalog **leaf_catalog)
~WritableCatalogManager()
void RemoveDirectory(const std::string &directory_path)
uint32_t GetMaxLinkId() const
void UpdateNestedCatalog(const std::string &path, const shash::Any &hash, const uint64_t size, const DeltaCounters &child_counters)
bool OpenDatabase(const std::string &db_path)
CVMFS_EXPORT const LogSource source
FILE * CreateTempFile(const std::string &path_prefix, const int mode, const char *open_flags, std::string *final_path)
WritableCatalog * GetHostingCatalog(const std::string &path)
void Assign(const char *chars, const unsigned length)
void set_linkcount(const uint32_t linkcount)
void set_is_nested_catalog_root(const bool val)
void FixWeight(WritableCatalog *catalog)
std::string ToStringWithSuffix() const
void Balance(catalog_t *catalog)
bool LookupPath(const PathString &path, DirectoryEntry *dirent) const
void UpdateLastModified()
void ScheduleCatalogProcessing(WritableCatalog *catalog)
pthread_mutex_t * catalog_download_lock_
std::vector< Catalog * > CatalogList
std::string CreateTempPath(const std::string &path_prefix, const int mode)
void DetachCatalog(Catalog *catalog)
void SetTTL(const uint64_t new_ttl)
static DeltaCounters Diff(const Counters &from, const Counters &to)
int GetModifiedCatalogsRecursively(const Catalog *catalog, WritableCatalogList *result) const
Counters_t GetSelfEntries() const
void set_revision(const uint64_t revision)
void InsertNestedCatalog(const std::string &mountpoint, Catalog *attached_reference, const shash::Any content_hash, const uint64_t size)
void TouchEntry(const DirectoryEntryBase &entry, const XattrList &xattrs, const shash::Md5 &path_hash)
assert((mem||(size==0))&&"Out Of Memory")
void Process(const shash::Any &catalog_hash)
bool FindCatalog(const std::string &path, WritableCatalog **result, DirectoryEntry *dirent=NULL)
bool Commit(const bool stop_for_tweaks, const uint64_t manual_revision, manifest::Manifest *manifest)
CatalogList GetChildren() const
bool LookupPath(const PathString &path, const LookupOptions options, DirectoryEntry *entry)
upload::Spooler * spooler
void SetPreviousRevision(const shash::Any &hash)
pthread_mutex_t * catalog_processing_lock_
std::map< std::string, WritableCatalog * > catalog_processing_map_
Catalog * FindChild(const PathString &mountpoint) const
std::vector< WritableCatalog * > WritableCatalogList
shash::Any checksum() const
const NestedCatalogList & ListNestedCatalogs() const
void CloneTreeImpl(const PathString &source_dir, const std::string &dest_parent_dir, const NameString &dest_name)
const unsigned kLookupDefault
bool CopyPath2File(const std::string &src, FILE *fdest)
void AddAsSubtree(DeltaCounters *delta) const
bool IsNestedCatalogMountpoint() const
bool IsTransitionPoint(const std::string &mountpoint)
pthread_mutex_t * catalog_hash_lock_
bool Listing(const PathString &path, DirectoryEntryList *listing, const bool expand_symlink)
void CatalogUploadCallback(const upload::SpoolerResult &result, const CatalogUploadContext clg_upload_context)
bool IsNestedCatalogRoot() const
void TouchDirectory(const DirectoryEntryBase &entry, const XattrList &xattrs, const std::string &directory_path)
uint64_t GetNumEntries() const
uint64_t GetRevision() const
void AddFileChunk(const std::string &entry_path, const FileChunk &chunk)
bool IsAutogenerated() const
std::vector< DirectoryEntry > DirectoryEntryList
CatalogDownloadPipeline * catalog_download_pipeline_
static manifest::Manifest * CreateRepository(const std::string &dir_temp, const bool volatile_content, const std::string &voms_authz, upload::Spooler *spooler)
bool AttachCatalog(const std::string &db_path, Catalog *new_catalog)
void SplitPath(const std::string &path, std::string *dirname, std::string *filename)
const unsigned max_weight_
void ActivateCatalog(Catalog *catalog)
std::string local_path
the local_path previously given as input
bool LookupXattrsPath(const PathString &path, XattrList *xattrs) const
void ShrinkHardlinkGroup(const std::string &remove_path)
bool CopyCatalogToLocalCache(const upload::SpoolerResult &result)
void RemoveSingleCatalogUploadCallback()
bool GetModifiedCatalogLeafsRecursively(Catalog *catalog, WritableCatalogList *result) const
const char kSuffixCatalog
pthread_mutex_t * sync_lock_
unsigned root_kcatalog_limit_
const std::string & dir_temp() const
void PopulateToParent(DeltaCounters *parent) const
bool InsertInitialValues(const std::string &root_path, const bool volatile_content, const std::string &voms_authz, const DirectoryEntry &root_entry=DirectoryEntry(kDirentNegative))
void AddCatalogToQueue(const std::string &path)
CatalogInfo SnapshotCatalogsSerialized(const bool stop_for_tweaks)
CatalogInfo SnapshotCatalogs(const bool stop_for_tweaks)
PathString mountpoint() const
static const inode_t kInvalidInode
void Append(const char *chars, const unsigned length)
std::list< WritableCatalog * > pending_catalogs_
void TakeDatabaseFileOwnership()
bool SetVOMSAuthz(const std::string &voms_authz)
bool HasPrefix(const string &str, const string &prefix, const bool ignore_case)
void Clone(const std::string from, const std::string to)
void RemoveFile(const std::string &file_path)
bool IsBindMountpoint() const
void SetupSingleCatalogUploadCallback()
std::string MakeRelativePath(const std::string &relative_path) const
void CatalogUploadSerializedCallback(const upload::SpoolerResult &result, const CatalogUploadContext unused)
void RemoveNestedCatalog(const std::string &mountpoint, Catalog **attached_reference)
Catalog * GetRootCatalog() const
upload::Spooler * spooler_
void AddEntry(const DirectoryEntry &entry, const XattrList &xattr, const std::string &entry_path, const std::string &parent_path)
void RemoveNestedCatalog(const std::string &mountpoint, const bool merge=true)
const unsigned min_weight_
void set_ttl(const uint32_t ttl)
shash::Algorithms GetHashAlgorithm() const
std::string MakePathWithoutSuffix() const
std::string ToString() const
std::vector< NestedCatalog > NestedCatalogList
bool ListFileChunks(const PathString &path, const shash::Algorithms interpret_hashes_as, FileChunkList *chunks)
void Partition(WritableCatalog *new_nested_catalog)
ShortString< kDefaultMaxPath, 0 > PathString
void SetRevision(const uint64_t new_revision)
void LoadCatalogs(const std::string &base_path, const std::unordered_set< std::string > &dirs)
const std::vector< Catalog * > & GetCatalogs() const
void CatalogDownloadCallback(const CatalogDownloadResult &result, const CatalogDownloadContext context)
void set_hardlink_group(const uint32_t group)
std::map< std::string, shash::Any > catalog_hash_map_
PathString GetParentPath(const PathString &path)
WritableCatalog * GetWritableParent() const
void set_catalog_size(const uint64_t catalog_size)
DeltaCounters delta_counters_
bool FindNested(const PathString &mountpoint, shash::Any *hash, uint64_t *size) const
void VacuumDatabaseIfNecessary()
std::string GetFullPath(const std::string &parent_directory) const
bool LookupXattrs(const PathString &path, XattrList *xattrs)
Catalog * MountCatalog(const PathString &mountpoint, const shash::Any &hash, Catalog *parent_catalog)
int64_t GetFileSize(const std::string &path)
std::vector< DirectoryEntryBase > DirectoryEntryBaseList
void ScheduleReadyCatalogs()
void set_has_alt_catalog_path(const bool &has_alt_path)
unsigned GetLength() const
void CatalogHashSerializedCallback(const CompressHashResult &result)
CatalogT * FindCatalog(const PathString &path) const
std::string MakePath() const
void AddFile(const DirectoryEntryBase &entry, const XattrList &xattrs, const std::string &parent_directory)
Future< CatalogInfo > * root_catalog_info
const char * c_str() const
void SwapNestedCatalog(const string &mountpoint, const shash::Any &new_hash, const uint64_t new_size)
void RemoveEntry(const std::string &entry_path)
const char * GetChars() const
virtual bool IsWritable() const
void GetModifiedCatalogLeafs(WritableCatalogList *result) const
Catalog * CreateCatalog(const PathString &mountpoint, const shash::Any &catalog_hash, Catalog *parent_catalog)
void FinalizeCatalog(WritableCatalog *catalog, const bool stop_for_tweaks)
void IncLinkcount(const std::string &path_within_group, const int delta)
void PrecalculateListings()
int DecrementDirtyChildren()
void GraftNestedCatalog(const string &mountpoint, const shash::Any &new_hash, const uint64_t new_size)
bool LookupDirEntry(const std::string &path, const LookupOptions options, DirectoryEntry *dirent)
const Item * AtPtr(const size_t index) const
void set_is_nested_catalog_mountpoint(const bool val)
bool CompressPath2Path(const string &src, const string &dest)
void CreateNestedCatalog(const std::string &mountpoint)
void UpdateEntry(const DirectoryEntry &entry, const shash::Md5 &path_hash)
static DerivedT * Create(const std::string &filename)
void GetModifiedCatalogs(WritableCatalogList *result) const
unsigned file_mbyte_limit_
const std::unordered_set< std::string > * dirs
void set_root_path(const std::string &root_path)
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
const shash::Any & base_hash() const