GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/cache_transport.h
Date: 2026-04-26 02:35:59
Exec Total Coverage
Lines: 15 39 38.5%
Branches: 2 14 14.3%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4 #ifndef CVMFS_CACHE_TRANSPORT_H_
5 #define CVMFS_CACHE_TRANSPORT_H_
6
7 #include <stdint.h>
8
9 #include <cstdlib>
10
11 #include "cache.pb.h"
12 #include "util/single_copy.h"
13
14 namespace shash {
15 struct Any;
16 }
17
18 117 inline const char *CacheTransportCode2Ascii(const cvmfs::EnumStatus code) {
19
2/14
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 78 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 39 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
117 switch (code) {
20 case cvmfs::STATUS_UNKNOWN:
21 return "unknown cache protocol error";
22 case cvmfs::STATUS_OK:
23 return "OK";
24 case cvmfs::STATUS_NOSUPPORT:
25 return "operation not implemented by cache plugin";
26 case cvmfs::STATUS_FORBIDDEN:
27 return "cache plugin denied the operation";
28 case cvmfs::STATUS_NOSPACE:
29 return "no space in cache";
30 case cvmfs::STATUS_NOENTRY:
31 return "object not found in cache";
32 78 case cvmfs::STATUS_MALFORMED:
33 78 return "malformed cache protocol message";
34 case cvmfs::STATUS_IOERR:
35 return "I/O error";
36 case cvmfs::STATUS_CORRUPTED:
37 return "corrupted data detected";
38 case cvmfs::STATUS_TIMEOUT:
39 return "multipart request timed out";
40 case cvmfs::STATUS_BADCOUNT:
41 return "invalid attempt to set negative reference count";
42 39 case cvmfs::STATUS_OUTOFBOUNDS:
43 39 return "out of bounds";
44 case cvmfs::STATUS_PARTIAL:
45 return "cache could not be cleaned up to the given limit";
46 default:
47 return "unexpected cache protocol error";
48 }
49 }
50
51 /**
52 * Sending and receiving with a file descriptor. Does _not_ take the ownership
53 * of the file descriptor.
54 */
55 class CacheTransport {
56 public:
57 /**
58 * When this environment variable is set, the plugin will notify a cvmfs
59 * client once it is ready to accept connections.
60 */
61 static const char *kEnvReadyNotifyFd; // __CVMFS_CACHE_EXTERNAL_PIPE_READY__
62 static const char kReadyNotification = 'C';
63 static const char kFailureNotification = 'F';
64 /**
65 * Version of the wire protocol. The effective protocol version is negotiated
66 * through the handshake.
67 */
68 static const unsigned char kWireProtocolVersion = 0x01;
69 /**
70 * This is or-ed to the version number if the message has an attachment. In
71 * this case, the 2 bytes after the header specify the size of the protobuf
72 * message alone.
73 */
74 static const unsigned char kFlagHasAttachment = 0x80;
75 /**
76 * Maximum size of the protobuf message _and_ the attachment, should it exist.
77 */
78 static const uint32_t kMaxMsgSize = (2 << 24) - 1; // 24MB (3 bytes)
79 /**
80 * The first byte has the wire protocol version, optionally or-ed with the
81 * "has attachment" flag. The other three bytes encode the overall message
82 * size in little-endian.
83 */
84 static const unsigned kHeaderSize = 4;
85 /**
86 * The "inner header" are two byte following the header. The two bytes encode
87 * in little-endian the size of the protobuf message alone, if there is an
88 * attachment. The inner header is only present if there is an attachment.
89 */
90 static const unsigned kInnerHeaderSize = 2;
91
92 static const uint32_t kFlagSendIgnoreFailure = 0x01;
93 static const uint32_t kFlagSendNonBlocking = 0x02;
94
95
96 /**
97 * A single unit of data transfer contains a "typed" Msg... protobuf message
98 * inside a MsgRpc message. Optionally, there can be an "attachment", which
99 * is a byte stream following the protobuf message. The typed message and the
100 * attachment buffer are (stack)-allocated by users of CacheTransport. The
101 * Frame subclass takes care of wrapping and unwrapping into/from MsgRpc
102 * message.
103 */
104 class Frame : SingleCopy {
105 public:
106 Frame();
107 explicit Frame(google::protobuf::MessageLite *m);
108 ~Frame();
109 void MergeFrom(const Frame &other);
110 void Reset(uint32_t original_att_size);
111
112 448000 void *attachment() const { return attachment_; }
113 752860 uint32_t att_size() const { return att_size_; }
114 313468 void set_att_size(uint32_t size) { att_size_ = size; }
115 452048 void set_attachment(void *attachment, uint32_t att_size) {
116 452048 attachment_ = attachment;
117 452048 att_size_ = att_size;
118 452048 }
119
120 bool ParseMsgRpc(void *buffer, uint32_t size);
121 cvmfs::MsgRpc *GetMsgRpc();
122 google::protobuf::MessageLite *GetMsgTyped();
123 // The Detach message does not follow the command-reply pattern
124 bool IsMsgOutOfBand();
125
126 private:
127 void WrapMsg();
128 void UnwrapMsg();
129 void Release();
130
131 cvmfs::MsgRpc msg_rpc_;
132 bool owns_msg_typed_;
133 /**
134 * Can either point to a user-provided message (sender side) or to a message
135 * inside msg_rpc_ (receiving end)
136 */
137 google::protobuf::MessageLite *msg_typed_;
138 void *attachment_;
139 uint32_t att_size_;
140 bool is_wrapped_;
141 bool is_msg_out_of_band_;
142 }; // class CacheTransport::Frame
143
144
145 explicit CacheTransport(int fd_connection);
146 CacheTransport(int fd_connection, uint32_t flags);
147 174471 ~CacheTransport() { }
148
149 void SendFrame(Frame *frame);
150 bool RecvFrame(Frame *frame);
151
152 void FillMsgHash(const shash::Any &hash, cvmfs::MsgHash *msg_hash);
153 bool ParseMsgHash(const cvmfs::MsgHash &msg_hash, shash::Any *hash);
154 void FillObjectType(int object_flags, cvmfs::EnumObjectType *wire_type);
155 bool ParseObjectType(cvmfs::EnumObjectType wire_type, int *object_flags);
156
157 1452 int fd_connection() const { return fd_connection_; }
158
159 private:
160 static const unsigned kMaxStackAlloc = 256 * 1024; // 256 kB
161
162 void SendData(void *message,
163 uint32_t msg_size,
164 void *attachment = NULL,
165 uint32_t att_size = 0);
166 void SendNonBlocking(struct iovec *iov, unsigned iovcnt);
167 bool RecvHeader(uint32_t *size, bool *has_attachment);
168
169 int fd_connection_;
170 uint32_t flags_;
171 }; // class CacheTransport
172
173 #endif // CVMFS_CACHE_TRANSPORT_H_
174