2 * Copyright (c) 2006 MontaVista Software, Inc.
3 * Copyright (c) 2008 Red Hat, Inc.
7 * Author: Steven Dake (sdake@mvista.com)
9 * This software licensed under BSD license, the text of which follows:
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
14 * - Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * - Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * - Neither the name of the MontaVista Software, Inc. nor the names of its
20 * contributors may be used to endorse or promote products derived from this
21 * software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33 * THE POSSIBILITY OF SUCH DAMAGE.
39 #include "../lcr/lcr_comp.h"
40 #include "../include/hdb.h"
41 #include "../include/list.h"
48 struct list_head list
;
51 struct object_instance
{
54 unsigned int object_handle
;
55 unsigned int parent_handle
;
56 struct list_head key_head
;
57 struct list_head child_head
;
58 struct list_head child_list
;
59 struct list_head
*find_child_list
;
60 struct list_head
*iter_key_list
;
61 struct list_head
*iter_list
;
63 struct object_valid
*object_valid_list
;
64 int object_valid_list_entries
;
65 struct object_key_valid
*object_key_valid_list
;
66 int object_key_valid_list_entries
;
69 static struct hdb_handle_database object_instance_database
= {
73 .mutex
= PTHREAD_MUTEX_INITIALIZER
76 static int objdb_init (void)
79 struct object_instance
*instance
;
82 res
= hdb_handle_create (&object_instance_database
,
83 sizeof (struct object_instance
), &handle
);
87 res
= hdb_handle_get (&object_instance_database
,
88 handle
, (void *)&instance
);
92 instance
->find_child_list
= &instance
->child_head
;
93 instance
->object_name
= "parent";
94 instance
->object_name_len
= strlen ("parent");
95 instance
->object_handle
= handle
;
96 instance
->priv
= NULL
;
97 instance
->object_valid_list
= NULL
;
98 instance
->object_valid_list_entries
= 0;
99 list_init (&instance
->key_head
);
100 list_init (&instance
->child_head
);
101 list_init (&instance
->child_list
);
103 hdb_handle_put (&object_instance_database
, handle
);
107 hdb_handle_destroy (&object_instance_database
, handle
);
114 * object db create/destroy/set
116 static int object_create (
117 unsigned int parent_object_handle
,
118 unsigned int *object_handle
,
120 unsigned int object_name_len
)
122 struct object_instance
*object_instance
;
123 struct object_instance
*parent_instance
;
128 res
= hdb_handle_get (&object_instance_database
,
129 parent_object_handle
, (void *)&parent_instance
);
135 * Do validation check if validation is configured for the parent object
137 if (parent_instance
->object_valid_list_entries
) {
138 for (i
= 0; i
< parent_instance
->object_valid_list_entries
; i
++) {
139 if ((object_name_len
==
140 parent_instance
->object_valid_list
[i
].object_len
) &&
141 (memcmp (object_name
,
142 parent_instance
->object_valid_list
[i
].object_name
,
143 object_name_len
) == 0)) {
151 * Item not found in validation list
154 goto error_object_put
;
159 res
= hdb_handle_create (&object_instance_database
,
160 sizeof (struct object_instance
), object_handle
);
162 goto error_object_put
;
165 res
= hdb_handle_get (&object_instance_database
,
166 *object_handle
, (void *)&object_instance
);
170 list_init (&object_instance
->key_head
);
171 list_init (&object_instance
->child_head
);
172 list_init (&object_instance
->child_list
);
173 object_instance
->object_name
= malloc (object_name_len
);
174 if (object_instance
->object_name
== 0) {
175 goto error_put_destroy
;
177 memcpy (object_instance
->object_name
, object_name
, object_name_len
);
179 object_instance
->object_name_len
= object_name_len
;
181 list_add (&object_instance
->child_list
, &parent_instance
->child_head
);
183 object_instance
->object_handle
= *object_handle
;
184 object_instance
->find_child_list
= &object_instance
->child_head
;
185 object_instance
->iter_key_list
= &object_instance
->key_head
;
186 object_instance
->iter_list
= &object_instance
->child_head
;
187 object_instance
->priv
= NULL
;
188 object_instance
->object_valid_list
= NULL
;
189 object_instance
->object_valid_list_entries
= 0;
190 object_instance
->parent_handle
= parent_object_handle
;
192 hdb_handle_put (&object_instance_database
, *object_handle
);
194 hdb_handle_put (&object_instance_database
, parent_object_handle
);
199 hdb_handle_put (&object_instance_database
, *object_handle
);
202 hdb_handle_destroy (&object_instance_database
, *object_handle
);
205 hdb_handle_put (&object_instance_database
, parent_object_handle
);
211 static int object_priv_set (
212 unsigned int object_handle
,
216 struct object_instance
*object_instance
;
218 res
= hdb_handle_get (&object_instance_database
,
219 object_handle
, (void *)&object_instance
);
224 object_instance
->priv
= priv
;
226 hdb_handle_put (&object_instance_database
, object_handle
);
233 static int object_key_create (
234 unsigned int object_handle
,
240 struct object_instance
*instance
;
241 struct object_key
*object_key
;
247 res
= hdb_handle_get (&object_instance_database
,
248 object_handle
, (void *)&instance
);
254 * Do validation check if validation is configured for the parent object
256 if (instance
->object_key_valid_list_entries
) {
257 for (i
= 0; i
< instance
->object_key_valid_list_entries
; i
++) {
259 instance
->object_key_valid_list
[i
].key_len
) &&
261 instance
->object_key_valid_list
[i
].key_name
,
270 * Item not found in validation list
275 if (instance
->object_key_valid_list
[i
].validate_callback
) {
276 res
= instance
->object_key_valid_list
[i
].validate_callback (
277 key_name
, key_len
, value
, value_len
);
285 object_key
= malloc (sizeof (struct object_key
));
286 if (object_key
== 0) {
289 object_key
->key_name
= malloc (key_len
);
290 if (object_key
->key_name
== 0) {
291 goto error_put_object
;
293 memcpy (&val
, value
, 4);
294 object_key
->value
= malloc (value_len
);
295 if (object_key
->value
== 0) {
298 memcpy (object_key
->key_name
, key_name
, key_len
);
299 memcpy (object_key
->value
, value
, value_len
);
301 object_key
->key_len
= key_len
;
302 object_key
->value_len
= value_len
;
304 list_init (&object_key
->list
);
305 list_add (&object_key
->list
, &instance
->key_head
);
310 free (object_key
->key_name
);
316 hdb_handle_put (&object_instance_database
, object_handle
);
323 static int _clear_object(struct object_instance
*instance
)
325 struct list_head
*list
;
327 struct object_instance
*find_instance
= NULL
;
328 struct object_key
*object_key
= NULL
;
330 for (list
= instance
->key_head
.next
;
331 list
!= &instance
->key_head
; ) {
333 object_key
= list_entry (list
, struct object_key
,
338 list_del(&object_key
->list
);
339 free(object_key
->key_name
);
340 free(object_key
->value
);
343 for (list
= instance
->child_head
.next
;
344 list
!= &instance
->child_head
; ) {
346 find_instance
= list_entry (list
, struct object_instance
,
348 res
= _clear_object(find_instance
);
354 list_del(&find_instance
->child_list
);
355 free(find_instance
->object_name
);
362 static int object_destroy (
363 unsigned int object_handle
)
365 struct object_instance
*instance
;
368 res
= hdb_handle_get (&object_instance_database
,
369 object_handle
, (void *)&instance
);
374 /* Recursively clear sub-objects & keys */
375 res
= _clear_object(instance
);
377 list_del(&instance
->child_list
);
378 free(instance
->object_name
);
384 static int object_valid_set (
385 unsigned int object_handle
,
386 struct object_valid
*object_valid_list
,
387 unsigned int object_valid_list_entries
)
389 struct object_instance
*instance
;
392 res
= hdb_handle_get (&object_instance_database
,
393 object_handle
, (void *)&instance
);
398 instance
->object_valid_list
= object_valid_list
;
399 instance
->object_valid_list_entries
= object_valid_list_entries
;
401 hdb_handle_put (&object_instance_database
, object_handle
);
409 static int object_key_valid_set (
410 unsigned int object_handle
,
411 struct object_key_valid
*object_key_valid_list
,
412 unsigned int object_key_valid_list_entries
)
414 struct object_instance
*instance
;
417 res
= hdb_handle_get (&object_instance_database
,
418 object_handle
, (void *)&instance
);
423 instance
->object_key_valid_list
= object_key_valid_list
;
424 instance
->object_key_valid_list_entries
= object_key_valid_list_entries
;
426 hdb_handle_put (&object_instance_database
, object_handle
);
437 static int object_find_reset (
438 unsigned int object_handle
)
441 struct object_instance
*instance
;
443 res
= hdb_handle_get (&object_instance_database
,
444 object_handle
, (void *)&instance
);
448 instance
->find_child_list
= &instance
->child_head
;
450 hdb_handle_put (&object_instance_database
, object_handle
);
457 static int object_find (
458 unsigned int parent_object_handle
,
461 unsigned int *object_handle
)
464 struct object_instance
*instance
;
465 struct object_instance
*find_instance
= NULL
;
466 struct list_head
*list
;
467 unsigned int found
= 0;
469 res
= hdb_handle_get (&object_instance_database
,
470 parent_object_handle
, (void *)&instance
);
475 for (list
= instance
->find_child_list
->next
;
476 list
!= &instance
->child_head
; list
= list
->next
) {
478 find_instance
= list_entry (list
, struct object_instance
,
481 if ((find_instance
->object_name_len
== object_name_len
) &&
482 (memcmp (find_instance
->object_name
, object_name
,
483 object_name_len
) == 0)) {
488 instance
->find_child_list
= list
;
489 hdb_handle_put (&object_instance_database
, parent_object_handle
);
491 *object_handle
= find_instance
->object_handle
;
500 static int object_key_get (
501 unsigned int object_handle
,
507 unsigned int res
= 0;
508 struct object_instance
*instance
;
509 struct object_key
*object_key
= NULL
;
510 struct list_head
*list
;
513 res
= hdb_handle_get (&object_instance_database
,
514 object_handle
, (void *)&instance
);
518 for (list
= instance
->key_head
.next
;
519 list
!= &instance
->key_head
; list
= list
->next
) {
521 object_key
= list_entry (list
, struct object_key
, list
);
523 if ((object_key
->key_len
== key_len
) &&
524 (memcmp (object_key
->key_name
, key_name
, key_len
) == 0)) {
530 *value
= object_key
->value
;
532 *value_len
= object_key
->value_len
;
539 hdb_handle_put (&object_instance_database
, object_handle
);
546 static int object_key_delete (
547 unsigned int object_handle
,
555 struct object_instance
*instance
;
556 struct object_key
*object_key
= NULL
;
557 struct list_head
*list
;
560 res
= hdb_handle_get (&object_instance_database
,
561 object_handle
, (void *)&instance
);
565 for (list
= instance
->key_head
.next
;
566 list
!= &instance
->key_head
; list
= list
->next
) {
568 object_key
= list_entry (list
, struct object_key
, list
);
570 if ((object_key
->key_len
== key_len
) &&
571 (memcmp (object_key
->key_name
, key_name
, key_len
) == 0) &&
573 (object_key
->value_len
== value_len
&&
574 (memcmp (object_key
->value
, value
, value_len
) == 0)))) {
580 list_del(&object_key
->list
);
581 free(object_key
->key_name
);
582 free(object_key
->value
);
590 hdb_handle_put (&object_instance_database
, object_handle
);
597 static int object_key_replace (
598 unsigned int object_handle
,
608 struct object_instance
*instance
;
609 struct object_key
*object_key
= NULL
;
610 struct list_head
*list
;
613 res
= hdb_handle_get (&object_instance_database
,
614 object_handle
, (void *)&instance
);
618 for (list
= instance
->key_head
.next
;
619 list
!= &instance
->key_head
; list
= list
->next
) {
621 object_key
= list_entry (list
, struct object_key
, list
);
623 if ((object_key
->key_len
== key_len
) &&
624 (memcmp (object_key
->key_name
, key_name
, key_len
) == 0) &&
625 (old_value
== NULL
||
626 (object_key
->value_len
== old_value_len
&&
627 (memcmp (object_key
->value
, old_value
, old_value_len
) == 0)))) {
637 * Do validation check if validation is configured for the parent object
639 if (instance
->object_key_valid_list_entries
) {
640 for (i
= 0; i
< instance
->object_key_valid_list_entries
; i
++) {
642 instance
->object_key_valid_list
[i
].key_len
) &&
644 instance
->object_key_valid_list
[i
].key_name
,
653 * Item not found in validation list
658 if (instance
->object_key_valid_list
[i
].validate_callback
) {
659 res
= instance
->object_key_valid_list
[i
].validate_callback (
660 key_name
, key_len
, new_value
, new_value_len
);
668 if (new_value_len
<= object_key
->value_len
) {
669 void *replacement_value
;
670 replacement_value
= malloc(new_value_len
);
671 if (!replacement_value
)
673 free(object_key
->value
);
674 object_key
->value
= replacement_value
;
676 memcpy(object_key
->value
, new_value
, new_value_len
);
677 object_key
->value_len
= new_value_len
;
684 hdb_handle_put (&object_instance_database
, object_handle
);
688 hdb_handle_put (&object_instance_database
, object_handle
);
693 static int object_priv_get (
694 unsigned int object_handle
,
698 struct object_instance
*object_instance
;
700 res
= hdb_handle_get (&object_instance_database
,
701 object_handle
, (void *)&object_instance
);
706 *priv
= object_instance
->priv
;
708 hdb_handle_put (&object_instance_database
, object_handle
);
715 static int _dump_object(struct object_instance
*instance
, FILE *file
, int depth
)
717 struct list_head
*list
;
720 struct object_instance
*find_instance
= NULL
;
721 struct object_key
*object_key
= NULL
;
722 char stringbuf1
[1024];
723 char stringbuf2
[1024];
725 memcpy(stringbuf1
, instance
->object_name
, instance
->object_name_len
);
726 stringbuf1
[instance
->object_name_len
] = '\0';
728 for (i
=0; i
<depth
; i
++)
731 if (instance
->object_handle
!= OBJECT_PARENT_HANDLE
)
732 fprintf(file
, "%s {\n", stringbuf1
);
734 for (list
= instance
->key_head
.next
;
735 list
!= &instance
->key_head
; list
= list
->next
) {
737 object_key
= list_entry (list
, struct object_key
,
740 memcpy(stringbuf1
, object_key
->key_name
, object_key
->key_len
);
741 stringbuf1
[object_key
->key_len
] = '\0';
742 memcpy(stringbuf2
, object_key
->value
, object_key
->value_len
);
743 stringbuf2
[object_key
->value_len
] = '\0';
745 for (i
=0; i
<depth
+1; i
++)
748 fprintf(file
, "%s: %s\n", stringbuf1
, stringbuf2
);
751 for (list
= instance
->child_head
.next
;
752 list
!= &instance
->child_head
; list
= list
->next
) {
754 find_instance
= list_entry (list
, struct object_instance
,
756 res
= _dump_object(find_instance
, file
, depth
+1);
760 for (i
=0; i
<depth
; i
++)
763 if (instance
->object_handle
!= OBJECT_PARENT_HANDLE
)
764 fprintf(file
, "}\n");
770 static int object_key_iter_reset(unsigned int object_handle
)
773 struct object_instance
*instance
;
775 res
= hdb_handle_get (&object_instance_database
,
776 object_handle
, (void *)&instance
);
780 instance
->iter_key_list
= &instance
->key_head
;
782 hdb_handle_put (&object_instance_database
, object_handle
);
789 static int object_key_iter(unsigned int parent_object_handle
,
796 struct object_instance
*instance
;
797 struct object_key
*find_key
= NULL
;
798 struct list_head
*list
;
799 unsigned int found
= 0;
801 res
= hdb_handle_get (&object_instance_database
,
802 parent_object_handle
, (void *)&instance
);
807 list
= instance
->iter_key_list
->next
;
808 if (list
!= &instance
->key_head
) {
809 find_key
= list_entry (list
, struct object_key
, list
);
812 instance
->iter_key_list
= list
;
814 *key_name
= find_key
->key_name
;
816 *key_len
= find_key
->key_len
;
817 *value
= find_key
->value
;
819 *value_len
= find_key
->value_len
;
826 hdb_handle_put (&object_instance_database
, parent_object_handle
);
833 static int object_iter_reset(unsigned int parent_object_handle
)
836 struct object_instance
*instance
;
838 res
= hdb_handle_get (&object_instance_database
,
839 parent_object_handle
, (void *)&instance
);
843 instance
->iter_list
= &instance
->child_head
;
845 hdb_handle_put (&object_instance_database
, parent_object_handle
);
852 static int object_iter(unsigned int parent_object_handle
,
855 unsigned int *object_handle
)
858 struct object_instance
*instance
;
859 struct object_instance
*find_instance
= NULL
;
860 struct list_head
*list
;
861 unsigned int found
= 0;
863 res
= hdb_handle_get (&object_instance_database
,
864 parent_object_handle
, (void *)&instance
);
869 list
= instance
->iter_list
->next
;
870 if (list
!= &instance
->child_head
) {
872 find_instance
= list_entry (list
, struct object_instance
,
876 instance
->iter_list
= list
;
879 *object_handle
= find_instance
->object_handle
;
880 *object_name
= find_instance
->object_name
;
881 *name_len
= find_instance
->object_name_len
;
895 static int object_find_from(unsigned int parent_object_handle
,
896 unsigned int start_pos
,
899 unsigned int *object_handle
,
900 unsigned int *next_pos
)
903 unsigned int pos
= 0;
904 struct object_instance
*instance
;
905 struct object_instance
*find_instance
= NULL
;
906 struct list_head
*list
;
907 unsigned int found
= 0;
909 res
= hdb_handle_get (&object_instance_database
,
910 parent_object_handle
, (void *)&instance
);
915 for (list
= instance
->child_head
.next
;
916 list
!= &instance
->child_head
; list
= list
->next
) {
918 find_instance
= list_entry (list
, struct object_instance
,
921 if ((find_instance
->object_name_len
== object_name_len
) &&
922 (memcmp (find_instance
->object_name
, object_name
,
923 object_name_len
) == 0)) {
924 if (pos
++ == start_pos
) {
931 hdb_handle_put (&object_instance_database
, parent_object_handle
);
933 *object_handle
= find_instance
->object_handle
;
943 static int object_iter_from(unsigned int parent_object_handle
,
944 unsigned int start_pos
,
947 unsigned int *object_handle
)
950 unsigned int pos
= 0;
951 struct object_instance
*instance
;
952 struct object_instance
*find_instance
= NULL
;
953 struct list_head
*list
;
954 unsigned int found
= 0;
956 res
= hdb_handle_get (&object_instance_database
,
957 parent_object_handle
, (void *)&instance
);
963 for (list
= instance
->child_head
.next
;
964 list
!= &instance
->child_head
; list
= list
->next
) {
966 find_instance
= list_entry (list
, struct object_instance
,
968 if (pos
++ == start_pos
) {
975 *object_handle
= find_instance
->object_handle
;
976 *object_name
= find_instance
->object_name
;
977 *name_len
= find_instance
->object_name_len
;
990 static int object_key_iter_from(unsigned int parent_object_handle
,
991 unsigned int start_pos
,
997 unsigned int pos
= 0;
999 struct object_instance
*instance
;
1000 struct object_key
*find_key
= NULL
;
1001 struct list_head
*list
;
1002 unsigned int found
= 0;
1004 res
= hdb_handle_get (&object_instance_database
,
1005 parent_object_handle
, (void *)&instance
);
1011 for (list
= instance
->key_head
.next
;
1012 list
!= &instance
->key_head
; list
= list
->next
) {
1014 find_key
= list_entry (list
, struct object_key
, list
);
1016 if (pos
++ == start_pos
) {
1023 *key_name
= find_key
->key_name
;
1025 *key_len
= find_key
->key_len
;
1026 *value
= find_key
->value
;
1028 *value_len
= find_key
->value_len
;
1035 hdb_handle_put (&object_instance_database
, parent_object_handle
);
1045 static int object_parent_get(unsigned int object_handle
,
1046 unsigned int *parent_handle
)
1048 struct object_instance
*instance
;
1051 res
= hdb_handle_get (&object_instance_database
,
1052 object_handle
, (void *)&instance
);
1057 if (object_handle
== OBJECT_PARENT_HANDLE
)
1060 *parent_handle
= instance
->parent_handle
;
1062 hdb_handle_put (&object_instance_database
, object_handle
);
1068 static int object_dump(unsigned int object_handle
,
1071 struct object_instance
*instance
;
1074 res
= hdb_handle_get (&object_instance_database
,
1075 object_handle
, (void *)&instance
);
1080 res
= _dump_object(instance
, file
, -1);
1082 hdb_handle_put (&object_instance_database
, object_handle
);
1087 struct objdb_iface_ver0 objdb_iface
= {
1088 .objdb_init
= objdb_init
,
1089 .object_create
= object_create
,
1090 .object_priv_set
= object_priv_set
,
1091 .object_key_create
= object_key_create
,
1092 .object_key_delete
= object_key_delete
,
1093 .object_key_replace
= object_key_replace
,
1094 .object_destroy
= object_destroy
,
1095 .object_valid_set
= object_valid_set
,
1096 .object_key_valid_set
= object_key_valid_set
,
1097 .object_find_reset
= object_find_reset
,
1098 .object_find
= object_find
,
1099 .object_find_from
= object_find_from
,
1100 .object_key_get
= object_key_get
,
1101 .object_key_iter
= object_key_iter
,
1102 .object_key_iter_reset
= object_key_iter_reset
,
1103 .object_key_iter_from
= object_key_iter_from
,
1104 .object_iter
= object_iter
,
1105 .object_iter_reset
= object_iter_reset
,
1106 .object_iter_from
= object_iter_from
,
1107 .object_priv_get
= object_priv_get
,
1108 .object_parent_get
= object_parent_get
,
1109 .object_dump
= object_dump
1112 struct lcr_iface objdb_iface_ver0
[1] = {
1116 .versions_replace
= 0,
1117 .versions_replace_count
= 0,
1119 .dependency_count
= 0,
1120 .constructor
= NULL
,
1126 struct lcr_comp objdb_comp_ver0
= {
1128 .ifaces
= objdb_iface_ver0
1133 __attribute__ ((constructor
)) static void objdb_comp_register (void) {
1134 lcr_interfaces_set (&objdb_iface_ver0
[0], &objdb_iface
);
1136 lcr_component_register (&objdb_comp_ver0
);