xref: /kvmtool/util/init.c (revision 50cb6dc9209f79a687edf3d7307b446c48f57c74)
1*50cb6dc9SSasha Levin #include <linux/list.h>
2*50cb6dc9SSasha Levin #include <linux/kernel.h>
3*50cb6dc9SSasha Levin 
4*50cb6dc9SSasha Levin #include "kvm/kvm.h"
5*50cb6dc9SSasha Levin #include "kvm/util-init.h"
6*50cb6dc9SSasha Levin 
7*50cb6dc9SSasha Levin #define PRIORITY_LISTS 10
8*50cb6dc9SSasha Levin 
9*50cb6dc9SSasha Levin static struct hlist_head init_lists[PRIORITY_LISTS];
10*50cb6dc9SSasha Levin static struct hlist_head exit_lists[PRIORITY_LISTS];
11*50cb6dc9SSasha Levin 
12*50cb6dc9SSasha Levin int init_list_add(struct init_item *t, int (*init)(struct kvm *),
13*50cb6dc9SSasha Levin 			int priority, const char *name)
14*50cb6dc9SSasha Levin {
15*50cb6dc9SSasha Levin 	t->init = init;
16*50cb6dc9SSasha Levin 	t->fn_name = name;
17*50cb6dc9SSasha Levin 	hlist_add_head(&t->n, &init_lists[priority]);
18*50cb6dc9SSasha Levin 
19*50cb6dc9SSasha Levin 	return 0;
20*50cb6dc9SSasha Levin }
21*50cb6dc9SSasha Levin 
22*50cb6dc9SSasha Levin int exit_list_add(struct init_item *t, int (*init)(struct kvm *),
23*50cb6dc9SSasha Levin 			int priority, const char *name)
24*50cb6dc9SSasha Levin {
25*50cb6dc9SSasha Levin 	t->init = init;
26*50cb6dc9SSasha Levin 	t->fn_name = name;
27*50cb6dc9SSasha Levin 	hlist_add_head(&t->n, &exit_lists[priority]);
28*50cb6dc9SSasha Levin 
29*50cb6dc9SSasha Levin 	return 0;
30*50cb6dc9SSasha Levin }
31*50cb6dc9SSasha Levin 
32*50cb6dc9SSasha Levin int init_list__init(struct kvm *kvm)
33*50cb6dc9SSasha Levin {
34*50cb6dc9SSasha Levin 	unsigned int i;
35*50cb6dc9SSasha Levin 	int r = 0;
36*50cb6dc9SSasha Levin 	struct hlist_node *n;
37*50cb6dc9SSasha Levin 	struct init_item *t;
38*50cb6dc9SSasha Levin 
39*50cb6dc9SSasha Levin 	for (i = 0; i < ARRAY_SIZE(init_lists); i++)
40*50cb6dc9SSasha Levin 		hlist_for_each_entry(t, n, &init_lists[i], n) {
41*50cb6dc9SSasha Levin 			r = t->init(kvm);
42*50cb6dc9SSasha Levin 			if (r < 0) {
43*50cb6dc9SSasha Levin 				pr_warning("Failed init: %s\n", t->fn_name);
44*50cb6dc9SSasha Levin 				goto fail;
45*50cb6dc9SSasha Levin 			}
46*50cb6dc9SSasha Levin 		}
47*50cb6dc9SSasha Levin 
48*50cb6dc9SSasha Levin fail:
49*50cb6dc9SSasha Levin 	return r;
50*50cb6dc9SSasha Levin }
51*50cb6dc9SSasha Levin 
52*50cb6dc9SSasha Levin int init_list__exit(struct kvm *kvm)
53*50cb6dc9SSasha Levin {
54*50cb6dc9SSasha Levin 	int i;
55*50cb6dc9SSasha Levin 	int r = 0;
56*50cb6dc9SSasha Levin 	struct hlist_node *n;
57*50cb6dc9SSasha Levin 	struct init_item *t;
58*50cb6dc9SSasha Levin 
59*50cb6dc9SSasha Levin 	for (i = ARRAY_SIZE(exit_lists) - 1; i >= 0; i--)
60*50cb6dc9SSasha Levin 		hlist_for_each_entry(t, n, &exit_lists[i], n) {
61*50cb6dc9SSasha Levin 			r = t->init(kvm);
62*50cb6dc9SSasha Levin 			if (r < 0) {
63*50cb6dc9SSasha Levin 				pr_warning("%s failed.\n", t->fn_name);
64*50cb6dc9SSasha Levin 				goto fail;
65*50cb6dc9SSasha Levin 			}
66*50cb6dc9SSasha Levin 		}
67*50cb6dc9SSasha Levin fail:
68*50cb6dc9SSasha Levin 	return r;
69*50cb6dc9SSasha Levin }
70