GCOV Execution Analysis for uid_utils.c
The left column is the number of times the code was executed
during the unit test suites.
Exec | Code | Line # | |
---|---|---|---|
Source:uid_utils.c | 1 | ||
Graph:.libs/uid_utils.gcno | 2 | ||
Data:.libs/uid_utils.gcda | 3 | ||
Runs:378 | 4 | ||
Programs:378 | 5 | ||
/* -*- linux-c -*- | 6 | ||
* | 7 | ||
* (C) Copyright IBM Corp. 2003, 2004 | 8 | ||
* Copyright (c) 2003 by Intel Corp. | 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. This | 13 | ||
* file and program are licensed under a BSD style license. See | 14 | ||
* the Copying file included with the OpenHPI distribution for | 15 | ||
* full licensing terms. | 16 | ||
* | 17 | ||
* Author(s): | 18 | ||
* David Judkovics < address removed > | 19 | ||
* Renier Morales < address removed > | 20 | ||
*/ | 21 | ||
22 | |||
#include <stdio.h> | 23 | ||
#include <stdlib.h> | 24 | ||
#include <glib.h> | 25 | ||
#include <fcntl.h> | 26 | ||
#include <string.h> | 27 | ||
#include <unistd.h> | 28 | ||
29 | |||
#include <SaHpi.h> | 30 | ||
#include <config.h> | 31 | ||
#include <oh_utils.h> | 32 | ||
33 | |||
static GStaticMutex oh_uid_lock = G_STATIC_MUTEX_INIT; | 34 | ||
static GHashTable *oh_ep_table; | 35 | ||
static GHashTable *oh_resource_id_table; | 36 | ||
static guint resource_id; | 37 | ||
38 | |||
39 | |||
/* use to build memory resident map table from file */ | 40 | ||
static int uid_map_from_file(void); | 41 | ||
static int build_uid_map_data(int file); | 42 | ||
43 | |||
/* used by oh_uid_remove() */ | 44 | ||
static void write_ep_xref(gpointer key, gpointer value, gpointer file); | 45 | ||
46 | |||
/* for hash table usage */ | 47 | ||
guint oh_entity_path_hash(gconstpointer key); | 48 | ||
gboolean oh_entity_path_equal(gconstpointer a, gconstpointer b); | 49 | ||
50 | |||
/* | 51 | ||
* oh_entity_path_hash: used by g_hash_table_new() | 52 | ||
* in oh_uid_initialize(). See glib library for | 53 | ||
* further details. | 54 | ||
*/ | 55 | ||
guint oh_entity_path_hash(gconstpointer key) | 56 | ||
8976 | { | 57 | |
8976 | const char *p = key; | 58 | |
8976 | guint h = *p; | 59 | |
60 | |||
8976 | int i; | 61 | |
62 | |||
8976 | int entity_path_len; | 63 | |
64 | |||
8976 | entity_path_len = sizeof(SaHpiEntityPathT); | 65 | |
66 | |||
8976 | p += 1; | 67 | |
68 | |||
1148928 | for( i=0; i<entity_path_len - 1; i++ ){ | 69 | |
/* h = (h << 5) - h + *p; */ | 70 | ||
1139952 | h = (h * 131) + *p; | 71 | |
1139952 | p++; | 72 | |
} | 73 | ||
74 | |||
/* don't change the 1009, its magic */ | 75 | ||
8976 | return( h % 1009 ); | 76 | |
77 | |||
} | 78 | ||
79 | |||
/* | 80 | ||
* oh_entity_path_equal: used by g_hash_table_new() | 81 | ||
* in oh_uid_initialize(). See glib library for | 82 | ||
* further details. | 83 | ||
*/ | 84 | ||
gboolean oh_entity_path_equal(gconstpointer a, gconstpointer b) | 85 | ||
10098 | { | 86 | |
10098 | if (!ep_cmp(a,b)) { | 87 | |
4114 | return 1; | 88 | |
} | 89 | ||
else { | 90 | ||
5984 | return 0; | 91 | |
} | 92 | ||
} | 93 | ||
94 | |||
/** | 95 | ||
* oh_uid_initialize | 96 | ||
* | 97 | ||
* UID utils initialization routine | 98 | ||
* This functions must be called before any other uid_utils | 99 | ||
* are made. | 100 | ||
* | 101 | ||
* Returns: success 0, failure -1. | 102 | ||
**/ | 103 | ||
SaErrorT oh_uid_initialize(void) | 104 | ||
374 | { | 105 | |
374 | static int initialized = FALSE; | 106 | |
107 | |||
374 | int rval; | 108 | |
109 | |||
374 | g_static_mutex_lock(&oh_uid_lock); | 110 | |
374 | if(!initialized) { | 111 | |
112 | |||
/* initialize hash tables */ | 113 | ||
374 | oh_ep_table = g_hash_table_new(oh_entity_path_hash, oh_entity_path_equal); | 114 | |
374 | oh_resource_id_table = g_hash_table_new(g_int_hash, g_int_equal); | 115 | |
116 | |||
374 | initialized = TRUE; | 117 | |
118 | |||
374 | resource_id = 1; | 119 | |
120 | |||
/* initialize uid map */ | 121 | ||
374 | rval = uid_map_from_file(); | 122 | |
123 | |||
0 | } else { rval = SA_ERR_HPI_ERROR; } | 124 | |
125 | |||
374 | g_static_mutex_unlock(&oh_uid_lock); | 126 | |
127 | |||
374 | return(rval); | 128 | |
129 | |||
} | 130 | ||
131 | |||
/** | 132 | ||
* oh_uid_from_entity_path | 133 | ||
* @ep: value to be removed from used | 134 | ||
* | 135 | ||
* This function returns an unique value to be used as | 136 | ||
* an uid/resourceID base upon a unique entity path specified | 137 | ||
* by @ep. If the entity path already exists, the already assigned | 138 | ||
* resource id is returned. Before returning, this call updates the | 139 | ||
* uid map file saved on disk. | 140 | ||
* | 141 | ||
* Returns: positive unsigned int, failure is 0. | 142 | ||
**/ | 143 | ||
guint oh_uid_from_entity_path(SaHpiEntityPathT *ep) | 144 | ||
1122 | { | 145 | |
1122 | gpointer key; | 146 | |
1122 | gpointer value; | 147 | |
1122 | SaHpiResourceIdT ruid; | 148 | |
149 | |||
1122 | EP_XREF *ep_xref; | 150 | |
151 | |||
1122 | char *uid_map_file; | 152 | |
1122 | int file; | 153 | |
154 | |||
1122 | SaHpiEntityPathT entitypath; | 155 | |
156 | |||
1122 | if (!ep) return 0; | 157 | |
158 | |||
1122 | ep_init(&entitypath); | 159 | |
1122 | ep_concat(&entitypath,ep); | 160 | |
1122 | key = &entitypath; | 161 | |
162 | |||
1122 | g_static_mutex_lock(&oh_uid_lock); | 163 | |
/* check for presence of EP and */ | 164 | ||
/* previously assigned uid */ | 165 | ||
1122 | ep_xref = (EP_XREF *)g_hash_table_lookup (oh_ep_table, key); | 166 | |
1122 | if (ep_xref) { | 167 | |
/*dbg("Entity Path already assigned uid. Use oh_uid_lookup().");*/ | 168 | ||
1122 | g_static_mutex_unlock(&oh_uid_lock); | 169 | |
1122 | return ep_xref->resource_id; | 170 | |
} | 171 | ||
172 | |||
/* allocate storage for EP cross reference data structure*/ | 173 | ||
0 | ep_xref = (EP_XREF *)g_malloc0(sizeof(EP_XREF)); | 174 | |
0 | if(!ep_xref) { | 175 | |
0 | dbg("malloc failed"); | 176 | |
0 | g_static_mutex_unlock(&oh_uid_lock); | 177 | |
0 | return 0; | 178 | |
} | 179 | ||
180 | |||
0 | memset(ep_xref, 0, sizeof(EP_XREF)); | 181 | |
0 | memcpy(&ep_xref->entity_path, &entitypath, sizeof(SaHpiEntityPathT)); | 182 | |
183 | |||
0 | ep_xref->resource_id = resource_id; | 184 | |
0 | resource_id++; | 185 | |
0 | ruid = ep_xref->resource_id; | 186 | |
187 | |||
0 | value = (gpointer)ep_xref; | 188 | |
189 | |||
/* entity path based key */ | 190 | ||
0 | key = (gpointer)&ep_xref->entity_path; | 191 | |
0 | g_hash_table_insert(oh_ep_table, key, value); | 192 | |
193 | |||
/* resource id based key */ | 194 | ||
0 | key = (gpointer)&ep_xref->resource_id; | 195 | |
0 | g_hash_table_insert(oh_resource_id_table, key, value); | 196 | |
197 | |||
/* save newly created ep xref (iud/resource_id) to map file */ | 198 | ||
0 | uid_map_file = (char *)getenv("OPENHPI_UID_MAP"); | 199 | |
0 | if (uid_map_file == NULL) { | 200 | |
0 | uid_map_file = OH_DEFAULT_UID_MAP; | 201 | |
} | 202 | ||
203 | |||
0 | file = open(uid_map_file, O_WRONLY); | 204 | |
0 | if (file >= 0) { | 205 | |
0 | lseek(file, 0, SEEK_END); | 206 | |
0 | write(file,ep_xref, sizeof(EP_XREF)); | 207 | |
0 | lseek(file, 0, SEEK_SET); | 208 | |
0 | write(file, &resource_id, sizeof(resource_id)); | 209 | |
} | 210 | ||
0 | close(file); | 211 | |
212 | |||
0 | g_static_mutex_unlock(&oh_uid_lock); | 213 | |
214 | |||
0 | return ruid; | 215 | |
} | 216 | ||
217 | |||
/** | 218 | ||
* oh_uid_remove | 219 | ||
* @uid: value to be removed | 220 | ||
* | 221 | ||
* This functions removes the uid/entity path | 222 | ||
* pair from use and removes the use of the uid forever. | 223 | ||
* A new uid may be requested for this entity path | 224 | ||
* in the future. oh_uid_from_entity_path() writes | 225 | ||
* the entire uid/entity path pairings to file before | 226 | ||
* returning. oh_uid_remove() deletes the pairing from file. | 227 | ||
* | 228 | ||
* Returns: success 0, failure -1. | 229 | ||
**/ | 230 | ||
gint oh_uid_remove(guint uid) | 231 | ||
0 | { | 232 | |
0 | EP_XREF *ep_xref; | 233 | |
0 | gpointer key; | 234 | |
0 | int rval; | 235 | |
236 | |||
/* check netry exist in oh_resource_id_table */ | 237 | ||
0 | key = (gpointer)&uid; | 238 | |
0 | g_static_mutex_lock(&oh_uid_lock); | 239 | |
0 | ep_xref = (EP_XREF *)g_hash_table_lookup (oh_resource_id_table, key); | 240 | |
0 | if(!ep_xref) { | 241 | |
0 | dbg("error freeing oh_resource_id_table"); | 242 | |
0 | g_static_mutex_unlock(&oh_uid_lock); | 243 | |
0 | return -1; | 244 | |
} | 245 | ||
246 | |||
/* check netry exist in oh_resource_id_table */ | 247 | ||
0 | key = (gpointer)&ep_xref->entity_path; | 248 | |
0 | ep_xref = (EP_XREF *)g_hash_table_lookup (oh_ep_table, key); | 249 | |
0 | if(!ep_xref) { | 250 | |
0 | dbg("error freeing oh_resource_id_table"); | 251 | |
0 | g_static_mutex_unlock(&oh_uid_lock); | 252 | |
0 | return -1; | 253 | |
} | 254 | ||
255 | |||
0 | g_hash_table_remove(oh_resource_id_table, &ep_xref->resource_id); | 256 | |
0 | g_hash_table_remove(oh_ep_table, &ep_xref->entity_path); | 257 | |
258 | |||
0 | free(ep_xref); | 259 | |
260 | |||
0 | g_static_mutex_unlock(&oh_uid_lock); | 261 | |
262 | |||
0 | rval = oh_uid_map_to_file(); | 263 | |
264 | |||
0 | return rval; | 265 | |
} | 266 | ||
267 | |||
/** | 268 | ||
* oh_uid_lookup | 269 | ||
* @ep: pointer to entity path used to identify resourceID/uid | 270 | ||
* | 271 | ||
* Fetches resourceID/uid based on entity path in @ep. | 272 | ||
* | 273 | ||
* Returns: success returns resourceID/uid, failure is 0. | 274 | ||
**/ | 275 | ||
guint oh_uid_lookup(SaHpiEntityPathT *ep) | 276 | ||
2992 | { | 277 | |
2992 | EP_XREF *ep_xref; | 278 | |
2992 | SaHpiEntityPathT entitypath; | 279 | |
2992 | SaHpiResourceIdT ruid; | 280 | |
2992 | gpointer key; | 281 | |
282 | |||
2992 | if (!ep) return 0; | 283 | |
284 | |||
2992 | ep_init(&entitypath); | 285 | |
2992 | ep_concat(&entitypath, ep); | 286 | |
2992 | key = &entitypath; | 287 | |
288 | |||
/* check hash table for entry in oh_ep_table */ | 289 | ||
2992 | g_static_mutex_lock(&oh_uid_lock); | 290 | |
2992 | ep_xref = (EP_XREF *)g_hash_table_lookup (oh_ep_table, key); | 291 | |
2992 | if(!ep_xref) { | 292 | |
0 | dbg("error looking up EP to get uid"); | 293 | |
0 | g_static_mutex_unlock(&oh_uid_lock); | 294 | |
0 | return 0; | 295 | |
} | 296 | ||
297 | |||
2992 | ruid = ep_xref->resource_id; | 298 | |
2992 | g_static_mutex_unlock(&oh_uid_lock); | 299 | |
300 | |||
2992 | return ruid; | 301 | |
} | 302 | ||
303 | |||
/** | 304 | ||
* oh_entity_path_lookup | 305 | ||
* @id: pointer to resource_id/uid identifying entity path | 306 | ||
* @ep: pointer to memory to fill in with entity path | 307 | ||
* | 308 | ||
* Fetches entity path based upon resource id, @id. | 309 | ||
* | 310 | ||
* Returns: success 0, failed -1. | 311 | ||
**/ | 312 | ||
gint oh_entity_path_lookup(guint *id, SaHpiEntityPathT *ep) | 313 | ||
0 | { | 314 | |
0 | EP_XREF *ep_xref; | 315 | |
0 | gpointer key = id; | 316 | |
317 | |||
0 | if (!id || !ep) return -1; | 318 | |
319 | |||
/* check hash table for entry in oh_ep_table */ | 320 | ||
0 | g_static_mutex_lock(&oh_uid_lock); | 321 | |
0 | ep_xref = (EP_XREF *)g_hash_table_lookup (oh_resource_id_table, key); | 322 | |
0 | if(!ep_xref) { | 323 | |
0 | dbg("error looking up EP to get uid"); | 324 | |
0 | g_static_mutex_unlock(&oh_uid_lock); | 325 | |
0 | return -1 ; | 326 | |
} | 327 | ||
328 | |||
0 | memcpy(ep, &ep_xref->entity_path, sizeof(SaHpiEntityPathT)); | 329 | |
330 | |||
0 | g_static_mutex_unlock(&oh_uid_lock); | 331 | |
332 | |||
0 | return 0; | 333 | |
} | 334 | ||
335 | |||
/** | 336 | ||
* oh_uid_map_to_file: saves current uid and entity path mappings | 337 | ||
* to file, first element in file is 4 bytes for resource id, | 338 | ||
* then repeat EP_XREF structures holding uid and entity path pairings | 339 | ||
* | 340 | ||
* Return value: success 0, failed -1. | 341 | ||
**/ | 342 | ||
gint oh_uid_map_to_file(void) | 343 | ||
0 | { | 344 | |
0 | char *uid_map_file; | 345 | |
0 | int file; | 346 | |
347 | |||
0 | uid_map_file = (char *)getenv("OPENHPI_UID_MAP"); | 348 | |
349 | |||
0 | if (uid_map_file == NULL) { | 350 | |
0 | uid_map_file = OH_DEFAULT_UID_MAP; | 351 | |
} | 352 | ||
353 | |||
0 | g_static_mutex_lock(&oh_uid_lock); | 354 | |
355 | |||
0 | file = open(uid_map_file, O_WRONLY|O_CREAT|O_TRUNC); | 356 | |
0 | if(file < 0) { | 357 | |
0 | dbg("Configuration file '%s' could not be opened", uid_map_file); | 358 | |
0 | g_static_mutex_unlock(&oh_uid_lock); | 359 | |
0 | return -1; | 360 | |
} | 361 | ||
362 | |||
/* write resource id */ | 363 | ||
0 | write(file, (void *)&resource_id, sizeof(resource_id)); | 364 | |
365 | |||
/* write all EP_XREF data records */ | 366 | ||
0 | g_hash_table_foreach(oh_resource_id_table, write_ep_xref, &file); | 367 | |
368 | |||
0 | if(close(file) != 0) { | 369 | |
0 | dbg("Couldn't close file '%s'.", uid_map_file); | 370 | |
0 | g_static_mutex_unlock(&oh_uid_lock); | 371 | |
0 | return -1; | 372 | |
} | 373 | ||
374 | |||
0 | g_static_mutex_unlock(&oh_uid_lock); | 375 | |
376 | |||
0 | return 0; | 377 | |
} | 378 | ||
379 | |||
380 | |||
/* | 381 | ||
* write_ep_xref: called by g_hash_table_foreach(), for each | 382 | ||
* hash table entry see glib manual for further details | 383 | ||
* | 384 | ||
* Return value: None (void). | 385 | ||
*/ | 386 | ||
static void write_ep_xref(gpointer key, gpointer value, gpointer file) | 387 | ||
0 | { | 388 | |
0 | write(*(int *)file, value, sizeof(EP_XREF)); | 389 | |
} | 390 | ||
391 | |||
392 | |||
/* | 393 | ||
* uid_map_from_file: called from oh_uid_initialize() during intialization | 394 | ||
* This function, if a uid map file exists, reads the current value for | 395 | ||
* uid and intializes the memory resident uid map file from file. | 396 | ||
* | 397 | ||
* Return value: success 0, error -1. | 398 | ||
*/ | 399 | ||
static gint uid_map_from_file() | 400 | ||
374 | { | 401 | |
374 | char *uid_map_file; | 402 | |
374 | int file; | 403 | |
374 | int rval; | 404 | |
405 | |||
/* initialize uid map file */ | 406 | ||
374 | uid_map_file = (char *)getenv("OPENHPI_UID_MAP"); | 407 | |
374 | if (uid_map_file == NULL) { | 408 | |
0 | uid_map_file = OH_DEFAULT_UID_MAP; | 409 | |
} | 410 | ||
374 | file = open(uid_map_file, O_RDONLY); | 411 | |
374 | if(file < 0) { | 412 | |
/* create map file with resource id initial value */ | 413 | ||
0 | dbg("Configuration file '%s' does not exist, initializing", uid_map_file); | 414 | |
0 | file = open(uid_map_file, | 415 | |
O_RDWR | O_CREAT | O_TRUNC, | 416 | ||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); | 417 | ||
0 | if(file < 0) { | 418 | |
0 | dbg("Could not initialize uid map file, %s", uid_map_file ); | 419 | |
0 | return -1; | 420 | |
} | 421 | ||
/* write initial uid value */ | 422 | ||
0 | if( write(file,(void *)&resource_id, sizeof(resource_id)) < 0 ) { | 423 | |
0 | dbg("failed to write uid, on uid map file initialization"); | 424 | |
0 | close(file); | 425 | |
0 | return -1; | 426 | |
} | 427 | ||
0 | if(close(file) != 0) { | 428 | |
0 | dbg("Couldn't close file '%s'.during uid map file initialization", uid_map_file); | 429 | |
0 | return -1; | 430 | |
} | 431 | ||
/* return from successful initialization, from newly created uid map file */ | 432 | ||
0 | return 0; | 433 | |
} | 434 | ||
435 | |||
/* read uid/resouce_id highest count from uid map file */ | 436 | ||
374 | if (read(file,&resource_id, sizeof(resource_id)) != sizeof(resource_id)) { | 437 | |
0 | dbg("error setting uid from existing uid map file"); | 438 | |
0 | return -1; | 439 | |
} | 440 | ||
441 | |||
374 | rval = build_uid_map_data(file); | 442 | |
374 | close(file); | 443 | |
444 | |||
374 | if (rval < 0) | 445 | |
0 | return -1; | 446 | |
447 | |||
/* return from successful initialization from existing uid map file */ | 448 | ||
374 | return 0; | 449 | |
} | 450 | ||
451 | |||
/* | 452 | ||
* build_uid_map_data: used by uid_map_from_file(), recursively | 453 | ||
* reads map file and builds two hash tables and EP_XREF data | 454 | ||
* structures | 455 | ||
* | 456 | ||
* @file: key into a GHashTable | 457 | ||
* | 458 | ||
* Return value: success 0, error -1. | 459 | ||
*/ | 460 | ||
static gint build_uid_map_data(int file) | 461 | ||
374 | { | 462 | |
374 | int rval; | 463 | |
374 | EP_XREF *ep_xref; | 464 | |
374 | EP_XREF ep_xref1; | 465 | |
374 | gpointer value; | 466 | |
374 | gpointer key; | 467 | |
468 | |||
374 | rval = read(file, &ep_xref1, sizeof(EP_XREF)); | 469 | |
470 | |||
5236 | while ( (rval != EOF) && (rval == sizeof(EP_XREF)) ) { | 471 | |
472 | |||
/* copy read record from ep_xref1 to malloc'd ep_xref */ | 473 | ||
4862 | ep_xref = (EP_XREF *)g_malloc0(sizeof(EP_XREF)); | 474 | |
4862 | if (!ep_xref) | 475 | |
0 | return -1; | 476 | |
4862 | memcpy(ep_xref, &ep_xref1, sizeof(EP_XREF)); | 477 | |
478 | |||
4862 | value = (gpointer)ep_xref; | 479 | |
480 | |||
/* entity path based key */ | 481 | ||
4862 | key = (gpointer)&ep_xref->entity_path; | 482 | |
4862 | g_hash_table_insert(oh_ep_table, key, value); | 483 | |
484 | |||
/* resource id based key */ | 485 | ||
4862 | key = (gpointer)&ep_xref->resource_id; | 486 | |
4862 | g_hash_table_insert(oh_resource_id_table, key, value); | 487 | |
488 | |||
4862 | rval = read(file, &ep_xref1, sizeof(EP_XREF)); | 489 | |
} | 490 | ||
491 | |||
/* TODO thought EOF would return -1, its not so check other way */ | 492 | ||
/* if (rval != EOF), rval of 0 seems to be EOF */ | 493 | ||
374 | if ( (rval > 0) && (rval < sizeof(EP_XREF)) ) { | 494 | |
0 | dbg("error building ep xref from map file"); | 495 | |
0 | return -1; | 496 | |
} | 497 | ||
374 | return 0; | 498 | |
} | 499 |