kinetic-c  v0.12.0
Seagate Kinetic Protocol Client Library for C
write_file_blocking.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_client.h"
22 #include "kinetic_types.h"
23 #include "byte_array.h"
24 #include <stdlib.h>
25 #include <getopt.h>
26 #include <stdio.h>
27 #include <sys/param.h>
28 #include <sys/stat.h>
29 #include <sys/file.h>
30 
31 typedef struct {
32  char ip[16];
33  KineticSession* session;
34  char keyPrefix[KINETIC_DEFAULT_KEY_LEN];
35  uint8_t key[KINETIC_DEFAULT_KEY_LEN];
36  uint8_t version[KINETIC_DEFAULT_KEY_LEN];
37  uint8_t tag[KINETIC_DEFAULT_KEY_LEN];
38  uint8_t value[KINETIC_OBJ_SIZE];
39  KineticEntry entry;
40  ByteBuffer data;
41  KineticStatus status;
42 } write_args;
43 
44 void store_data(write_args* args)
45 {
46  KineticEntry* entry = &(args->entry);
47  int32_t objIndex = 0;
48 
49  while (ByteBuffer_BytesRemaining(args->data) > 0) {
50 
51  // Configure entry meta-data
52  ByteBuffer_Reset(&entry->key);
53  ByteBuffer_AppendCString(&entry->key, args->keyPrefix);
54  char keySuffix[8];
55  snprintf(keySuffix, sizeof(keySuffix), "%02d", objIndex);
56  ByteBuffer_AppendCString(&entry->key, keySuffix);
57 
58  // Prepare entry with the next object to store
59  ByteBuffer_Reset(&entry->value);
61  &entry->value,
63  &args->data,
65  );
66 
67  // Store the object
68  KineticStatus status = KineticClient_Put(args->session, entry, NULL);
69  if (status != KINETIC_STATUS_SUCCESS) {
70  fprintf(stderr, "Kinetic PUT of object %d to host %s failed w/ status: %s\n",
71  objIndex, args->ip, Kinetic_GetStatusDescription(status));
72  exit(-1);
73  }
74 
75  objIndex++;
76  }
77 
78  printf("File stored on Kinetic Device across %d entries\n", objIndex);
79 }
80 
81 int main(int argc, char** argv)
82 {
83  (void)argc;
84  (void)argv;
85 
86  // Initialize kinetic-c and configure sessions
87  KineticSession* session;
88  KineticClientConfig clientConfig = {
89  .logFile = "stdout",
90  .logLevel = 1,
91  };
92  KineticClient * client = KineticClient_Init(&clientConfig);
93  if (client == NULL) { return 1; }
94  const char HmacKeyString[] = "asdfasdf";
95  KineticSessionConfig sessionConfig = {
96  .host = "localhost",
97  .port = KINETIC_PORT,
98  .clusterVersion = 0,
99  .identity = 1,
100  .hmacKey = ByteArray_CreateWithCString(HmacKeyString),
101  };
102  KineticStatus status = KineticClient_CreateSession(&sessionConfig, client, &session);
103  if (status != KINETIC_STATUS_SUCCESS) {
104  fprintf(stderr, "Failed connecting to the Kinetic device w/status: %s\n",
106  exit(1);
107  }
108 
109  // Read in file contents to store
110  const char* dataFile = "test/support/data/test.data";
111  struct stat st;
112  stat(dataFile, &st);
113  char* buf = malloc(st.st_size);
114  int fd = open(dataFile, O_RDONLY);
115  long dataLen = read(fd, buf, st.st_size);
116  close(fd);
117  if (dataLen <= 0) {
118  fprintf(stderr, "Failed reading data file to store: %s\n", dataFile);
119  exit(-1);
120  }
121 
122 
123  write_args* writeArgs = calloc(1, sizeof(write_args));
124  writeArgs->session = session;
125 
126  // Create a ByteBuffer for consuming chunks of data out of for overlapped PUTs
127  writeArgs->data = ByteBuffer_Create(buf, dataLen, 0);
128 
129  // Configure common meta-data for the entries
130  struct timeval now;
131  gettimeofday(&now, NULL);
132  snprintf(writeArgs->keyPrefix, sizeof(writeArgs->keyPrefix), "%010ld_", now.tv_sec);
133  ByteBuffer verBuf = ByteBuffer_Create(writeArgs->version, sizeof(writeArgs->version), 0);
134  ByteBuffer_AppendCString(&verBuf, "v1.0");
135  ByteBuffer tagBuf = ByteBuffer_Create(writeArgs->tag, sizeof(writeArgs->tag), 0);
136  ByteBuffer_AppendCString(&tagBuf, "some_value_tag...");
137  writeArgs->entry = (KineticEntry) {
138  .key = ByteBuffer_Create(writeArgs->key, sizeof(writeArgs->key), 0),
139  // .newVersion = verBuf,
140  .tag = tagBuf,
141  .algorithm = KINETIC_ALGORITHM_SHA1,
142  .value = ByteBuffer_Create(writeArgs->value, sizeof(writeArgs->value), 0),
143  .synchronization = KINETIC_SYNCHRONIZATION_WRITEBACK,
144  };
145  strcpy(writeArgs->ip, sessionConfig.host);
146 
147  // Store the data
148  printf("\nWriting data file to the Kinetic device...\n");
149  store_data(writeArgs);
150 
151  // Shutdown client connection and cleanup
152  KineticClient_DestroySession(writeArgs->session);
153  KineticClient_Shutdown(client);
154  free(writeArgs);
155  free(buf);
156 
157  return 0;
158 }
void ByteBuffer_Reset(ByteBuffer *buffer)
Definition: byte_array.c:62
Structure for an embedded ByteArray as a buffer.
Definition: byte_array.h:53
int main(int argc, char **argv)
Operation successful.
KineticStatus KineticClient_CreateSession(KineticSessionConfig *const config, KineticClient *const client, KineticSession **session)
Creates a session with the Kinetic Device per specified configuration.
Structure used to specify the configuration for a session.
#define KINETIC_OBJ_SIZE
Max object/value size.
Definition: kinetic_types.h:47
void store_data(write_args *args)
ByteBuffer * ByteBuffer_AppendArray(ByteBuffer *buffer, const ByteArray array)
Definition: byte_array.c:149
KineticStatus KineticClient_DestroySession(KineticSession *const session)
Closes the connection to a host.
Kinetic object instance.
char host[256]
Host name/IP address of Kinetic Device.
ByteBuffer * ByteBuffer_AppendCString(ByteBuffer *buffer, const char *data)
Definition: byte_array.c:176
const char * Kinetic_GetStatusDescription(KineticStatus status)
Provides a string representation for a KineticStatus code.
Definition: kinetic_types.c:67
ByteBuffer ByteBuffer_Create(void *data, size_t max_len, size_t used)
Definition: byte_array.c:68
#define KINETIC_PORT
Default kinetic port.
Definition: kinetic_types.h:40
They can be made persistent when the drive chooses, or when a subsequent FLUSH is sent to the drive...
Definition: kinetic_types.h:97
long ByteBuffer_BytesRemaining(const ByteBuffer buffer)
Definition: byte_array.c:111
const char * logFile
Path to log file. Specify 'stdout' to log to STDOUT or NULL to disable logging.
ByteBuffer key
Key associated with the object stored on disk.
ByteArray ByteBuffer_Consume(ByteBuffer *buffer, size_t max_len)
Definition: byte_array.c:117
#define KINETIC_DEFAULT_KEY_LEN
Default key length.
Definition: kinetic_types.h:45
KineticStatus
Kinetic status codes.
KineticStatus KineticClient_Put(KineticSession *const session, KineticEntry *const entry, KineticCompletionClosure *closure)
Executes a PUT operation to store/update an entry on the Kinetic Device.
Configuration values for the KineticClient connection.
void KineticClient_Shutdown(KineticClient *const client)
Performs shutdown/cleanup of the kinetic-c client library.
KineticClient * KineticClient_Init(KineticClientConfig *config)
Initializes the Kinetic API and configures logging.
ByteArray ByteArray_CreateWithCString(const char *str)
Definition: byte_array.c:38
ByteBuffer value
Value data associated with the key.