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