]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/lib/event/subsystem.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / spdk / lib / event / subsystem.c
1 /*-
2 * BSD LICENSE
3 *
4 * Copyright (c) Intel Corporation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include "spdk_internal/event.h"
35
36 #include <stddef.h>
37 #include <stdbool.h>
38 #include <string.h>
39
40 static TAILQ_HEAD(spdk_subsystem_list, spdk_subsystem) g_subsystems =
41 TAILQ_HEAD_INITIALIZER(g_subsystems);
42 static TAILQ_HEAD(subsystem_depend, spdk_subsystem_depend) g_depends =
43 TAILQ_HEAD_INITIALIZER(g_depends);
44
45 void
46 spdk_add_subsystem(struct spdk_subsystem *subsystem)
47 {
48 TAILQ_INSERT_TAIL(&g_subsystems, subsystem, tailq);
49 }
50
51 void
52 spdk_add_subsystem_depend(struct spdk_subsystem_depend *depend)
53 {
54 TAILQ_INSERT_TAIL(&g_depends, depend, tailq);
55 }
56
57 static struct spdk_subsystem *
58 spdk_subsystem_find(struct spdk_subsystem_list *list, const char *name)
59 {
60 struct spdk_subsystem *iter;
61
62 TAILQ_FOREACH(iter, list, tailq) {
63 if (strcmp(name, iter->name) == 0) {
64 return iter;
65 }
66 }
67
68 return NULL;
69 }
70
71 static void
72 subsystem_sort(void)
73 {
74 bool depends_on, depends_on_sorted;
75 struct spdk_subsystem *subsystem, *subsystem_tmp;
76 struct spdk_subsystem_depend *subsystem_dep;
77
78 struct spdk_subsystem_list subsystems_list = TAILQ_HEAD_INITIALIZER(subsystems_list);
79
80 while (!TAILQ_EMPTY(&g_subsystems)) {
81 TAILQ_FOREACH_SAFE(subsystem, &g_subsystems, tailq, subsystem_tmp) {
82 depends_on = false;
83 TAILQ_FOREACH(subsystem_dep, &g_depends, tailq) {
84 if (strcmp(subsystem->name, subsystem_dep->name) == 0) {
85 depends_on = true;
86 depends_on_sorted = !!spdk_subsystem_find(&subsystems_list, subsystem_dep->depends_on);
87 if (depends_on_sorted)
88 continue;
89 break;
90 }
91 }
92
93 if (depends_on == false) {
94 TAILQ_REMOVE(&g_subsystems, subsystem, tailq);
95 TAILQ_INSERT_TAIL(&subsystems_list, subsystem, tailq);
96 } else {
97 if (depends_on_sorted == true) {
98 TAILQ_REMOVE(&g_subsystems, subsystem, tailq);
99 TAILQ_INSERT_TAIL(&subsystems_list, subsystem, tailq);
100 }
101 }
102 }
103 }
104
105 TAILQ_FOREACH_SAFE(subsystem, &subsystems_list, tailq, subsystem_tmp) {
106 TAILQ_REMOVE(&subsystems_list, subsystem, tailq);
107 TAILQ_INSERT_TAIL(&g_subsystems, subsystem, tailq);
108 }
109 }
110
111 int
112 spdk_subsystem_init(void)
113 {
114 int rc = 0;
115 struct spdk_subsystem *subsystem;
116 struct spdk_subsystem_depend *dep;
117
118 /* Verify that all dependency name and depends_on subsystems are registered */
119 TAILQ_FOREACH(dep, &g_depends, tailq) {
120 if (!spdk_subsystem_find(&g_subsystems, dep->name)) {
121 fprintf(stderr, "subsystem %s is missing\n", dep->name);
122 return -1;
123 }
124 if (!spdk_subsystem_find(&g_subsystems, dep->depends_on)) {
125 fprintf(stderr, "subsystem %s dependency %s is missing\n",
126 dep->name, dep->depends_on);
127 return -1;
128 }
129 }
130
131 subsystem_sort();
132
133 TAILQ_FOREACH(subsystem, &g_subsystems, tailq) {
134 if (subsystem->init) {
135 rc = subsystem->init();
136 if (rc)
137 return rc;
138 }
139 }
140 return rc;
141 }
142
143 int
144 spdk_subsystem_fini(void)
145 {
146 int rc = 0;
147 struct spdk_subsystem *cur;
148
149 cur = TAILQ_LAST(&g_subsystems, spdk_subsystem_list);
150
151 while (cur) {
152 if (cur->fini) {
153 rc = cur->fini();
154 if (rc)
155 return rc;
156 }
157 cur = TAILQ_PREV(cur, spdk_subsystem_list, tailq);
158 }
159
160 return rc;
161 }
162
163 void
164 spdk_subsystem_config(FILE *fp)
165 {
166 struct spdk_subsystem *subsystem;
167
168 TAILQ_FOREACH(subsystem, &g_subsystems, tailq) {
169 if (subsystem->config)
170 subsystem->config(fp);
171 }
172 }