source: mainline/uspace/srv/sysman/configuration.c@ c0e4fc50

Last change on this file since c0e4fc50 was 5559712, checked in by Matthieu Riolo <matthieu.riolo@…>, 6 years ago

sysman: Naive autostart instrumentation of locsrv

  • Add IPC_FLAG_AUTOSTART flag.
  • libsysman: sysman's broker and control API.
  • Simple implementation of service unit, exposee verification is missing.
  • Simple mapping of exposee to unit name in locsrv.
  • Temporary debug prints in locsrv.

Conflicts:

boot/Makefile.common
boot/arch/amd64/Makefile.inc
uspace/lib/c/include/ipc/services.h
uspace/srv/locsrv/locsrv.c

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * Copyright (c) 2015 Michal Koutny
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <adt/hash.h>
30#include <adt/hash_table.h>
31#include <adt/list.h>
32#include <assert.h>
33#include <errno.h>
34#include <fibril_synch.h>
35
36#include "configuration.h"
37#include "dep.h"
38#include "log.h"
39
40static hash_table_t units;
41
42/* Hash table functions */
43static size_t units_ht_hash(const ht_link_t *item)
44{
45 unit_t *unit =
46 hash_table_get_inst(item, unit_t, units);
47 return hash_string(unit->name);
48}
49
50static size_t units_ht_key_hash(void *key)
51{
52 return hash_string((const char *)key);
53}
54
55static bool units_ht_equal(const ht_link_t *item1, const ht_link_t *item2)
56{
57 return str_cmp(
58 hash_table_get_inst(item1, unit_t, units)->name,
59 hash_table_get_inst(item2, unit_t, units)->name) == 0;
60}
61
62static bool units_ht_key_equal(void *key, const ht_link_t *item)
63{
64 return str_cmp((const char *)key,
65 hash_table_get_inst(item, unit_t, units)->name) == 0;
66}
67
68
69static hash_table_ops_t units_ht_ops = {
70 .hash = &units_ht_hash,
71 .key_hash = &units_ht_key_hash,
72 .equal = &units_ht_equal,
73 .key_equal = &units_ht_key_equal,
74 .remove_callback = NULL // TODO realy unneeded?
75};
76
77/* Configuration functions */
78
79void configuration_init(void)
80{
81 hash_table_create(&units, 0, 0, &units_ht_ops);
82}
83
84int configuration_add_unit(unit_t *unit)
85{
86 assert(unit);
87 assert(unit->state == STATE_EMBRYO);
88 assert(unit->name != NULL);
89 sysman_log(LVL_DEBUG2, "%s('%s')", __func__, unit_name(unit));
90
91 if (hash_table_insert_unique(&units, &unit->units)) {
92 return EOK;
93 } else {
94 return EEXISTS;
95 }
96}
97
98void configuration_start_update(void) {
99 sysman_log(LVL_DEBUG2, "%s", __func__);
100}
101
102static bool configuration_commit_unit(ht_link_t *ht_link, void *arg)
103{
104 unit_t *unit = hash_table_get_inst(ht_link, unit_t, units);
105 // TODO state locking?
106 if (unit->state == STATE_EMBRYO) {
107 unit->state = STATE_STOPPED;
108 }
109
110 list_foreach(unit->dependencies, dependencies, unit_dependency_t, dep) {
111 if (dep->state == DEP_EMBRYO) {
112 dep->state = DEP_VALID;
113 }
114 }
115 return true;
116}
117
118/** Marks newly added units as usable (via state change) */
119void configuration_commit(void)
120{
121 sysman_log(LVL_DEBUG2, "%s", __func__);
122
123 /*
124 * Apply commit to all units, each commited unit commits its outgoing
125 * deps, thus eventually commiting all embryo deps as well.
126 */
127 hash_table_apply(&units, &configuration_commit_unit, NULL);
128}
129
130static bool configuration_rollback_unit(ht_link_t *ht_link, void *arg)
131{
132 unit_t *unit = hash_table_get_inst(ht_link, unit_t, units);
133
134 list_foreach_safe(unit->dependencies, cur_link, next_link) {
135 unit_dependency_t *dep =
136 list_get_instance(cur_link, unit_dependency_t, dependencies);
137 if (dep->state == DEP_EMBRYO) {
138 dep_remove_dependency(&dep);
139 }
140 }
141
142 if (unit->state == STATE_EMBRYO) {
143 hash_table_remove_item(&units, ht_link);
144 unit_destroy(&unit);
145 }
146
147 return true;
148}
149
150/** Remove all uncommited units and edges from configuratio
151 *
152 * Memory used by removed object is released.
153 */
154void configuration_rollback(void)
155{
156 sysman_log(LVL_DEBUG2, "%s", __func__);
157
158 hash_table_apply(&units, &configuration_rollback_unit, NULL);
159}
160
161static bool configuration_resolve_unit(ht_link_t *ht_link, void *arg)
162{
163 bool *has_error_ptr = arg;
164 unit_t *unit = hash_table_get_inst(ht_link, unit_t, units);
165
166 list_foreach(unit->dependencies, dependencies, unit_dependency_t, dep) {
167 assert(dep->dependant == unit);
168 assert((dep->dependency != NULL) != (dep->dependency_name != NULL));
169 if (dep->dependency) {
170 continue;
171 }
172
173 unit_t *dependency =
174 configuration_find_unit_by_name(dep->dependency_name);
175 if (dependency == NULL) {
176 sysman_log(LVL_ERROR,
177 "Cannot resolve dependency of '%s' to unit '%s'",
178 unit_name(unit), dep->dependency_name);
179 *has_error_ptr = true;
180 // TODO should we just leave the sprout untouched?
181 } else {
182 dep_resolve_dependency(dep, dependency);
183 }
184 }
185
186 return true;
187}
188
189/** Resolve unresolved dependencies between any pair of units
190 *
191 * @return EOK on success
192 * @return ENOENT when one or more resolution fails, information is logged
193 */
194int configuration_resolve_dependecies(void)
195{
196 sysman_log(LVL_DEBUG2, "%s", __func__);
197
198 bool has_error = false;
199 hash_table_apply(&units, &configuration_resolve_unit, &has_error);
200
201 return has_error ? ENOENT : EOK;
202}
203
204unit_t *configuration_find_unit_by_name(const char *name)
205{
206 ht_link_t *ht_link = hash_table_find(&units, (void *)name);
207 if (ht_link != NULL) {
208 return hash_table_get_inst(ht_link, unit_t, units);
209 } else {
210 return NULL;
211 }
212}
213
Note: See TracBrowser for help on using the repository browser.