kinetic-c  v0.12.0
Seagate Kinetic Protocol Client Library for C
kinetic_types_internal.c
Go to the documentation of this file.
1 /*
2 * kinetic-c
3 * Copyright (C) 2015 Seagate Technology.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 */
20 
21 #include "kinetic_types_internal.h"
22 #include "kinetic_logger.h"
23 #include "byte_array.h"
24 #include <sys/param.h>
25 #include <errno.h>
26 
27 // Type mapping from from public to internal protobuf status type
30 {
31  KineticStatus status;
32 
33  switch (protoStatus) {
34 
35  // Start one-to-one status mappings
37  status = KINETIC_STATUS_SUCCESS;
38  break;
41  break;
44  break;
47  break;
50  break;
52  status = KINETIC_STATUS_NOT_FOUND;
53  break;
56  break;
57  // End one-to-one mappings
58 
64  break;
65 
69  break;
70 
76  break;
77 
80  break;
81 
84  break;
85 
86  default:
88  status = KINETIC_STATUS_INVALID;
89  break;
90  }
91 
92  return status;
93 }
94 
96  KineticSynchronization sync_mode)
97 {
99  switch (sync_mode) {
102  break;
105  break;
108  break;
109  default:
112  break;
113  };
114  return protoSyncMode;
115 }
116 
119 {
120  KineticSynchronization kineticSyncMode;
121  switch (sync_mode) {
123  kineticSyncMode = KINETIC_SYNCHRONIZATION_WRITETHROUGH;
124  break;
126  kineticSyncMode = KINETIC_SYNCHRONIZATION_WRITEBACK;
127  break;
129  kineticSyncMode = KINETIC_SYNCHRONIZATION_FLUSH;
130  break;
131  default:
133  kineticSyncMode = KINETIC_SYNCHRONIZATION_INVALID;
134  break;
135  };
136  return kineticSyncMode;
137 }
138 
139 // Type mapping from public to internal types
141  KineticAlgorithm kinteicAlgorithm)
142 {
144  switch (kinteicAlgorithm) {
147  break;
150  break;
153  break;
156  break;
159  break;
161  default:
163  break;
164  };
165  return protoAlgorithm;
166 }
167 
168 
169 
170 // Type mapping from internal types
173 {
174  KineticAlgorithm kineticAlgorithm;
175  switch (protoAlgorithm) {
177  kineticAlgorithm = KINETIC_ALGORITHM_SHA1;
178  break;
180  kineticAlgorithm = KINETIC_ALGORITHM_SHA2;
181  break;
183  kineticAlgorithm = KINETIC_ALGORITHM_SHA3;
184  break;
186  kineticAlgorithm = KINETIC_ALGORITHM_CRC32;
187  break;
189  kineticAlgorithm = KINETIC_ALGORITHM_CRC64;
190  break;
192  default:
193  kineticAlgorithm = KINETIC_ALGORITHM_INVALID;
194  break;
195  };
196  return kineticAlgorithm;
197 }
198 
200  ProtobufCBinaryData protoData)
201 {
202  return (ByteArray) {
203  .data = protoData.data, .len = protoData.len
204  };
205 }
206 
207 
208 bool Copy_ProtobufCBinaryData_to_ByteBuffer(ByteBuffer dest, ProtobufCBinaryData src)
209 {
210  if (src.data == NULL || src.len == 0) {
211  return false;
212  }
213  if (dest.array.data == NULL || dest.array.len < src.len) {
214  return false;
215  }
216 
217  bool success = (memcpy(dest.array.data, src.data, src.len) == dest.array.data);
218  if (success) {
219  dest.bytesUsed = src.len;
220  }
221 
222  return success;
223 }
224 
225 
226 bool Copy_Com__Seagate__Kinetic__Proto__Command__KeyValue_to_KineticEntry(Com__Seagate__Kinetic__Proto__Command__KeyValue* key_value, KineticEntry* entry)
227 {
228  bool bufferOverflow = false;
229 
230  if (key_value != NULL && entry != NULL) {
231  ByteBuffer_Reset(&entry->dbVersion);
232  if (key_value->has_dbversion && key_value->dbversion.len > 0) {
233  if (entry->dbVersion.array.data == NULL || entry->dbVersion.array.len < key_value->dbversion.len) {
234  entry->dbVersion.bytesUsed = key_value->dbversion.len;
235  LOG1(" BUFFER_OVERRUN: dbVersion");
236  bufferOverflow = true;
237  }
238  else {
239  ByteBuffer_Append(&entry->dbVersion, key_value->dbversion.data, key_value->dbversion.len);
240  }
241  }
242 
243  ByteBuffer_Reset(&entry->key);
244  if (key_value->has_key && key_value->key.len > 0) {
245  if (entry->key.array.data == NULL || entry->key.array.len < key_value->key.len) {
246  entry->key.bytesUsed = key_value->key.len;
247  LOG1(" BUFFER_OVERRUN: key");
248  bufferOverflow = true;
249  }
250  else {
251  ByteBuffer_Append(&entry->key, key_value->key.data, key_value->key.len);
252  }
253  }
254 
255  ByteBuffer_Reset(&entry->tag);
256  if (key_value->has_tag && key_value->tag.len > 0) {
257  if (entry->tag.array.data == NULL || entry->tag.array.len < key_value->tag.len) {
258  entry->tag.bytesUsed = key_value->tag.len;
259  LOG1(" BUFFER_OVERRUN: tag");
260  bufferOverflow = true;
261  }
262  else {
263  ByteBuffer_Append(&entry->tag, key_value->tag.data, key_value->tag.len);
264  }
265  }
266 
267  if (key_value->has_algorithm) {
268  entry->algorithm =
270  key_value->algorithm);
271  }
272  }
273 
274  return !bufferOverflow;
275 }
276 
277 bool Copy_Com__Seagate__Kinetic__Proto__Command__Range_to_ByteBufferArray(Com__Seagate__Kinetic__Proto__Command__Range* keyRange, ByteBufferArray* keys)
278 {
279  bool bufferOverflow = false;
280  LOGF2("Copying: keyRange=0x%0llX, keys=0x%0llX, max_keys=%lld", keyRange, keys->buffers, keys->count);
281  if (keyRange != NULL && keys->count > 0 && keys != NULL) {
282  for (size_t i = 0; i < MIN((size_t)keys->count, (size_t)keyRange->n_keys); i++) {
283  ByteBuffer_Reset(&keys->buffers[i]);
284  if (ByteBuffer_Append(&keys->buffers[i], keyRange->keys[i].data, keyRange->keys[i].len) == NULL) {
285  LOGF2("WANRNING: Buffer overrun for keys[%zd]", i);
286  bufferOverflow = true;
287  }
288  }
289  keys->used = keyRange->n_keys;
290  }
291  return !bufferOverflow;
292 }
293 
294 int Kinetic_GetErrnoDescription(int err_num, char *buf, size_t len)
295 {
296  static pthread_mutex_t strerror_lock = PTHREAD_MUTEX_INITIALIZER;
297  if (!len) {
298  errno = ENOSPC;
299  return -1;
300  }
301  buf[0] = '\0';
302  pthread_mutex_lock(&strerror_lock);
303  strncat(buf, strerror(err_num), len - 1);
304  pthread_mutex_unlock(&strerror_lock);
305  return 0;
306 }
307 
308 struct timeval Kinetic_TimevalZero(void)
309 {
310  return (struct timeval) {
311  .tv_sec = 0,
312  .tv_usec = 0,
313  };
314 }
315 
316 bool Kinetic_TimevalIsZero(struct timeval const tv)
317 {
318  return tv.tv_sec == 0 && tv.tv_usec == 0;
319 }
320 
321 struct timeval Kinetic_TimevalAdd(struct timeval const a, struct timeval const b)
322 {
323  struct timeval result = {
324  .tv_sec = a.tv_sec + b.tv_sec,
325  .tv_usec = a.tv_usec + b.tv_usec,
326  };
327 
328  if (result.tv_usec >= 1000000) {
329  result.tv_sec++;
330  result.tv_usec -= 1000000;
331  }
332  return result;
333 }
334 
335 static int cmp_suseconds_t(suseconds_t const a, suseconds_t const b)
336 {
337  if (a == b) {
338  return 0;
339  }
340  else if (a > b) {
341  return 1;
342  }
343  else {
344  return -1;
345  }
346 }
347 
348 int Kinetic_TimevalCmp(struct timeval const a, struct timeval const b)
349 {
350  return (a.tv_sec == b.tv_sec) ? cmp_suseconds_t(a.tv_usec, b.tv_usec) : ((a.tv_sec > b.tv_sec) ? 1 : -1);
351 }
352 
354 {
356 
357  switch(type) {
372  default:
374  };
375 
376  return protoType;
377 }
378 
380 {
381  return (KineticMessageType)type;
382 }
383 
385 {
386  KINETIC_ASSERT(dest != NULL);
387  KINETIC_ASSERT(src != NULL);
388  if (dest == src) {return;}
389  *dest = *src;
390  if (src->hmacKey.data != NULL) {
391  memcpy(dest->keyData, src->hmacKey.data, src->hmacKey.len);
392  }
393 }
394 
396 {
397  KINETIC_ASSERT(message != NULL);
398 
413 }
414 
415 static void KineticMessage_HeaderInit(Com__Seagate__Kinetic__Proto__Command__Header* hdr, KineticSession const * const session)
416 {
417  KINETIC_ASSERT(hdr != NULL);
418  KINETIC_ASSERT(session != NULL);
419  *hdr = (Com__Seagate__Kinetic__Proto__Command__Header) {
420  .base = PROTOBUF_C_MESSAGE_INIT(&com__seagate__kinetic__proto__command__header__descriptor),
421  .has_clusterversion = true,
422  .clusterversion = session->config.clusterVersion,
423  .has_connectionid = true,
424  .connectionid = session->connectionID,
425  .has_sequence = true,
426  .sequence = KINETIC_SEQUENCE_NOT_YET_BOUND,
427  };
428 }
429 
430 void KineticRequest_Init(KineticRequest* request, KineticSession const * const session)
431 {
432  KINETIC_ASSERT(request != NULL);
433  KINETIC_ASSERT(session != NULL);
434  memset(request, 0, sizeof(KineticRequest));
435  KineticMessage_Init(&(request->message));
436  KineticMessage_HeaderInit(&(request->message.header), session);
437  request->command = &request->message.command;
438  request->command->header = &request->message.header;
439 }
An HMAC validation error was detected.
Structure for handling generic arrays of bytes.
Definition: byte_array.h:34
KineticSynchronization
Enumeration of synchronization types for an operation on a KineticEntry.
Definition: kinetic_types.h:86
void ByteBuffer_Reset(ByteBuffer *buffer)
Definition: byte_array.c:62
KineticStatus KineticProtoStatusCode_to_KineticStatus(Com__Seagate__Kinetic__Proto__Command__Status__StatusCode protoStatus)
ByteBuffer * ByteBuffer_Append(ByteBuffer *buffer, const void *data, size_t len)
Definition: byte_array.c:135
Com__Seagate__Kinetic__Proto__Command__MessageType
Definition: kinetic.pb-c.h:304
Structure for an embedded ByteArray as a buffer.
Definition: byte_array.h:53
void com__seagate__kinetic__proto__message__init(Com__Seagate__Kinetic__Proto__Message *message)
Definition: kinetic.pb-c.c:66
void com__seagate__kinetic__proto__command__range__init(Com__Seagate__Kinetic__Proto__Command__Range *message)
Definition: kinetic.pb-c.c:133
This request is made persistent before returning.
Definition: kinetic_types.h:93
Com__Seagate__Kinetic__Proto__Command__PinOperation pinOp
Invalid algorithm value.
Definition: kinetic_types.h:74
ByteBuffer tag
Generated authentication hash per the specified algorithm
Operation successful.
KineticMessageType Com__Seagate__Kinetic__Proto__Command__MessageType_to_KineticMessageType(Com__Seagate__Kinetic__Proto__Command__MessageType type)
Structure used to specify the configuration for a session.
void com__seagate__kinetic__proto__command__get_log__init(Com__Seagate__Kinetic__Proto__Command__GetLog *message)
Definition: kinetic.pb-c.c:211
Com__Seagate__Kinetic__Proto__Command__GetLog__Type KineticLogInfo_Type_to_Com__Seagate__Kinetic__Proto__Command__GetLog__Type(KineticLogInfo_Type type)
Com__Seagate__Kinetic__Proto__Command__Range keyRange
struct timeval Kinetic_TimevalZero(void)
Authorization failure.
ByteBuffer * buffers
Definition: byte_array.h:59
All pending information that has not been written is pushed to the disk and the command that specifie...
Com__Seagate__Kinetic__Proto__Command__Algorithm
Definition: kinetic.pb-c.h:274
Com__Seagate__Kinetic__Proto__Command__Synchronization
Definition: kinetic.pb-c.h:253
void com__seagate__kinetic__proto__command__init(Com__Seagate__Kinetic__Proto__Command *message)
Definition: kinetic.pb-c.c:241
int Kinetic_TimevalCmp(struct timeval const a, struct timeval const b)
void com__seagate__kinetic__proto__command__security__init(Com__Seagate__Kinetic__Proto__Command__Security *message)
Definition: kinetic.pb-c.c:229
The operation failed because the device is securely locked. An UNLOCK must be issued to unlock for us...
Com__Seagate__Kinetic__Proto__Command__GetLog__Device getLogDevice
void com__seagate__kinetic__proto__message__pinauth__init(Com__Seagate__Kinetic__Proto__Message__PINauth *message)
Definition: kinetic.pb-c.c:60
The specified object version info for a PUT/GET do not match stored object.
void com__seagate__kinetic__proto__command__pin_operation__init(Com__Seagate__Kinetic__Proto__Command__PinOperation *message)
Definition: kinetic.pb-c.c:235
Com__Seagate__Kinetic__Proto__Command__Status status
#define KINETIC_SEQUENCE_NOT_YET_BOUND
Something about the request is invalid.
KineticAlgorithm algorithm
Algorithm used to generate the specified tag
void com__seagate__kinetic__proto__command__setup__init(Com__Seagate__Kinetic__Proto__Command__Setup *message)
Definition: kinetic.pb-c.c:139
bool Copy_Com__Seagate__Kinetic__Proto__Command__Range_to_ByteBufferArray(Com__Seagate__Kinetic__Proto__Command__Range *keyRange, ByteBufferArray *keys)
int Kinetic_GetErrnoDescription(int err_num, char *buf, size_t len)
KineticAlgorithm
Enumeration of encryption/checksum key algorithms.
Definition: kinetic_types.h:73
Com__Seagate__Kinetic__Proto__Message message
void com__seagate__kinetic__proto__command__get_log__device__init(Com__Seagate__Kinetic__Proto__Command__GetLog__Device *message)
Definition: kinetic.pb-c.c:205
ByteArray ProtobufCBinaryData_to_ByteArray(ProtobufCBinaryData protoData)
Device busy (retry later)
KineticSynchronization KineticSynchronization_from_Com__Seagate__Kinetic__Proto__Command__Synchronization(Com__Seagate__Kinetic__Proto__Command__Synchronization sync_mode)
ByteArray array
ByteArray holding allocated array w/length = allocated size.
Definition: byte_array.h:54
const ProtobufCMessageDescriptor com__seagate__kinetic__proto__command__header__descriptor
Definition: kinetic.pb-c.c:651
Com__Seagate__Kinetic__Proto__Command__GetLog__Type
Definition: kinetic.pb-c.h:161
Kinetic object instance.
uint8_t keyData[(4096)]
This is the identity's HMAC Key.
KineticLogInfo_Type
Log info type.
The requested object does not exist.
void KineticSessionConfig_Copy(KineticSessionConfig *dest, KineticSessionConfig *src)
void KineticRequest_Init(KineticRequest *request, KineticSession const *const session)
Com__Seagate__Kinetic__Proto__Command__Header header
#define KINETIC_ASSERT(cond)
Com__Seagate__Kinetic__Proto__Message__PINauth pinAuth
No connection/disconnected.
KineticAlgorithm KineticAlgorithm_from_Com__Seagate__Kinetic__Proto__Command__Algorithm(Com__Seagate__Kinetic__Proto__Command__Algorithm protoAlgorithm)
void com__seagate__kinetic__proto__message__hmacauth__init(Com__Seagate__Kinetic__Proto__Message__HMACauth *message)
Definition: kinetic.pb-c.c:54
Com__Seagate__Kinetic__Proto__Command__Algorithm Com__Seagate__Kinetic__Proto__Command__Algorithm_from_KineticAlgorithm(KineticAlgorithm kinteicAlgorithm)
They can be made persistent when the drive chooses, or when a subsequent FLUSH is sent to the drive...
Definition: kinetic_types.h:97
void KineticMessage_Init(KineticMessage *const message)
Invalid synchronization value.
Definition: kinetic_types.h:89
static void KineticMessage_HeaderInit(Com__Seagate__Kinetic__Proto__Command__Header *hdr, KineticSession const *const session)
Com__Seagate__Kinetic__Proto__Command__Body body
size_t len
Number of bytes in the data field.
Definition: byte_array.h:35
void com__seagate__kinetic__proto__command__body__init(Com__Seagate__Kinetic__Proto__Command__Body *message)
Definition: kinetic.pb-c.c:115
bool Kinetic_TimevalIsZero(struct timeval const tv)
struct timeval Kinetic_TimevalAdd(struct timeval const a, struct timeval const b)
Com__Seagate__Kinetic__Proto__Command__Synchronization Com__Seagate__Kinetic__Proto__Command__Synchronization_from_KineticSynchronization(KineticSynchronization sync_mode)
Device reported an operation error.
void com__seagate__kinetic__proto__command__key_value__init(Com__Seagate__Kinetic__Proto__Command__KeyValue *message)
Definition: kinetic.pb-c.c:127
#define LOG1(message)
ByteBuffer key
Key associated with the object stored on disk.
Com__Seagate__Kinetic__Proto__Command__KeyValue keyValue
Com__Seagate__Kinetic__Proto__Command__Security security
uint8_t * data
Pointer to an allocated array of data bytes.
Definition: byte_array.h:36
Com__Seagate__Kinetic__Proto__Command__GetLog getLog
Status not available (no reponse/status available)
Com__Seagate__Kinetic__Proto__Command__Setup setup
KineticStatus
Kinetic status codes.
Device reported data error, no space or HMAC failure.
KineticMessageType
Log info message types.
Com__Seagate__Kinetic__Proto__Command command
void com__seagate__kinetic__proto__command__header__init(Com__Seagate__Kinetic__Proto__Command__Header *message)
Definition: kinetic.pb-c.c:109
size_t bytesUsed
Reflects the number of bytes used from the array
Definition: byte_array.h:55
ByteBuffer dbVersion
Current version of the entry (optional)
Com__Seagate__Kinetic__Proto__Message__HMACauth hmacAuth
Com__Seagate__Kinetic__Proto__Command__Status__StatusCode
Definition: kinetic.pb-c.h:78
bool Copy_ProtobufCBinaryData_to_ByteBuffer(ByteBuffer dest, ProtobufCBinaryData src)
static int cmp_suseconds_t(suseconds_t const a, suseconds_t const b)
void com__seagate__kinetic__proto__command__status__init(Com__Seagate__Kinetic__Proto__Command__Status *message)
Definition: kinetic.pb-c.c:121
Specified cluster version does not match device.
bool Copy_Com__Seagate__Kinetic__Proto__Command__KeyValue_to_KineticEntry(Com__Seagate__Kinetic__Proto__Command__KeyValue *key_value, KineticEntry *entry)
#define LOGF2(message,...)