1 |
|
|
/** |
2 |
|
|
* This file is part of the CernVM File System |
3 |
|
|
*/ |
4 |
|
|
|
5 |
|
|
#define __STDC_FORMAT_MACROS |
6 |
|
|
|
7 |
|
|
#include "sync_union.h" |
8 |
|
|
|
9 |
|
|
#include "sync_mediator.h" |
10 |
|
|
#include "util/shared_ptr.h" |
11 |
|
|
|
12 |
|
|
namespace publish { |
13 |
|
|
|
14 |
|
1 |
SyncUnion::SyncUnion(AbstractSyncMediator *mediator, |
15 |
|
|
const std::string &rdonly_path, |
16 |
|
|
const std::string &union_path, |
17 |
|
|
const std::string &scratch_path) |
18 |
|
|
: rdonly_path_(rdonly_path), |
19 |
|
|
scratch_path_(scratch_path), |
20 |
|
|
union_path_(union_path), |
21 |
|
|
mediator_(mediator), |
22 |
|
1 |
initialized_(false) {} |
23 |
|
|
|
24 |
|
1 |
bool SyncUnion::Initialize() { |
25 |
|
1 |
mediator_->RegisterUnionEngine(this); |
26 |
|
1 |
initialized_ = true; |
27 |
|
1 |
return true; |
28 |
|
|
} |
29 |
|
|
|
30 |
|
|
SharedPtr<SyncItem> SyncUnion::CreateSyncItem( |
31 |
|
|
const std::string &relative_parent_path, const std::string &filename, |
32 |
|
|
const SyncItemType entry_type) const { |
33 |
|
|
SharedPtr<SyncItem> entry = SharedPtr<SyncItem>( |
34 |
|
|
new SyncItemNative(relative_parent_path, filename, this, entry_type)); |
35 |
|
|
|
36 |
|
|
PreprocessSyncItem(entry); |
37 |
|
|
if (entry_type == kItemFile) { |
38 |
|
|
entry->SetExternalData(mediator_->IsExternalData()); |
39 |
|
|
entry->SetCompressionAlgorithm(mediator_->GetCompressionAlgorithm()); |
40 |
|
|
} |
41 |
|
|
return entry; |
42 |
|
|
} |
43 |
|
|
|
44 |
|
|
void SyncUnion::PreprocessSyncItem(SharedPtr<SyncItem> entry) const { |
45 |
|
|
if (IsWhiteoutEntry(entry)) { |
46 |
|
|
entry->MarkAsWhiteout(UnwindWhiteoutFilename(entry)); |
47 |
|
|
} |
48 |
|
|
|
49 |
|
|
if (entry->IsDirectory() && IsOpaqueDirectory(entry)) { |
50 |
|
|
entry->MarkAsOpaqueDirectory(); |
51 |
|
|
} |
52 |
|
|
} |
53 |
|
|
|
54 |
|
|
bool SyncUnion::IgnoreFilePredicate(const std::string &parent_dir, |
55 |
|
|
const std::string &filename) { |
56 |
|
|
return false; |
57 |
|
|
} |
58 |
|
|
|
59 |
|
|
bool SyncUnion::ProcessDirectory(const string &parent_dir, |
60 |
|
|
const string &dir_name) { |
61 |
|
|
LogCvmfs(kLogUnionFs, kLogDebug, "SyncUnion::ProcessDirectory(%s, %s)", |
62 |
|
|
parent_dir.c_str(), dir_name.c_str()); |
63 |
|
|
SharedPtr<SyncItem> entry = CreateSyncItem(parent_dir, dir_name, kItemDir); |
64 |
|
|
return ProcessDirectory(entry); |
65 |
|
|
} |
66 |
|
|
|
67 |
|
|
bool SyncUnion::ProcessDirectory(SharedPtr<SyncItem> entry) { |
68 |
|
|
if (entry->IsNew()) { |
69 |
|
|
mediator_->Add(entry); |
70 |
|
|
// Recursion stops here. All content of new directory |
71 |
|
|
// is added later by the SyncMediator |
72 |
|
|
return false; |
73 |
|
|
} else { // directory already existed... |
74 |
|
|
if (entry->IsOpaqueDirectory()) { // was directory completely overwritten? |
75 |
|
|
mediator_->Replace(entry); |
76 |
|
|
return false; // <-- replace does not need any further recursion |
77 |
|
|
} else { // directory was just changed internally... only touch needed |
78 |
|
|
mediator_->Touch(entry); |
79 |
|
|
return true; |
80 |
|
|
} |
81 |
|
|
} |
82 |
|
|
} |
83 |
|
|
|
84 |
|
|
// We don't have the directory that we are processing in the fs, we |
85 |
|
|
// cannot recurse inside the directory. |
86 |
|
|
// If the directory already exists, we simply remove it and we put it back the |
87 |
|
|
// new one (some attributes may change) |
88 |
|
|
// If it does not exists we simply add it. |
89 |
|
|
bool SyncUnion::ProcessUnmaterializedDirectory(SharedPtr<SyncItem> entry) { |
90 |
|
|
if (entry->IsNew()) { |
91 |
|
|
mediator_->AddUnmaterializedDirectory(entry); |
92 |
|
|
} |
93 |
|
|
return true; |
94 |
|
|
} |
95 |
|
|
|
96 |
|
|
void SyncUnion::ProcessRegularFile(const string &parent_dir, |
97 |
|
|
const string &filename) { |
98 |
|
|
LogCvmfs(kLogUnionFs, kLogDebug, "SyncUnion::ProcessRegularFile(%s, %s)", |
99 |
|
|
parent_dir.c_str(), filename.c_str()); |
100 |
|
|
SharedPtr<SyncItem> entry = CreateSyncItem(parent_dir, filename, kItemFile); |
101 |
|
|
ProcessFile(entry); |
102 |
|
|
} |
103 |
|
|
|
104 |
|
|
void SyncUnion::ProcessSymlink(const string &parent_dir, |
105 |
|
|
const string &link_name) { |
106 |
|
|
LogCvmfs(kLogUnionFs, kLogDebug, "SyncUnion::ProcessSymlink(%s, %s)", |
107 |
|
|
parent_dir.c_str(), link_name.c_str()); |
108 |
|
|
SharedPtr<SyncItem> entry = |
109 |
|
|
CreateSyncItem(parent_dir, link_name, kItemSymlink); |
110 |
|
|
ProcessFile(entry); |
111 |
|
|
} |
112 |
|
|
|
113 |
|
|
void SyncUnion::ProcessFile(SharedPtr<SyncItem> entry) { |
114 |
|
|
LogCvmfs(kLogUnionFs, kLogDebug, "SyncUnion::ProcessFile(%s)", |
115 |
|
|
entry->filename().c_str()); |
116 |
|
|
if (entry->IsWhiteout()) { |
117 |
|
|
mediator_->Remove(entry); |
118 |
|
|
} else { |
119 |
|
|
if (entry->IsNew()) { |
120 |
|
|
LogCvmfs(kLogUnionFs, kLogVerboseMsg, "processing file [%s] as new (add)", |
121 |
|
|
entry->filename().c_str()); |
122 |
|
|
mediator_->Add(entry); |
123 |
|
|
} else { |
124 |
|
|
LogCvmfs(kLogUnionFs, kLogVerboseMsg, |
125 |
|
|
"processing file [%s] as existing (touch)", |
126 |
|
|
entry->filename().c_str()); |
127 |
|
|
mediator_->Touch(entry); |
128 |
|
|
} |
129 |
|
|
} |
130 |
|
|
} |
131 |
|
|
|
132 |
|
|
void SyncUnion::EnterDirectory(const string &parent_dir, |
133 |
|
|
const string &dir_name) { |
134 |
|
|
SharedPtr<SyncItem> entry = CreateSyncItem(parent_dir, dir_name, kItemDir); |
135 |
|
|
mediator_->EnterDirectory(entry); |
136 |
|
|
} |
137 |
|
|
|
138 |
|
|
void SyncUnion::LeaveDirectory(const string &parent_dir, |
139 |
|
|
const string &dir_name) { |
140 |
|
|
SharedPtr<SyncItem> entry = CreateSyncItem(parent_dir, dir_name, kItemDir); |
141 |
|
|
mediator_->LeaveDirectory(entry); |
142 |
|
|
} |
143 |
|
|
|
144 |
|
|
void SyncUnion::ProcessCharacterDevice(const std::string &parent_dir, |
145 |
|
|
const std::string &filename) { |
146 |
|
|
LogCvmfs(kLogUnionFs, kLogDebug, |
147 |
|
|
"SyncUnionOverlayfs::ProcessCharacterDevice(%s, %s)", |
148 |
|
|
parent_dir.c_str(), filename.c_str()); |
149 |
|
|
SharedPtr<SyncItem> entry = |
150 |
|
|
CreateSyncItem(parent_dir, filename, kItemCharacterDevice); |
151 |
|
|
ProcessFile(entry); |
152 |
|
|
} |
153 |
|
|
|
154 |
|
|
void SyncUnion::ProcessBlockDevice(const std::string &parent_dir, |
155 |
|
|
const std::string &filename) { |
156 |
|
|
LogCvmfs(kLogUnionFs, kLogDebug, |
157 |
|
|
"SyncUnionOverlayfs::ProcessBlockDevice(%s, %s)", parent_dir.c_str(), |
158 |
|
|
filename.c_str()); |
159 |
|
|
SharedPtr<SyncItem> entry = |
160 |
|
|
CreateSyncItem(parent_dir, filename, kItemBlockDevice); |
161 |
|
|
ProcessFile(entry); |
162 |
|
|
} |
163 |
|
|
|
164 |
|
|
void SyncUnion::ProcessFifo(const std::string &parent_dir, |
165 |
|
|
const std::string &filename) { |
166 |
|
|
LogCvmfs(kLogUnionFs, kLogDebug, "SyncUnionOverlayfs::ProcessFifo(%s, %s)", |
167 |
|
|
parent_dir.c_str(), filename.c_str()); |
168 |
|
|
SharedPtr<SyncItem> entry = CreateSyncItem(parent_dir, filename, kItemFifo); |
169 |
|
|
ProcessFile(entry); |
170 |
|
|
} |
171 |
|
|
|
172 |
|
|
void SyncUnion::ProcessSocket(const std::string &parent_dir, |
173 |
|
|
const std::string &filename) { |
174 |
|
|
LogCvmfs(kLogUnionFs, kLogDebug, "SyncUnionOverlayfs::ProcessSocket(%s, %s)", |
175 |
|
|
parent_dir.c_str(), filename.c_str()); |
176 |
|
|
SharedPtr<SyncItem> entry = CreateSyncItem(parent_dir, filename, kItemSocket); |
177 |
|
|
ProcessFile(entry); |
178 |
|
|
} |
179 |
|
|
|
180 |
|
|
} // namespace publish |