kinetic-c  v0.12.0
Seagate Kinetic Protocol Client Library for C
kinetic_device_info.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_device_info.h"
22 #include "kinetic_logger.h"
23 #include <stdlib.h>
24 #include <string.h>
25 
26 /* Using copy_str instead of strdup since it's not necessarily available. */
27 static char *copy_str(const char *s) {
28  if (s == NULL) { return NULL; }
29 
30  int len = strlen(s);
31  char *res = calloc(len + 1, sizeof(char));
32  if (res) {
33  memcpy(res, s, len);
34  res[len] = '\0';
35  }
36 
37  return res;
38 }
39 
40 /* Copy a byte array. Returns one with res.data == NULL on alloc fail. */
41 static ByteArray copy_to_byte_array(uint8_t *data, size_t length) {
42  ByteArray res = { .len = length, };
43  res.data = calloc(res.len, sizeof(uint8_t));
44  if (res.data) {
45  memcpy(res.data, data, res.len);
46  }
47  return res;
48 }
49 
50 static void free_byte_array(ByteArray ba) {
51  free(ba.data);
52 }
53 
55  const Com__Seagate__Kinetic__Proto__Command__GetLog* getLog,
56  size_t *numUtilizations)
57 {
58  *numUtilizations = 0;
59  size_t num_util = getLog->n_utilizations;
60 
61  KineticLogInfo_Utilization * util = calloc(num_util, sizeof(*util));
62 
63  if (util) {
64  for (size_t i = 0; i < num_util; i++) {
65  util[i].name = copy_str(getLog->utilizations[i]->name);
66  if (util[i].name == NULL) {
67  for (size_t j = 0; j < i; j++) { free(util[j].name); }
68  free(util);
69  util = NULL;
70  break;
71  }
72  util[i].value = getLog->utilizations[i]->value;
73  }
74 
75  *numUtilizations = num_util;
76  }
77  return util;
78 }
79 
81  const Com__Seagate__Kinetic__Proto__Command__GetLog* getLog,
82  size_t *numTemperatures)
83 {
84  size_t num_temp = getLog->n_temperatures;
85  *numTemperatures = 0;
86  KineticLogInfo_Temperature *temp = calloc(num_temp, sizeof(*temp));
87  if (temp) {
88  for (size_t i = 0; i < num_temp; i++) {
89  temp[i].name = copy_str(getLog->temperatures[i]->name);
90  temp[i].current = getLog->temperatures[i]->current;
91  temp[i].minimum = getLog->temperatures[i]->minimum;
92  temp[i].maximum = getLog->temperatures[i]->maximum;
93  temp[i].target = getLog->temperatures[i]->target;
94  }
95 
96  *numTemperatures = num_temp;
97  }
98  return temp;
99 }
100 
102  const Com__Seagate__Kinetic__Proto__Command__GetLog* getLog)
103 {
104  KineticLogInfo_Capacity *cap = calloc(1, sizeof(*cap));
105  if (cap && getLog->capacity) {
106  cap->nominalCapacityInBytes = getLog->capacity->nominalcapacityinbytes;
107  cap->portionFull = getLog->capacity->portionfull;
108  }
109  return cap;
110 }
111 
113  const Com__Seagate__Kinetic__Proto__Command__GetLog* getLog)
114 {
115  Com__Seagate__Kinetic__Proto__Command__GetLog__Configuration const *gcfg = getLog->configuration;
116 
117  KineticLogInfo_Configuration *cfg = calloc(1, sizeof(*cfg));
118  if (cfg) {
119  if (gcfg->has_serialnumber) {
120  cfg->serialNumber = (ByteArray){0, 0};
121  }
122  if (gcfg->has_worldwidename) {
123  cfg->worldWideName = (ByteArray){0, 0};
124  }
125 
126  cfg->vendor = copy_str(gcfg->vendor);
127  if (cfg->vendor == NULL) { goto cleanup; }
128  cfg->model = copy_str(gcfg->model);
129  if (cfg->model == NULL) { goto cleanup; }
130  cfg->version = copy_str(gcfg->version);
131  if (cfg->version == NULL) { goto cleanup; }
132  cfg->compilationDate = copy_str(gcfg->compilationdate);
133  if (cfg->compilationDate == NULL) { goto cleanup; }
134  cfg->sourceHash = copy_str(gcfg->sourcehash);
135  if (cfg->sourceHash == NULL) { goto cleanup; }
136  cfg->protocolVersion = copy_str(gcfg->protocolversion);
137  if (cfg->protocolVersion == NULL) { goto cleanup; }
138  cfg->protocolCompilationDate = copy_str(gcfg->protocolcompilationdate);
139  if (cfg->protocolCompilationDate == NULL) { goto cleanup; }
140  cfg->protocolSourceHash = copy_str(gcfg->protocolsourcehash);
141  if (cfg->protocolSourceHash == NULL) { goto cleanup; }
142 
143  cfg->numInterfaces = gcfg->n_interface;
144  cfg->interfaces = calloc(cfg->numInterfaces, sizeof(*cfg->interfaces));
145  if (cfg->interfaces == NULL) { goto cleanup; }
146  for (size_t i = 0; i < cfg->numInterfaces; i++) {
147  KineticLogInfo_Interface *inf = &cfg->interfaces[i];
148  inf->name = copy_str(gcfg->interface[i]->name);
149  if (inf->name == NULL) { goto cleanup; }
150 
151  if (gcfg->interface[i]->has_mac) {
152  inf->MAC = copy_to_byte_array((uint8_t *)gcfg->interface[i]->mac.data,
153  gcfg->interface[i]->mac.len);
154  if (inf->MAC.data == NULL) { goto cleanup; }
155  }
156 
157  if (gcfg->interface[i]->has_ipv4address) {
158  inf->ipv4Address = copy_to_byte_array(gcfg->interface[i]->ipv4address.data,
159  gcfg->interface[i]->ipv4address.len);
160  if (inf->ipv4Address.data == NULL) { goto cleanup; }
161  }
162 
163  if (gcfg->interface[i]->has_ipv6address) {
164  inf->ipv6Address = copy_to_byte_array(gcfg->interface[i]->ipv6address.data,
165  gcfg->interface[i]->ipv6address.len);
166  if (inf->ipv6Address.data == NULL) { goto cleanup; }
167  }
168  }
169  }
170  return cfg;
171 cleanup:
172  if (cfg->vendor) { free(cfg->vendor); }
173  if (cfg->model) { free(cfg->model); }
174  if (cfg->version) { free(cfg->version); }
175  if (cfg->compilationDate) { free(cfg->compilationDate); }
176  if (cfg->sourceHash) { free(cfg->sourceHash); }
177  if (cfg->protocolVersion) { free(cfg->protocolVersion); }
178  if (cfg->protocolCompilationDate) { free(cfg->protocolCompilationDate); }
179  if (cfg->protocolSourceHash) { free(cfg->protocolSourceHash); }
180 
181  if (cfg->interfaces) {
182  for (size_t i = 0; i < cfg->numInterfaces; i++) {
183  if (cfg->interfaces[i].name) { free(cfg->interfaces[i].name); }
184  free_byte_array(cfg->interfaces[i].MAC);
187  }
188  free(cfg->interfaces);
189  }
190 
191  free(cfg);
192  return NULL;
193 }
194 
196  const Com__Seagate__Kinetic__Proto__Command__GetLog* getLog,
197  size_t *numStatistics)
198 {
199  size_t num_stats = getLog->n_statistics;
200  KineticLogInfo_Statistics *stats = calloc(num_stats, sizeof(*stats));
201  *numStatistics = 0;
202  if (stats) {
203  for (size_t i = 0; i < num_stats; i++) {
204  stats[i].messageType = getLog->statistics[i]->messagetype;
205  if (getLog->statistics[i]->has_count) {
206  stats[i].count = getLog->statistics[i]->count;
207  }
208  if (getLog->statistics[i]->has_bytes) {
209  stats[i].bytes = getLog->statistics[i]->bytes;
210  }
211  }
212  *numStatistics = num_stats;
213  }
214  return stats;
215 }
216 
218  const Com__Seagate__Kinetic__Proto__Command__GetLog* getLog)
219 {
220  return copy_to_byte_array(getLog->messages.data, getLog->messages.len);
221  //COPY_BYTES_OPTIONAL(messages, info, getLog, allocator);
222 }
223 
225  const Com__Seagate__Kinetic__Proto__Command__GetLog* getLog)
226 {
227  KineticLogInfo_Limits * limits = calloc(1, sizeof(*limits));
228  if (limits) {
229  limits->maxKeySize = getLog->limits->maxkeysize;
230  limits->maxValueSize = getLog->limits->maxvaluesize;
231  limits->maxVersionSize = getLog->limits->maxversionsize;
232  limits->maxTagSize = getLog->limits->maxtagsize;
233  limits->maxConnections = getLog->limits->maxconnections;
234  limits->maxOutstandingReadRequests = getLog->limits->maxoutstandingreadrequests;
235  limits->maxOutstandingWriteRequests = getLog->limits->maxoutstandingwriterequests;
236  limits->maxMessageSize = getLog->limits->maxmessagesize;
237  limits->maxKeyRangeCount = getLog->limits->maxkeyrangecount;
238  limits->maxIdentityCount = getLog->limits->maxidentitycount;
239  limits->maxPinSize = getLog->limits->maxpinsize;
240  }
241  return limits;
242 }
243 
245  const Com__Seagate__Kinetic__Proto__Command__GetLog* getLog)
246 {
247  KineticLogInfo_Device *device = calloc(1, sizeof(*device));
248  if (device && getLog->device) {
249  if (getLog->device->has_name) {
250  device->name = copy_to_byte_array(getLog->device->name.data,
251  getLog->device->name.len);
252  }
253  }
254  return device;
255 }
256 
257 KineticLogInfo* KineticLogInfo_Create(const Com__Seagate__Kinetic__Proto__Command__GetLog* getLog)
258 {
259  KINETIC_ASSERT(getLog != NULL);
260 
261  // Copy data into the nested allocated structure tree
262  KineticLogInfo* info = calloc(1, sizeof(*info));
263  if (info == NULL) { return NULL; }
264  memset(info, 0, sizeof(*info));
265 
266  KineticLogInfo_Utilization* utilizations = NULL;
267  KineticLogInfo_Temperature* temperatures = NULL;
268  KineticLogInfo_Capacity* capacity = NULL;
269  KineticLogInfo_Configuration* configuration = NULL;
270  KineticLogInfo_Statistics* statistics = NULL;
271  KineticLogInfo_Limits* limits = NULL;
272  KineticLogInfo_Device* device = NULL;
273 
274  utilizations = KineticLogInfo_GetUtilizations(getLog, &info->numUtilizations);
275  if (utilizations == NULL) { goto cleanup; }
276  capacity = KineticLogInfo_GetCapacity(getLog);
277  if (capacity == NULL) { goto cleanup; }
278  temperatures = KineticLogInfo_GetTemperatures(getLog, &info->numTemperatures);
279  if (temperatures == NULL) { goto cleanup; }
280 
281  if (getLog->configuration != NULL) {
282  configuration = KineticLogInfo_GetConfiguration(getLog);
283  if (configuration == NULL) { goto cleanup; }
284  }
285 
286  statistics = KineticLogInfo_GetStatistics(getLog, &info->numStatistics);
287  if (statistics == NULL) { goto cleanup; }
288  ByteArray messages = KineticLogInfo_GetMessages(getLog);
289  if (messages.data == NULL) { goto cleanup; }
290 
291  if (getLog->limits != NULL) {
292  limits = KineticLogInfo_GetLimits(getLog);
293  if (limits == NULL) { goto cleanup; }
294  }
295 
296  device = KineticLogInfo_GetDevice(getLog);
297  if (device == NULL) { goto cleanup; }
298 
299  info->utilizations = utilizations;
300  info->temperatures = temperatures;
301  info->capacity = capacity;
302  info->configuration = configuration;
303  info->statistics = statistics;
304  info->limits = limits;
305  info->device = device;
306  info->messages = messages;
307 
308  LOGF2("Created KineticLogInfo @ 0x%0llX", info);
309  return info;
310 
311 cleanup:
312  if (info) { free(info); }
313  if (utilizations) { free(utilizations); }
314  if (temperatures) { free(temperatures); }
315  if (capacity) { free(capacity); }
316  if (configuration) { free(configuration); }
317  if (statistics) { free(statistics); }
318  if (limits) { free(limits); }
319  if (device) { free(device); }
320  return NULL;
321 }
322 
324  if (kdi) {
325  if (kdi->utilizations) {
326  for (size_t i = 0; i < kdi->numUtilizations; i++) {
327  free(kdi->utilizations[i].name);
328  }
329  free(kdi->utilizations);
330  }
331 
332  if (kdi->temperatures) {
333  for (size_t i = 0; i < kdi->numTemperatures; i++) {
334  free(kdi->temperatures[i].name);
335  }
336  free(kdi->temperatures);
337  }
338 
339  if (kdi->capacity) { free(kdi->capacity); }
340 
341  if (kdi->configuration) {
343 
344  if (cfg->vendor) { free(cfg->vendor); }
345  if (cfg->model) { free(cfg->model); }
346  if (cfg->version) { free(cfg->version); }
347  if (cfg->compilationDate) { free(cfg->compilationDate); }
348  if (cfg->sourceHash) { free(cfg->sourceHash); }
349  if (cfg->protocolVersion) { free(cfg->protocolVersion); }
350  if (cfg->protocolCompilationDate) { free(cfg->protocolCompilationDate); }
351  if (cfg->protocolSourceHash) { free(cfg->protocolSourceHash); }
352 
353  if (cfg->serialNumber.data) { free(cfg->serialNumber.data); }
354  if (cfg->worldWideName.data) { free(cfg->worldWideName.data); }
355 
356  if (cfg->interfaces) {
357  for (size_t i = 0; i < cfg->numInterfaces; i++) {
358  KineticLogInfo_Interface *inf = &cfg->interfaces[i];
359  if (inf->name) { free(inf->name); }
360  if (inf->MAC.data) { free(inf->MAC.data); }
361  if (inf->ipv4Address.data) { free(inf->ipv4Address.data); }
362  if (inf->ipv6Address.data) { free(inf->ipv6Address.data); }
363  }
364  free(cfg->interfaces);
365  }
366  free(cfg);
367  }
368 
369  if (kdi->statistics) { free(kdi->statistics); }
370  if (kdi->limits) { free(kdi->limits); }
371 
372  if (kdi->device) {
373  if (kdi->device->name.data) { free(kdi->device->name.data); }
374  free(kdi->device);
375  }
376 
377  if (kdi->messages.data) { free(kdi->messages.data); }
378 
379  free(kdi);
380  }
381 }
Log info device limits.
static KineticLogInfo_Device * KineticLogInfo_GetDevice(const Com__Seagate__Kinetic__Proto__Command__GetLog *getLog)
Structure for handling generic arrays of bytes.
Definition: byte_array.h:34
size_t numStatistics
Log info device name (used as a key for device-specific log data)
static char * copy_str(const char *s)
size_t numTemperatures
KineticMessageType messageType
uint32_t maxOutstandingWriteRequests
KineticLogInfo_Capacity * capacity
Log info network interface entry.
static KineticLogInfo_Capacity * KineticLogInfo_GetCapacity(const Com__Seagate__Kinetic__Proto__Command__GetLog *getLog)
KineticLogInfo_Configuration * configuration
Log info device configuration.
static ByteArray KineticLogInfo_GetMessages(const Com__Seagate__Kinetic__Proto__Command__GetLog *getLog)
uint32_t maxOutstandingReadRequests
KineticLogInfo_Limits * limits
ByteArray messages
static void free_byte_array(ByteArray ba)
Base log info structure which is allocated by client and passed to KineticAdminClient_GetLog.
static KineticLogInfo_Temperature * KineticLogInfo_GetTemperatures(const Com__Seagate__Kinetic__Proto__Command__GetLog *getLog, size_t *numTemperatures)
#define KINETIC_ASSERT(cond)
KineticLogInfo_Interface * interfaces
KineticLogInfo_Device * device
static KineticLogInfo_Configuration * KineticLogInfo_GetConfiguration(const Com__Seagate__Kinetic__Proto__Command__GetLog *getLog)
Log info statistics entry.
size_t len
Number of bytes in the data field.
Definition: byte_array.h:35
static ByteArray copy_to_byte_array(uint8_t *data, size_t length)
KineticLogInfo_Utilization * utilizations
Log info untilization entry.
KineticLogInfo_Statistics * statistics
KineticLogInfo_Temperature * temperatures
size_t numUtilizations
void KineticLogInfo_Free(KineticLogInfo *kdi)
uint8_t * data
Pointer to an allocated array of data bytes.
Definition: byte_array.h:36
static KineticLogInfo_Statistics * KineticLogInfo_GetStatistics(const Com__Seagate__Kinetic__Proto__Command__GetLog *getLog, size_t *numStatistics)
static KineticLogInfo_Limits * KineticLogInfo_GetLimits(const Com__Seagate__Kinetic__Proto__Command__GetLog *getLog)
KineticLogInfo * KineticLogInfo_Create(const Com__Seagate__Kinetic__Proto__Command__GetLog *getLog)
Log info capacity entry.
static KineticLogInfo_Utilization * KineticLogInfo_GetUtilizations(const Com__Seagate__Kinetic__Proto__Command__GetLog *getLog, size_t *numUtilizations)
Log info temperature entry.
#define LOGF2(message,...)