GCC Code Coverage Report


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