Directory: | cvmfs/ |
---|---|
File: | cvmfs/catalog_rw.h |
Date: | 2025-06-22 02:36:02 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 30 | 31 | 96.8% |
Branches: | 9 | 16 | 56.2% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * This file is part of the CernVM File System | ||
3 | * | ||
4 | * The WritableCatalog class is derived from Catalog. It is used by the | ||
5 | * WritableCatalogManager on the server side. | ||
6 | * | ||
7 | * The main functionality is in: | ||
8 | * - AddEntry | ||
9 | * - UpdateEntry | ||
10 | * - RemoveEntry | ||
11 | * | ||
12 | * Catalogs not thread safe. | ||
13 | */ | ||
14 | |||
15 | #ifndef CVMFS_CATALOG_RW_H_ | ||
16 | #define CVMFS_CATALOG_RW_H_ | ||
17 | |||
18 | #include <stdint.h> | ||
19 | |||
20 | #include <string> | ||
21 | #include <vector> | ||
22 | |||
23 | #include "catalog.h" | ||
24 | #include "util/posix.h" | ||
25 | |||
26 | class XattrList; | ||
27 | |||
28 | namespace swissknife { | ||
29 | class CommandMigrate; | ||
30 | } | ||
31 | |||
32 | namespace catalog { | ||
33 | |||
34 | class WritableCatalogManager; | ||
35 | |||
36 | class WritableCatalog : public Catalog { | ||
37 | friend class WritableCatalogManager; | ||
38 | friend class swissknife::CommandMigrate; // needed for catalog migrations | ||
39 | friend class VirtualCatalog; // needed for /.cvmfs creation | ||
40 | |||
41 | public: | ||
42 | WritableCatalog(const std::string &path, | ||
43 | const shash::Any &catalog_hash, | ||
44 | Catalog *parent, | ||
45 | const bool is_not_root = false); | ||
46 | virtual ~WritableCatalog(); | ||
47 | |||
48 | static WritableCatalog *AttachFreely(const std::string &root_path, | ||
49 | const std::string &file, | ||
50 | const shash::Any &catalog_hash, | ||
51 | Catalog *parent = NULL, | ||
52 | const bool is_not_root = false); | ||
53 | |||
54 | void Transaction(); | ||
55 | void Commit(); | ||
56 | |||
57 | 1817 | inline bool IsDirty() const { return dirty_; } | |
58 | 14314 | inline bool IsWritable() const { return true; } | |
59 | uint32_t GetMaxLinkId() const; | ||
60 | |||
61 | void AddEntry(const DirectoryEntry &entry, | ||
62 | const XattrList &xattr, | ||
63 | const std::string &entry_path, | ||
64 | const std::string &parent_path); | ||
65 | void TouchEntry(const DirectoryEntryBase &entry, | ||
66 | const XattrList &xattrs, | ||
67 | const shash::Md5 &path_hash); | ||
68 | 91 | inline void TouchEntry(const DirectoryEntryBase &entry, | |
69 | const XattrList &xattrs, | ||
70 | const std::string &path) { | ||
71 |
2/4✓ Branch 2 taken 91 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 91 times.
✗ Branch 6 not taken.
|
91 | TouchEntry(entry, xattrs, shash::Md5(shash::AsciiPtr(path))); |
72 | 91 | } | |
73 | void RemoveEntry(const std::string &entry_path); | ||
74 | void IncLinkcount(const std::string &path_within_group, const int delta); | ||
75 | void AddFileChunk(const std::string &entry_path, const FileChunk &chunk); | ||
76 | void RemoveFileChunks(const std::string &entry_path); | ||
77 | |||
78 | // Creation and removal of catalogs | ||
79 | void Partition(WritableCatalog *new_nested_catalog); | ||
80 | void MergeIntoParent(); | ||
81 | void RemoveFromParent(); | ||
82 | |||
83 | // Nested catalog references | ||
84 | void InsertNestedCatalog(const std::string &mountpoint, | ||
85 | Catalog *attached_reference, | ||
86 | const shash::Any content_hash, | ||
87 | const uint64_t size); | ||
88 | void InsertBindMountpoint(const std::string &mountpoint, | ||
89 | const shash::Any content_hash, | ||
90 | const uint64_t size); | ||
91 | void UpdateNestedCatalog(const std::string &path, | ||
92 | const shash::Any &hash, | ||
93 | const uint64_t size, | ||
94 | const DeltaCounters &child_counters); | ||
95 | void RemoveNestedCatalog(const std::string &mountpoint, | ||
96 | Catalog **attached_reference); | ||
97 | void RemoveBindMountpoint(const std::string &mountpoint); | ||
98 | |||
99 | void UpdateLastModified(); | ||
100 | void IncrementRevision(); | ||
101 | void SetRevision(const uint64_t new_revision); | ||
102 | void SetBranch(const std::string &branch_name); | ||
103 | void SetPreviousRevision(const shash::Any &hash); | ||
104 | void SetTTL(const uint64_t new_ttl); | ||
105 | bool SetVOMSAuthz(const std::string &voms_authz); | ||
106 | |||
107 | protected: | ||
108 | static const double kMaximalFreePageRatio; // = 0.2 | ||
109 | static const double kMaximalRowIdWasteRatio; // = 0.25; | ||
110 | |||
111 | 2611 | CatalogDatabase::OpenMode DatabaseOpenMode() const { | |
112 | 2611 | return CatalogDatabase::kOpenReadWrite; | |
113 | } | ||
114 | |||
115 | void UpdateEntry(const DirectoryEntry &entry, const shash::Md5 &path_hash); | ||
116 | 6520 | inline void UpdateEntry(const DirectoryEntry &entry, | |
117 | const std::string &path) { | ||
118 |
2/4✓ Branch 2 taken 6520 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6520 times.
✗ Branch 6 not taken.
|
6520 | UpdateEntry(entry, shash::Md5(shash::AsciiPtr(path))); |
119 | 6520 | } | |
120 | |||
121 | 3745 | inline void AddEntry(const DirectoryEntry &entry, | |
122 | const XattrList &xattrs, | ||
123 | const std::string &path) { | ||
124 |
1/2✓ Branch 2 taken 3745 times.
✗ Branch 3 not taken.
|
3745 | AddEntry(entry, xattrs, path, GetParentPath(path)); |
125 | 3745 | } | |
126 | |||
127 | void InitPreparedStatements(); | ||
128 | void FinalizePreparedStatements(); | ||
129 | |||
130 | 2115 | inline WritableCatalog *GetWritableParent() const { | |
131 | 2115 | Catalog *parent = this->parent(); | |
132 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2115 times.
|
2115 | assert(parent->IsWritable()); |
133 | 2115 | return static_cast<WritableCatalog *>(parent); | |
134 | } | ||
135 | |||
136 | ✗ | int dirty_children() const { return atomic_read32(&dirty_children_); } | |
137 | 1817 | void set_dirty_children(const int count) { | |
138 | 1817 | atomic_write32(&dirty_children_, count); | |
139 | 1817 | } | |
140 | 939 | int DecrementDirtyChildren() { | |
141 | 939 | return atomic_xadd32(&dirty_children_, -1) - 1; | |
142 | } | ||
143 | |||
144 | private: | ||
145 | SqlDirentInsert *sql_insert_; | ||
146 | SqlDirentUnlink *sql_unlink_; | ||
147 | SqlDirentTouch *sql_touch_; | ||
148 | SqlDirentUpdate *sql_update_; | ||
149 | SqlChunkInsert *sql_chunk_insert_; | ||
150 | SqlChunksRemove *sql_chunks_remove_; | ||
151 | SqlChunksCount *sql_chunks_count_; | ||
152 | SqlMaxHardlinkGroup *sql_max_link_id_; | ||
153 | SqlIncLinkcount *sql_inc_linkcount_; | ||
154 | |||
155 | bool dirty_; /**< Indicates if the catalog has been changed */ | ||
156 | |||
157 | DeltaCounters delta_counters_; | ||
158 | |||
159 | // parallel commit state | ||
160 | mutable atomic_int32 dirty_children_; | ||
161 | |||
162 | 26816 | inline void SetDirty() { | |
163 |
2/2✓ Branch 0 taken 2225 times.
✓ Branch 1 taken 24591 times.
|
26816 | if (!dirty_) |
164 | 2225 | Transaction(); | |
165 | 26816 | dirty_ = true; | |
166 | 26816 | } | |
167 | |||
168 | // Helpers for nested catalog creation and removal | ||
169 | void MakeTransitionPoint(const std::string &mountpoint); | ||
170 | void MakeNestedRoot(); | ||
171 | 981 | inline void MoveToNested(const std::string &dir_structure_root, | |
172 | WritableCatalog *new_nested_catalog, | ||
173 | std::vector<std::string> *grand_child_mountpoints) { | ||
174 |
1/2✓ Branch 2 taken 981 times.
✗ Branch 3 not taken.
|
981 | MoveToNestedRecursively( |
175 | dir_structure_root, new_nested_catalog, grand_child_mountpoints); | ||
176 | 981 | } | |
177 | void MoveToNestedRecursively( | ||
178 | const std::string dir_structure_root, | ||
179 | WritableCatalog *new_nested_catalog, | ||
180 | std::vector<std::string> *grand_child_mountpoints); | ||
181 | void MoveCatalogsToNested(const std::vector<std::string> &nested_catalogs, | ||
182 | WritableCatalog *new_nested_catalog); | ||
183 | void MoveFileChunksToNested(const std::string &full_path, | ||
184 | const shash::Algorithms algorithm, | ||
185 | WritableCatalog *new_nested_catalog); | ||
186 | |||
187 | void CopyToParent(); | ||
188 | void CopyCatalogsToParent(); | ||
189 | |||
190 | void UpdateCounters(); | ||
191 | void VacuumDatabaseIfNecessary(); | ||
192 | }; // class WritableCatalog | ||
193 | |||
194 | typedef std::vector<WritableCatalog *> WritableCatalogList; | ||
195 | |||
196 | } // namespace catalog | ||
197 | |||
198 | #endif // CVMFS_CATALOG_RW_H_ | ||
199 |