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 CodeLine #
 
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