GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/cache_transport.cc
Date: 2025-11-09 02:35:23
Exec Total Coverage
Lines: 328 372 88.2%
Branches: 168 228 73.7%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #include "cache_transport.h"
6
7 #include <alloca.h>
8 #include <errno.h>
9 #include <sys/socket.h>
10
11 #include <cassert>
12 #include <cstdlib>
13 #include <cstring>
14
15 #include "crypto/hash.h"
16 #include "util/exception.h"
17 #include "util/logging.h"
18 #include "util/posix.h"
19 #include "util/smalloc.h"
20
21 // TODO(jblomer): Check for possible starvation of plugin by dying clients
22 // (blocking read). Probably only relevant for TCP sockets.
23
24 using namespace std; // NOLINT
25
26 const char
27 *CacheTransport::kEnvReadyNotifyFd = "__CVMFS_CACHE_EXTERNAL_PIPE_READY__";
28
29 /**
30 * Called on the sender side to wrap a message into a MsgRpc message for wire
31 * transfer.
32 */
33 179499 cvmfs::MsgRpc *CacheTransport::Frame::GetMsgRpc() {
34
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 179499 times.
179499 assert(msg_typed_ != NULL);
35
1/2
✓ Branch 0 taken 179499 times.
✗ Branch 1 not taken.
179499 if (!is_wrapped_)
36 179499 WrapMsg();
37 179499 return &msg_rpc_;
38 }
39
40
41 /**
42 * Called on the receiving end of an RPC to extract the actual message from the
43 * MsgRpc.
44 */
45 223981 google::protobuf::MessageLite *CacheTransport::Frame::GetMsgTyped() {
46
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 223959 times.
223981 assert(msg_rpc_.IsInitialized());
47
2/2
✓ Branch 0 taken 187642 times.
✓ Branch 1 taken 36317 times.
223959 if (msg_typed_ == NULL)
48 187642 UnwrapMsg();
49 223893 return msg_typed_;
50 }
51
52
53 224069 CacheTransport::Frame::Frame()
54 224069 : owns_msg_typed_(false)
55 224069 , msg_typed_(NULL)
56 224069 , attachment_(NULL)
57 224069 , att_size_(0)
58 224069 , is_wrapped_(false)
59 224069 , is_msg_out_of_band_(false) { }
60
61
62 179499 CacheTransport::Frame::Frame(google::protobuf::MessageLite *m)
63 179499 : owns_msg_typed_(false)
64 179499 , msg_typed_(m)
65 179499 , attachment_(NULL)
66 179499 , att_size_(0)
67 179499 , is_wrapped_(false)
68 179499 , is_msg_out_of_band_(false) { }
69
70
71 403524 CacheTransport::Frame::~Frame() { Reset(0); }
72
73
74 36317 bool CacheTransport::Frame::IsMsgOutOfBand() {
75
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 36317 times.
36317 assert(msg_rpc_.IsInitialized());
76
1/2
✓ Branch 0 taken 36317 times.
✗ Branch 1 not taken.
36317 if (msg_typed_ == NULL)
77 36317 UnwrapMsg();
78 36317 return is_msg_out_of_band_;
79 }
80
81
82 44616 void CacheTransport::Frame::MergeFrom(const Frame &other) {
83 44616 msg_rpc_.CheckTypeAndMergeFrom(other.msg_rpc_);
84 44616 owns_msg_typed_ = true;
85
2/2
✓ Branch 0 taken 39600 times.
✓ Branch 1 taken 5016 times.
44616 if (other.att_size_ > 0) {
86
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39600 times.
39600 assert(att_size_ >= other.att_size_);
87 39600 memcpy(attachment_, other.attachment_, other.att_size_);
88 39600 att_size_ = other.att_size_;
89 }
90 44616 }
91
92
93 179365 bool CacheTransport::Frame::ParseMsgRpc(void *buffer, uint32_t size) {
94 179365 const bool retval = msg_rpc_.ParseFromArray(buffer, size);
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 179343 times.
179343 if (!retval)
96 return false;
97
98 // Cleanup typed message when Frame leaves scope
99 179343 owns_msg_typed_ = true;
100 179343 return true;
101 }
102
103
104 403546 void CacheTransport::Frame::Release() {
105
2/2
✓ Branch 0 taken 224047 times.
✓ Branch 1 taken 179499 times.
403546 if (owns_msg_typed_)
106 224047 return;
107
108 179499 msg_rpc_.release_msg_refcount_req();
109 179477 msg_rpc_.release_msg_refcount_reply();
110 179477 msg_rpc_.release_msg_read_req();
111 179455 msg_rpc_.release_msg_read_reply();
112 179477 msg_rpc_.release_msg_object_info_req();
113 179477 msg_rpc_.release_msg_object_info_reply();
114 179477 msg_rpc_.release_msg_store_req();
115 179477 msg_rpc_.release_msg_store_abort_req();
116 179499 msg_rpc_.release_msg_store_reply();
117 179499 msg_rpc_.release_msg_handshake();
118 179499 msg_rpc_.release_msg_handshake_ack();
119 179499 msg_rpc_.release_msg_quit();
120 179499 msg_rpc_.release_msg_ioctl();
121 179499 msg_rpc_.release_msg_info_req();
122 179499 msg_rpc_.release_msg_info_reply();
123 179499 msg_rpc_.release_msg_shrink_req();
124 179499 msg_rpc_.release_msg_shrink_reply();
125 179455 msg_rpc_.release_msg_list_req();
126 179455 msg_rpc_.release_msg_list_reply();
127 179477 msg_rpc_.release_msg_detach();
128 179477 msg_rpc_.release_msg_breadcrumb_store_req();
129 179477 msg_rpc_.release_msg_breadcrumb_load_req();
130 179477 msg_rpc_.release_msg_breadcrumb_reply();
131 }
132
133
134 403546 void CacheTransport::Frame::Reset(uint32_t original_att_size) {
135 403546 msg_typed_ = NULL;
136 403546 att_size_ = original_att_size;
137 403546 is_wrapped_ = false;
138 403546 is_msg_out_of_band_ = false;
139 403546 Release();
140 403480 msg_rpc_.Clear();
141 403480 owns_msg_typed_ = false;
142 403480 }
143
144
145 179499 void CacheTransport::Frame::WrapMsg() {
146
2/2
✓ Branch 3 taken 422 times.
✓ Branch 4 taken 179077 times.
179499 if (msg_typed_->GetTypeName() == "cvmfs.MsgHandshake") {
147 422 msg_rpc_.set_allocated_msg_handshake(
148 422 reinterpret_cast<cvmfs::MsgHandshake *>(msg_typed_));
149
2/2
✓ Branch 3 taken 396 times.
✓ Branch 4 taken 178681 times.
179077 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgHandshakeAck") {
150 396 msg_rpc_.set_allocated_msg_handshake_ack(
151 396 reinterpret_cast<cvmfs::MsgHandshakeAck *>(msg_typed_));
152
2/2
✓ Branch 3 taken 420 times.
✓ Branch 4 taken 178261 times.
178681 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgQuit") {
153 420 msg_rpc_.set_allocated_msg_quit(
154 420 reinterpret_cast<cvmfs::MsgQuit *>(msg_typed_));
155
2/2
✓ Branch 3 taken 88 times.
✓ Branch 4 taken 178173 times.
178261 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgIoctl") {
156 88 msg_rpc_.set_allocated_msg_ioctl(
157 88 reinterpret_cast<cvmfs::MsgIoctl *>(msg_typed_));
158
2/2
✓ Branch 3 taken 14912 times.
✓ Branch 4 taken 163261 times.
178173 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgRefcountReq") {
159 14912 msg_rpc_.set_allocated_msg_refcount_req(
160 14912 reinterpret_cast<cvmfs::MsgRefcountReq *>(msg_typed_));
161
2/2
✓ Branch 3 taken 12408 times.
✓ Branch 4 taken 150853 times.
163261 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgRefcountReply") {
162 12408 msg_rpc_.set_allocated_msg_refcount_reply(
163 12408 reinterpret_cast<cvmfs::MsgRefcountReply *>(msg_typed_));
164
2/2
✓ Branch 3 taken 376 times.
✓ Branch 4 taken 150477 times.
150853 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgObjectInfoReq") {
165 376 msg_rpc_.set_allocated_msg_object_info_req(
166 376 reinterpret_cast<cvmfs::MsgObjectInfoReq *>(msg_typed_));
167
2/2
✓ Branch 3 taken 352 times.
✓ Branch 4 taken 150125 times.
150477 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgObjectInfoReply") {
168 352 msg_rpc_.set_allocated_msg_object_info_reply(
169 352 reinterpret_cast<cvmfs::MsgObjectInfoReply *>(msg_typed_));
170
2/2
✓ Branch 3 taken 49347 times.
✓ Branch 4 taken 100778 times.
150125 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgReadReq") {
171 49347 msg_rpc_.set_allocated_msg_read_req(
172 49347 reinterpret_cast<cvmfs::MsgReadReq *>(msg_typed_));
173
2/2
✓ Branch 3 taken 48642 times.
✓ Branch 4 taken 52136 times.
100778 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgReadReply") {
174 48642 msg_rpc_.set_allocated_msg_read_reply(
175 48642 reinterpret_cast<cvmfs::MsgReadReply *>(msg_typed_));
176
2/2
✓ Branch 3 taken 15790 times.
✓ Branch 4 taken 36346 times.
52136 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgStoreReq") {
177 15790 msg_rpc_.set_allocated_msg_store_req(
178 15790 reinterpret_cast<cvmfs::MsgStoreReq *>(msg_typed_));
179
2/2
✓ Branch 3 taken 22 times.
✓ Branch 4 taken 36324 times.
36346 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgStoreAbortReq") {
180 22 msg_rpc_.set_allocated_msg_store_abort_req(
181 22 reinterpret_cast<cvmfs::MsgStoreAbortReq *>(msg_typed_));
182
2/2
✓ Branch 3 taken 13398 times.
✓ Branch 4 taken 22926 times.
36324 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgStoreReply") {
183 13398 msg_rpc_.set_allocated_msg_store_reply(
184 13398 reinterpret_cast<cvmfs::MsgStoreReply *>(msg_typed_));
185
2/2
✓ Branch 3 taken 112 times.
✓ Branch 4 taken 22814 times.
22926 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgInfoReq") {
186 112 msg_rpc_.set_allocated_msg_info_req(
187 112 reinterpret_cast<cvmfs::MsgInfoReq *>(msg_typed_));
188
2/2
✓ Branch 3 taken 88 times.
✓ Branch 4 taken 22726 times.
22814 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgInfoReply") {
189 88 msg_rpc_.set_allocated_msg_info_reply(
190 88 reinterpret_cast<cvmfs::MsgInfoReply *>(msg_typed_));
191
2/2
✓ Branch 3 taken 52 times.
✓ Branch 4 taken 22674 times.
22726 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgShrinkReq") {
192 52 msg_rpc_.set_allocated_msg_shrink_req(
193 52 reinterpret_cast<cvmfs::MsgShrinkReq *>(msg_typed_));
194
2/2
✓ Branch 3 taken 44 times.
✓ Branch 4 taken 22630 times.
22674 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgShrinkReply") {
195 44 msg_rpc_.set_allocated_msg_shrink_reply(
196 44 reinterpret_cast<cvmfs::MsgShrinkReply *>(msg_typed_));
197
2/2
✓ Branch 3 taken 228 times.
✓ Branch 4 taken 22402 times.
22630 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgListReq") {
198 228 msg_rpc_.set_allocated_msg_list_req(
199 228 reinterpret_cast<cvmfs::MsgListReq *>(msg_typed_));
200
2/2
✓ Branch 3 taken 220 times.
✓ Branch 4 taken 22182 times.
22402 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgListReply") {
201 220 msg_rpc_.set_allocated_msg_list_reply(
202 220 reinterpret_cast<cvmfs::MsgListReply *>(msg_typed_));
203
2/2
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 22158 times.
22182 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgBreadcrumbStoreReq") {
204 24 msg_rpc_.set_allocated_msg_breadcrumb_store_req(
205 24 reinterpret_cast<cvmfs::MsgBreadcrumbStoreReq *>(msg_typed_));
206
2/2
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 22110 times.
22158 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgBreadcrumbLoadReq") {
207 48 msg_rpc_.set_allocated_msg_breadcrumb_load_req(
208 48 reinterpret_cast<cvmfs::MsgBreadcrumbLoadReq *>(msg_typed_));
209
2/2
✓ Branch 3 taken 66 times.
✓ Branch 4 taken 22044 times.
22110 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgBreadcrumbReply") {
210 66 msg_rpc_.set_allocated_msg_breadcrumb_reply(
211 66 reinterpret_cast<cvmfs::MsgBreadcrumbReply *>(msg_typed_));
212
1/2
✓ Branch 3 taken 22044 times.
✗ Branch 4 not taken.
22044 } else if (msg_typed_->GetTypeName() == "cvmfs.MsgDetach") {
213 22044 msg_rpc_.set_allocated_msg_detach(
214 22044 reinterpret_cast<cvmfs::MsgDetach *>(msg_typed_));
215 22044 is_msg_out_of_band_ = true;
216 } else {
217 // Unexpected message type, should never happen
218 PANIC(NULL);
219 }
220 179499 is_wrapped_ = true;
221 179499 }
222
223
224 223959 void CacheTransport::Frame::UnwrapMsg() {
225
2/2
✓ Branch 1 taken 396 times.
✓ Branch 2 taken 223585 times.
223959 if (msg_rpc_.has_msg_handshake()) {
226 396 msg_typed_ = msg_rpc_.mutable_msg_handshake();
227
2/2
✓ Branch 1 taken 422 times.
✓ Branch 2 taken 223097 times.
223585 } else if (msg_rpc_.has_msg_handshake_ack()) {
228 422 msg_typed_ = msg_rpc_.mutable_msg_handshake_ack();
229
2/2
✓ Branch 1 taken 396 times.
✓ Branch 2 taken 222745 times.
223097 } else if (msg_rpc_.has_msg_quit()) {
230 396 msg_typed_ = msg_rpc_.mutable_msg_quit();
231
2/2
✓ Branch 1 taken 88 times.
✓ Branch 2 taken 222635 times.
222745 } else if (msg_rpc_.has_msg_ioctl()) {
232 88 msg_typed_ = msg_rpc_.mutable_msg_ioctl();
233
2/2
✓ Branch 1 taken 12408 times.
✓ Branch 2 taken 210205 times.
222635 } else if (msg_rpc_.has_msg_refcount_req()) {
234 12408 msg_typed_ = msg_rpc_.mutable_msg_refcount_req();
235
2/2
✓ Branch 1 taken 15308 times.
✓ Branch 2 taken 194831 times.
210205 } else if (msg_rpc_.has_msg_refcount_reply()) {
236 15308 msg_typed_ = msg_rpc_.mutable_msg_refcount_reply();
237
2/2
✓ Branch 1 taken 352 times.
✓ Branch 2 taken 194501 times.
194831 } else if (msg_rpc_.has_msg_object_info_req()) {
238 352 msg_typed_ = msg_rpc_.mutable_msg_object_info_req();
239
2/2
✓ Branch 1 taken 552 times.
✓ Branch 2 taken 193949 times.
194501 } else if (msg_rpc_.has_msg_object_info_reply()) {
240 552 msg_typed_ = msg_rpc_.mutable_msg_object_info_reply();
241
2/2
✓ Branch 1 taken 48642 times.
✓ Branch 2 taken 145329 times.
193949 } else if (msg_rpc_.has_msg_read_req()) {
242 48642 msg_typed_ = msg_rpc_.mutable_msg_read_req();
243
2/2
✓ Branch 1 taken 88947 times.
✓ Branch 2 taken 56514 times.
145329 } else if (msg_rpc_.has_msg_read_reply()) {
244 88947 msg_typed_ = msg_rpc_.mutable_msg_read_reply();
245
2/2
✓ Branch 1 taken 13376 times.
✓ Branch 2 taken 43138 times.
56514 } else if (msg_rpc_.has_msg_store_req()) {
246 13376 msg_typed_ = msg_rpc_.mutable_msg_store_req();
247
2/2
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 43116 times.
43138 } else if (msg_rpc_.has_msg_store_abort_req()) {
248 22 msg_typed_ = msg_rpc_.mutable_msg_store_abort_req();
249
2/2
✓ Branch 1 taken 20212 times.
✓ Branch 2 taken 22904 times.
43116 } else if (msg_rpc_.has_msg_store_reply()) {
250 20212 msg_typed_ = msg_rpc_.mutable_msg_store_reply();
251
2/2
✓ Branch 1 taken 88 times.
✓ Branch 2 taken 22816 times.
22904 } else if (msg_rpc_.has_msg_info_req()) {
252 88 msg_typed_ = msg_rpc_.mutable_msg_info_req();
253
2/2
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 22704 times.
22816 } else if (msg_rpc_.has_msg_info_reply()) {
254 112 msg_typed_ = msg_rpc_.mutable_msg_info_reply();
255
2/2
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 22660 times.
22704 } else if (msg_rpc_.has_msg_shrink_req()) {
256 44 msg_typed_ = msg_rpc_.mutable_msg_shrink_req();
257
2/2
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 22608 times.
22660 } else if (msg_rpc_.has_msg_shrink_reply()) {
258 52 msg_typed_ = msg_rpc_.mutable_msg_shrink_reply();
259
2/2
✓ Branch 1 taken 220 times.
✓ Branch 2 taken 22388 times.
22608 } else if (msg_rpc_.has_msg_list_req()) {
260 220 msg_typed_ = msg_rpc_.mutable_msg_list_req();
261
2/2
✓ Branch 1 taken 228 times.
✓ Branch 2 taken 22160 times.
22388 } else if (msg_rpc_.has_msg_list_reply()) {
262 228 msg_typed_ = msg_rpc_.mutable_msg_list_reply();
263
2/2
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 22138 times.
22160 } else if (msg_rpc_.has_msg_breadcrumb_store_req()) {
264 22 msg_typed_ = msg_rpc_.mutable_msg_breadcrumb_store_req();
265
2/2
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 22094 times.
22138 } else if (msg_rpc_.has_msg_breadcrumb_load_req()) {
266 44 msg_typed_ = msg_rpc_.mutable_msg_breadcrumb_load_req();
267
2/2
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 22022 times.
22094 } else if (msg_rpc_.has_msg_breadcrumb_reply()) {
268 72 msg_typed_ = msg_rpc_.mutable_msg_breadcrumb_reply();
269
1/2
✓ Branch 1 taken 22022 times.
✗ Branch 2 not taken.
22022 } else if (msg_rpc_.has_msg_detach()) {
270 22022 msg_typed_ = msg_rpc_.mutable_msg_detach();
271 22022 is_msg_out_of_band_ = true;
272 } else {
273 // Unexpected message type, should never happen
274 PANIC(NULL);
275 }
276 224047 }
277
278
279 //------------------------------------------------------------------------------
280
281
282 422 CacheTransport::CacheTransport(int fd_connection)
283 422 : fd_connection_(fd_connection), flags_(0) {
284
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 422 times.
422 assert(fd_connection_ >= 0);
285 422 }
286
287
288 98142 CacheTransport::CacheTransport(int fd_connection, uint32_t flags)
289 98142 : fd_connection_(fd_connection), flags_(flags) {
290
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98142 times.
98142 assert(fd_connection_ >= 0);
291 98142 }
292
293
294 4431777 void CacheTransport::FillMsgHash(const shash::Any &hash,
295 cvmfs::MsgHash *msg_hash) {
296
3/4
✓ Branch 0 taken 4431707 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 58 times.
✗ Branch 3 not taken.
4431777 switch (hash.algorithm) {
297 4431707 case shash::kSha1:
298 4431707 msg_hash->set_algorithm(cvmfs::HASH_SHA1);
299 4431707 break;
300 12 case shash::kRmd160:
301 12 msg_hash->set_algorithm(cvmfs::HASH_RIPEMD160);
302 12 break;
303 58 case shash::kShake128:
304 58 msg_hash->set_algorithm(cvmfs::HASH_SHAKE128);
305 58 break;
306 default:
307 PANIC(NULL);
308 }
309 4431777 msg_hash->set_digest(hash.digest, shash::kDigestSizes[hash.algorithm]);
310 4431777 }
311
312
313 15782 void CacheTransport::FillObjectType(int object_flags,
314 cvmfs::EnumObjectType *wire_type) {
315 15782 *wire_type = cvmfs::OBJECT_REGULAR;
316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15782 times.
15782 if (object_flags & CacheManager::kLabelCatalog)
317 *wire_type = cvmfs::OBJECT_CATALOG;
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15782 times.
15782 if (object_flags & CacheManager::kLabelVolatile)
319 *wire_type = cvmfs::OBJECT_VOLATILE;
320 15782 }
321
322
323 74824 bool CacheTransport::ParseMsgHash(const cvmfs::MsgHash &msg_hash,
324 shash::Any *hash) {
325
2/4
✓ Branch 1 taken 74778 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 46 times.
✗ Branch 4 not taken.
74824 switch (msg_hash.algorithm()) {
326 74778 case cvmfs::HASH_SHA1:
327 74778 hash->algorithm = shash::kSha1;
328 74778 break;
329 case cvmfs::HASH_RIPEMD160:
330 hash->algorithm = shash::kRmd160;
331 break;
332 46 case cvmfs::HASH_SHAKE128:
333 46 hash->algorithm = shash::kShake128;
334 46 break;
335 default:
336 return false;
337 }
338 74824 const unsigned digest_size = shash::kDigestSizes[hash->algorithm];
339
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 74824 times.
74824 if (msg_hash.digest().length() != digest_size)
340 return false;
341 74824 memcpy(hash->digest, msg_hash.digest().data(), digest_size);
342 74824 return true;
343 }
344
345
346 bool CacheTransport::ParseObjectType(cvmfs::EnumObjectType wire_type,
347 int *object_flags) {
348 *object_flags = 0;
349 switch (wire_type) {
350 case cvmfs::OBJECT_REGULAR:
351 return true;
352 case cvmfs::OBJECT_CATALOG:
353 *object_flags |= CacheManager::kLabelCatalog;
354 return true;
355 case cvmfs::OBJECT_VOLATILE:
356 *object_flags |= CacheManager::kLabelVolatile;
357 return true;
358 default:
359 return false;
360 }
361 }
362
363
364 179475 bool CacheTransport::RecvFrame(CacheTransport::Frame *frame) {
365 uint32_t size;
366 bool has_attachment;
367
1/2
✓ Branch 1 taken 179475 times.
✗ Branch 2 not taken.
179475 bool retval = RecvHeader(&size, &has_attachment);
368
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 179453 times.
179475 if (!retval)
369 22 return false;
370
371 void *buffer;
372
2/2
✓ Branch 0 taken 117047 times.
✓ Branch 1 taken 62406 times.
179453 if (size <= kMaxStackAlloc)
373 117047 buffer = alloca(size);
374 else
375 62406 buffer = smalloc(size);
376
1/2
✓ Branch 1 taken 179453 times.
✗ Branch 2 not taken.
179453 const ssize_t nbytes = SafeRead(fd_connection_, buffer, size);
377
3/4
✓ Branch 0 taken 179365 times.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 179365 times.
179453 if ((nbytes < 0) || (static_cast<uint32_t>(nbytes) != size)) {
378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if (size > kMaxStackAlloc) {
379 free(buffer);
380 }
381 88 return false;
382 }
383
384 179365 uint32_t msg_size = size;
385
2/2
✓ Branch 0 taken 62673 times.
✓ Branch 1 taken 116692 times.
179365 if (has_attachment) {
386
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62673 times.
62673 if (size < 2) {
387 // kMaxStackAlloc is > 2 (of course!) but we'll leave the condition here
388 // for consistency.
389 if (size > kMaxStackAlloc) {
390 free(buffer);
391 }
392 return false;
393 }
394 62673 msg_size = (*reinterpret_cast<unsigned char *>(buffer))
395 62673 + ((*(reinterpret_cast<unsigned char *>(buffer) + 1)) << 8);
396
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62673 times.
62673 if ((msg_size + kInnerHeaderSize) > size) {
397 if (size > kMaxStackAlloc) {
398 free(buffer);
399 }
400 return false;
401 }
402 }
403
404 179365 void *ptr_msg = has_attachment
405
2/2
✓ Branch 0 taken 62673 times.
✓ Branch 1 taken 116692 times.
179365 ? (reinterpret_cast<char *>(buffer) + kInnerHeaderSize)
406 : buffer;
407
1/2
✓ Branch 1 taken 179343 times.
✗ Branch 2 not taken.
179365 retval = frame->ParseMsgRpc(ptr_msg, msg_size);
408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 179343 times.
179343 if (!retval) {
409 if (size > kMaxStackAlloc) {
410 free(buffer);
411 }
412 return false;
413 }
414
415
2/2
✓ Branch 0 taken 62673 times.
✓ Branch 1 taken 116670 times.
179343 if (has_attachment) {
416 62673 const uint32_t attachment_size = size - (msg_size + kInnerHeaderSize);
417
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 62673 times.
62673 if (frame->att_size() < attachment_size) {
418 if (size > kMaxStackAlloc) {
419 free(buffer);
420 }
421 return false;
422 }
423 62673 void *ptr_attachment = reinterpret_cast<char *>(buffer) + kInnerHeaderSize
424 62673 + msg_size;
425 62673 memcpy(frame->attachment(), ptr_attachment, attachment_size);
426 62673 frame->set_att_size(attachment_size);
427 } else {
428 116670 frame->set_att_size(0);
429 }
430
2/2
✓ Branch 0 taken 62406 times.
✓ Branch 1 taken 117047 times.
179453 if (size > kMaxStackAlloc) {
431 62406 free(buffer);
432 }
433 179453 return true;
434 }
435
436
437 179475 bool CacheTransport::RecvHeader(uint32_t *size, bool *has_attachment) {
438 unsigned char header[kHeaderSize];
439
1/2
✓ Branch 1 taken 179475 times.
✗ Branch 2 not taken.
179475 const ssize_t nbytes = SafeRead(fd_connection_, header, kHeaderSize);
440
3/4
✓ Branch 0 taken 179475 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 179453 times.
179475 if ((nbytes < 0) || (static_cast<unsigned>(nbytes) != kHeaderSize))
441 22 return false;
442
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 179453 times.
179453 if ((header[0] & (~kFlagHasAttachment)) != kWireProtocolVersion)
443 return false;
444 179453 *has_attachment = header[0] & kFlagHasAttachment;
445 179453 *size = header[1] + (header[2] << 8) + (header[3] << 16);
446
2/4
✓ Branch 0 taken 179453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 179453 times.
✗ Branch 3 not taken.
179453 return (*size > 0) && (*size <= kMaxMsgSize);
447 }
448
449
450 179499 void CacheTransport::SendData(void *message,
451 uint32_t msg_size,
452 void *attachment,
453 uint32_t att_size) {
454 358998 const uint32_t total_size = msg_size + att_size
455
2/2
✓ Branch 0 taken 64386 times.
✓ Branch 1 taken 115113 times.
179499 + ((att_size > 0) ? kInnerHeaderSize : 0);
456
457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 179499 times.
179499 assert(total_size > 0);
458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 179499 times.
179499 assert(total_size <= kMaxMsgSize);
459
1/2
✓ Branch 1 taken 173756 times.
✗ Branch 2 not taken.
173756 LogCvmfs(kLogCache, kLogDebug,
460 "sending message of size %u to cache transport", total_size);
461
462 unsigned char header[kHeaderSize];
463
2/2
✓ Branch 0 taken 115113 times.
✓ Branch 1 taken 64386 times.
179499 header[0] = kWireProtocolVersion | ((att_size == 0) ? 0 : kFlagHasAttachment);
464 179499 header[1] = (total_size & 0x000000FF);
465 179499 header[2] = (total_size & 0x0000FF00) >> 8;
466 179499 header[3] = (total_size & 0x00FF0000) >> 16;
467 // Only transferred if an attachment is present. Otherwise the overall size
468 // is also the size of the protobuf message.
469 unsigned char inner_header[kInnerHeaderSize];
470
471 struct iovec iov[4];
472 179499 iov[0].iov_base = header;
473 179499 iov[0].iov_len = kHeaderSize;
474
475
2/2
✓ Branch 0 taken 64386 times.
✓ Branch 1 taken 115113 times.
179499 if (att_size > 0) {
476 64386 inner_header[0] = (msg_size & 0x000000FF);
477 64386 inner_header[1] = (msg_size & 0x0000FF00) >> 8;
478 64386 iov[1].iov_base = inner_header;
479 64386 iov[1].iov_len = kInnerHeaderSize;
480 64386 iov[2].iov_base = message;
481 64386 iov[2].iov_len = msg_size;
482 64386 iov[3].iov_base = attachment;
483 64386 iov[3].iov_len = att_size;
484 } else {
485 115113 iov[1].iov_base = message;
486 115113 iov[1].iov_len = msg_size;
487 }
488
2/2
✓ Branch 0 taken 22044 times.
✓ Branch 1 taken 157455 times.
179499 if (flags_ & kFlagSendNonBlocking) {
489
2/4
✓ Branch 0 taken 22044 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 22044 times.
✗ Branch 4 not taken.
22044 SendNonBlocking(iov, (att_size == 0) ? 2 : 4);
490 22044 return;
491 }
492
3/4
✓ Branch 0 taken 93069 times.
✓ Branch 1 taken 64386 times.
✓ Branch 3 taken 157455 times.
✗ Branch 4 not taken.
157455 const bool retval = SafeWriteV(fd_connection_, iov, (att_size == 0) ? 2 : 4);
493
494
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 157455 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
157455 if (!retval && !(flags_ & kFlagSendIgnoreFailure)) {
495 PANIC(kLogSyslogErr | kLogDebug,
496 "failed to write to external cache transport (%d), aborting", errno);
497 }
498 }
499
500 22044 void CacheTransport::SendNonBlocking(struct iovec *iov, unsigned iovcnt) {
501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22044 times.
22044 assert(iovcnt > 0);
502 22044 unsigned total_size = 0;
503
2/2
✓ Branch 0 taken 44088 times.
✓ Branch 1 taken 22044 times.
66132 for (unsigned i = 0; i < iovcnt; ++i)
504 44088 total_size += iov[i].iov_len;
505 22044 unsigned char *buffer = reinterpret_cast<unsigned char *>(alloca(total_size));
506
507 22044 unsigned pos = 0;
508
2/2
✓ Branch 0 taken 44088 times.
✓ Branch 1 taken 22044 times.
66132 for (unsigned i = 0; i < iovcnt; ++i) {
509 44088 memcpy(buffer + pos, iov[i].iov_base, iov[i].iov_len);
510 44088 pos += iov[i].iov_len;
511 }
512
513 22044 const int retval = send(fd_connection_, buffer, total_size, MSG_DONTWAIT);
514
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22044 times.
22044 if (retval < 0) {
515 assert(errno != EMSGSIZE);
516 if (!(flags_ & kFlagSendIgnoreFailure)) {
517 PANIC(kLogSyslogErr | kLogDebug,
518 "failed to write to external cache transport (%d), aborting",
519 errno);
520 }
521 }
522 22044 }
523
524
525 179499 void CacheTransport::SendFrame(CacheTransport::Frame *frame) {
526 179499 cvmfs::MsgRpc *msg_rpc = frame->GetMsgRpc();
527 179499 const int32_t size = msg_rpc->ByteSize();
528
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 179499 times.
179499 assert(size > 0);
529 #ifdef __APPLE__
530 void *buffer = smalloc(size);
531 #else
532 179499 void *buffer = alloca(size);
533 #endif
534 179499 const bool retval = msg_rpc->SerializeToArray(buffer, size);
535
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 179499 times.
179499 assert(retval);
536 179499 SendData(buffer, size, frame->attachment(), frame->att_size());
537 #ifdef __APPLE__
538 free(buffer);
539 #endif
540 179455 }
541