Changeset bb154c6 in mainline for uspace/srv/sysman/configuration.c
- Timestamp:
- 2019-08-03T08:15:25Z (5 years ago)
- Children:
- 09a8006
- Parents:
- 6006f35
- git-author:
- Michal Koutný <xm.koutny+hos@…> (2015-04-15 15:14:58)
- git-committer:
- Matthieu Riolo <matthieu.riolo@…> (2019-08-03 08:15:25)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/sysman/configuration.c
r6006f35 rbb154c6 1 #include <adt/hash.h> 2 #include <adt/hash_table.h> 1 3 #include <adt/list.h> 2 4 #include <assert.h> … … 5 7 6 8 #include "configuration.h" 9 #include "dep.h" 7 10 #include "log.h" 8 11 9 static list_t units; 10 static fibril_mutex_t units_mtx; 12 static hash_table_t units; 13 static fibril_rwlock_t units_rwl; 14 15 /* Hash table functions */ 16 static size_t units_ht_hash(const ht_link_t *item) 17 { 18 unit_t *unit = 19 hash_table_get_inst(item, unit_t, units); 20 return hash_string(unit->name); 21 } 22 23 static size_t units_ht_key_hash(void *key) 24 { 25 return hash_string((const char *)key); 26 } 27 28 static bool units_ht_equal(const ht_link_t *item1, const ht_link_t *item2) 29 { 30 return str_cmp( 31 hash_table_get_inst(item1, unit_t, units)->name, 32 hash_table_get_inst(item2, unit_t, units)->name) == 0; 33 } 34 35 static bool units_ht_key_equal(void *key, const ht_link_t *item) 36 { 37 return str_cmp((const char *)key, 38 hash_table_get_inst(item, unit_t, units)->name) == 0; 39 } 40 41 42 static hash_table_ops_t units_ht_ops = { 43 .hash = &units_ht_hash, 44 .key_hash = &units_ht_key_hash, 45 .equal = &units_ht_equal, 46 .key_equal = &units_ht_key_equal, 47 .remove_callback = NULL // TODO realy unneeded? 48 }; 49 50 /* Configuration functions */ 11 51 12 52 void configuration_init(void) 13 53 { 14 list_initialize(&units);15 fibril_ mutex_initialize(&units_mtx);54 hash_table_create(&units, 0, 0, &units_ht_ops); 55 fibril_rwlock_initialize(&units_rwl); 16 56 } 17 57 18 58 int configuration_add_unit(unit_t *unit) 19 59 { 20 sysman_log(LVL_DEBUG2, "%s(%p)", __func__, unit);21 60 assert(unit); 22 61 assert(unit->state == STATE_EMBRYO); 62 assert(unit->name != NULL); 63 assert(fibril_rwlock_is_write_locked(&units_rwl)); 64 sysman_log(LVL_DEBUG2, "%s('%s')", __func__, unit_name(unit)); 23 65 24 fibril_mutex_lock(&units_mtx); 25 list_append(&unit->units, &units); 26 27 // TODO check name uniqueness 28 fibril_mutex_unlock(&units_mtx); 29 return EOK; 66 if (hash_table_insert_unique(&units, &unit->units)) { 67 return EOK; 68 } else { 69 return EEXISTS; 70 } 71 } 72 73 void configuration_start_update(void) { 74 assert(!fibril_rwlock_is_write_locked(&units_rwl)); 75 sysman_log(LVL_DEBUG2, "%s", __func__); 76 fibril_rwlock_write_lock(&units_rwl); 77 } 78 79 static bool configuration_commit_unit(ht_link_t *ht_link, void *arg) 80 { 81 unit_t *unit = hash_table_get_inst(ht_link, unit_t, units); 82 // TODO state locking? 83 if (unit->state == STATE_EMBRYO) { 84 unit->state = STATE_STOPPED; 85 } 86 87 list_foreach(unit->dependencies, dependencies, unit_dependency_t, dep) { 88 if (dep->state == DEP_EMBRYO) { 89 dep->state = DEP_VALID; 90 } 91 } 92 return true; 30 93 } 31 94 32 95 /** Marks newly added units as usable (via state change) */ 33 intconfiguration_commit(void)96 void configuration_commit(void) 34 97 { 98 assert(fibril_rwlock_is_write_locked(&units_rwl)); 35 99 sysman_log(LVL_DEBUG2, "%s", __func__); 36 100 37 fibril_mutex_lock(&units_mtx); 38 list_foreach(units, units, unit_t, u) { 39 if (u->state == STATE_EMBRYO) { 40 u->state = STATE_STOPPED; 101 /* 102 * Apply commit to all units, each commited unit commits its outgoing 103 * deps, thus eventually commiting all embryo deps as well. 104 */ 105 hash_table_apply(&units, &configuration_commit_unit, NULL); 106 fibril_rwlock_write_unlock(&units_rwl); 107 } 108 109 static bool configuration_rollback_unit(ht_link_t *ht_link, void *arg) 110 { 111 unit_t *unit = hash_table_get_inst(ht_link, unit_t, units); 112 113 list_foreach_safe(unit->dependencies, cur_link, next_link) { 114 unit_dependency_t *dep = 115 list_get_instance(cur_link, unit_dependency_t, dependencies); 116 if (dep->state == DEP_EMBRYO) { 117 dep_remove_dependency(&dep); 41 118 } 42 119 } 43 fibril_mutex_unlock(&units_mtx);44 120 45 return EOK; 121 if (unit->state == STATE_EMBRYO) { 122 hash_table_remove_item(&units, ht_link); 123 unit_destroy(&unit); 124 } 125 126 return true; 46 127 } 128 129 void configuration_rollback(void) 130 { 131 assert(fibril_rwlock_is_write_locked(&units_rwl)); 132 sysman_log(LVL_DEBUG2, "%s", __func__); 133 134 hash_table_apply(&units, &configuration_rollback_unit, NULL); 135 fibril_rwlock_write_unlock(&units_rwl); 136 } 137 138 static bool configuration_resolve_unit(ht_link_t *ht_link, void *arg) 139 { 140 bool *has_error_ptr = arg; 141 unit_t *unit = hash_table_get_inst(ht_link, unit_t, units); 142 143 list_foreach(unit->dependencies, dependencies, unit_dependency_t, dep) { 144 assert(dep->dependant == unit); 145 assert((dep->dependency != NULL) != (dep->dependency_name != NULL)); 146 if (dep->dependency) { 147 continue; 148 } 149 150 unit_t *dependency = 151 configuration_find_unit_by_name(dep->dependency_name); 152 if (dependency == NULL) { 153 sysman_log(LVL_ERROR, 154 "Cannot resolve dependency of '%s' to unit '%s'", 155 unit_name(unit), dep->dependency_name); 156 *has_error_ptr = true; 157 // TODO should we just leave the sprout untouched? 158 } else { 159 dep_resolve_dependency(dep, dependency); 160 } 161 } 162 163 return true; 164 } 165 166 /** Resolve unresolved dependencies between any pair of units 167 * 168 * @return EOK on success 169 * @return ENONENT when one or more resolution fails, information is logged 170 */ 171 int configuration_resolve_dependecies(void) 172 { 173 assert(fibril_rwlock_is_write_locked(&units_rwl)); 174 sysman_log(LVL_DEBUG2, "%s", __func__); 175 176 bool has_error = false; 177 hash_table_apply(&units, &configuration_resolve_unit, &has_error); 178 179 return has_error ? ENOENT : EOK; 180 } 181 182 unit_t *configuration_find_unit_by_name(const char *name) 183 { 184 ht_link_t *ht_link = hash_table_find(&units, (void *)name); 185 if (ht_link != NULL) { 186 return hash_table_get_inst(ht_link, unit_t, units); 187 } else { 188 return NULL; 189 } 190 } 191
Note:
See TracChangeset
for help on using the changeset viewer.