GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/sync_item_dummy.h
Date: 2026-07-05 02:36:18
Exec Total Coverage
Lines: 10 63 15.9%
Branches: 1 34 2.9%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System
3 */
4
5 #ifndef CVMFS_SYNC_ITEM_DUMMY_H_
6 #define CVMFS_SYNC_ITEM_DUMMY_H_
7
8 #include <ctime>
9 #include <string>
10
11 #include "ingestion/ingestion_source.h"
12 #include "sync_item.h"
13 #include "sync_union_tarball.h"
14
15 namespace publish {
16
17 class SyncItemDummyCatalog : public SyncItem {
18 friend class SyncUnionTarball;
19
20 protected:
21 SyncItemDummyCatalog(const std::string &relative_parent_path,
22 const SyncUnion *union_engine)
23 : SyncItem(relative_parent_path, ".cvmfscatalog", union_engine,
24 kItemFile) { }
25
26 public:
27 bool IsType(const SyncItemType expected_type) const {
28 return expected_type == kItemFile;
29 }
30
31 catalog::DirectoryEntryBase CreateBasicCatalogDirent(
32 bool /* enable_mtime_ns */) const {
33 catalog::DirectoryEntryBase dirent;
34 std::string name(".cvmfscatalog");
35 dirent.inode_ = catalog::DirectoryEntry::kInvalidInode;
36 dirent.linkcount_ = 1;
37 dirent.mode_ = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
38 dirent.uid_ = getuid();
39 dirent.gid_ = getgid();
40 dirent.size_ = 0;
41 dirent.mtime_ = time(NULL);
42 dirent.checksum_ = this->GetContentHash();
43 dirent.is_external_file_ = false;
44 dirent.compression_algorithm_ = this->GetCompressionAlgorithm();
45
46 dirent.name_.Assign(name.data(), name.length());
47
48 return dirent;
49 }
50
51 IngestionSource *CreateIngestionSource() const {
52 return new StringIngestionSource("", GetUnionPath());
53 }
54
55 void StatScratch(const bool /* refresh */) const { return; }
56
57 SyncItemType GetScratchFiletype() const { return kItemFile; }
58
59 void MakePlaceholderDirectory() const { }
60 };
61
62 /**
63 * Represents an empty regular file that is materialized on the fly, without a
64 * backing entry in the tarball. It is used by the tarball engine to stand in
65 * for a hardlink whose target is not part of the archive (e.g. a cross-layer
66 * hardlink in an OCI image layer): instead of cloning a non-existent source we
67 * create an empty file with the link's own ownership and permissions. The
68 * content (and therefore the content hash) is the empty string, pushed through
69 * the normal ingestion pipeline so that the empty object is uploaded and
70 * compressed/hashed consistently with the spooler configuration.
71 */
72 class SyncItemDummyFile : public SyncItem {
73 friend class SyncUnionTarball;
74
75 protected:
76 SyncItemDummyFile(const std::string &relative_parent_path,
77 const std::string &filename, const SyncUnion *union_engine,
78 const unsigned int mode, const uid_t uid, const gid_t gid,
79 const time_t mtime)
80 : SyncItem(relative_parent_path, filename, union_engine, kItemFile)
81 , mode_(mode)
82 , uid_(uid)
83 , gid_(gid)
84 , mtime_(mtime) { }
85
86 public:
87 bool IsType(const SyncItemType expected_type) const {
88 return expected_type == kItemFile;
89 }
90
91 catalog::DirectoryEntryBase CreateBasicCatalogDirent(
92 bool /* enable_mtime_ns */) const {
93 catalog::DirectoryEntryBase dirent;
94 dirent.inode_ = catalog::DirectoryEntry::kInvalidInode;
95 dirent.linkcount_ = 1;
96 // Force a regular file type, keeping only the permission bits of the
97 // original hardlink entry.
98 dirent.mode_ = (mode_ & 07777) | S_IFREG;
99 dirent.uid_ = uid_;
100 dirent.gid_ = gid_;
101 dirent.size_ = 0;
102 dirent.mtime_ = mtime_;
103 dirent.checksum_ = this->GetContentHash();
104 dirent.is_external_file_ = false;
105 dirent.compression_algorithm_ = this->GetCompressionAlgorithm();
106
107 dirent.name_.Assign(this->filename().data(), this->filename().length());
108
109 return dirent;
110 }
111
112 IngestionSource *CreateIngestionSource() const {
113 return new StringIngestionSource("", GetUnionPath());
114 }
115
116 void StatScratch(const bool /* refresh */) const { return; }
117
118 SyncItemType GetScratchFiletype() const { return kItemFile; }
119
120 void MakePlaceholderDirectory() const { }
121
122 private:
123 const unsigned int mode_;
124 const uid_t uid_;
125 const gid_t gid_;
126 const time_t mtime_;
127 };
128
129 /*
130 * This class represents dummy directories that we know are going to be there
131 * but we still haven't found yet. This is possible in the extraction of
132 * tarball, where the files are not extracted in order (root to leaves) but in a
133 * random fashion.
134 */
135 class SyncItemDummyDir : public SyncItemNative {
136 friend class SyncUnionTarball;
137
138 public:
139 virtual catalog::DirectoryEntryBase CreateBasicCatalogDirent(
140 bool enable_mtime_ns) const;
141 SyncItemType GetScratchFiletype() const;
142 virtual void MakePlaceholderDirectory() const { rdonly_type_ = kItemDir; }
143
144 protected:
145 SyncItemDummyDir(const std::string &relative_parent_path,
146 const std::string &filename, const SyncUnion *union_engine,
147 const SyncItemType entry_type)
148 : SyncItemNative(relative_parent_path, filename, union_engine,
149 entry_type) {
150 assert(kItemDir == entry_type);
151
152 scratch_stat_.obtained = true;
153 scratch_stat_.stat.st_mode = kPermision;
154 scratch_stat_.stat.st_nlink = 1;
155 scratch_stat_.stat.st_uid = getuid();
156 scratch_stat_.stat.st_gid = getgid();
157 }
158 110 SyncItemDummyDir(const std::string &relative_parent_path,
159 const std::string &filename, const SyncUnion *union_engine,
160 const SyncItemType entry_type, uid_t uid, gid_t gid)
161 110 : SyncItemNative(relative_parent_path, filename, union_engine,
162 110 entry_type) {
163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 110 times.
110 assert(kItemDir == entry_type);
164
165 110 scratch_stat_.obtained = true;
166 110 scratch_stat_.stat.st_mode = kPermision;
167 110 scratch_stat_.stat.st_nlink = 1;
168 110 scratch_stat_.stat.st_uid = uid;
169 110 scratch_stat_.stat.st_gid = gid;
170 110 }
171
172 private:
173 static const mode_t kPermision = S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR
174 | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
175 };
176
177 } // namespace publish
178
179 #endif // CVMFS_SYNC_ITEM_DUMMY_H_
180