Changeset bb154c6 in mainline
- Timestamp:
- 2019-08-03T08:15:25Z (6 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)
- Files:
-
- 3 added
- 1 deleted
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/Makefile
r6006f35 rbb154c6 70 70 endif 71 71 72 cp -r -L $(INITRD_CFG_PATH)/* $(DIST_PATH)/cfg 72 73 for app in $(RD_APPS) ; do \ 73 74 app_dir="`dirname "$$app"`" ; \ -
boot/Makefile.common
r6006f35 rbb154c6 50 50 TOOLS_PATH = $(ROOT_PATH)/tools 51 51 DRVS_PATH = drv 52 INITRD_CFG_PATH = $(USPACE_PATH)/cfg 53 # TODO configuration separation may change 54 ROOTFS_CFG_PATH = $(USPACE_PATH)/cfg 52 55 53 56 MKARRAY = $(TOOLS_PATH)/mkarray.py -
uspace/srv/sysman/Makefile
r6006f35 rbb154c6 29 29 30 30 USPACE_PREFIX = ../.. 31 EXTRA_CFLAGS = -I. -I./units 31 LIBS = $(LIBCONF_PREFIX)/libconf.a 32 EXTRA_CFLAGS += -I. -I./units -I$(LIBCONF_PREFIX)/include 32 33 BINARY = sysman 33 34 STATIC_NEEDED = y … … 41 42 unit.c \ 42 43 units/unit_cfg.c \ 43 units/unit_mnt.c \ 44 units/unit_tgt.c 44 units/unit_mnt.c \ 45 units/unit_tgt.c \ 46 util.c 45 47 46 48 include $(USPACE_PREFIX)/Makefile.common -
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 -
uspace/srv/sysman/configuration.h
r6006f35 rbb154c6 8 8 extern int configuration_add_unit(unit_t *); 9 9 10 extern int configuration_commit(void); 10 extern void configuration_start_update(void); 11 12 extern void configuration_commit(void); 13 14 extern void configuration_rollback(void); 15 16 extern int configuration_resolve_dependecies(void); 17 18 extern unit_t *configuration_find_unit_by_name(const char *); 19 11 20 12 21 #endif -
uspace/srv/sysman/dep.c
r6006f35 rbb154c6 1 #include <assert.h> 1 2 #include <errno.h> 2 3 #include <stdlib.h> 4 #include <str.h> 3 5 4 6 #include "dep.h" 7 8 static void dep_dependency_init(unit_dependency_t *dep) 9 { 10 link_initialize(&dep->dependants); 11 link_initialize(&dep->dependencies); 12 13 dep->dependency_name = NULL; 14 dep->state = DEP_EMBRYO; 15 } 16 17 unit_dependency_t *dep_dependency_create(void) 18 { 19 unit_dependency_t *dep = malloc(sizeof(unit_dependency_t)); 20 if (dep) { 21 dep_dependency_init(dep); 22 } 23 return dep; 24 } 25 26 void dep_dependency_destroy(unit_dependency_t **dep_ptr) 27 { 28 unit_dependency_t *dep = *dep_ptr; 29 if (dep == NULL) { 30 return; 31 } 32 33 list_remove(&dep->dependencies); 34 list_remove(&dep->dependants); 35 36 free(dep->dependency_name); 37 free(dep); 38 39 *dep_ptr = NULL; 40 } 41 42 int dep_sprout_dependency(unit_t *dependant, const char *dependency_name) 43 { 44 unit_dependency_t *dep = dep_dependency_create(); 45 int rc; 46 47 if (dep == NULL) { 48 rc = ENOMEM; 49 goto finish; 50 } 51 52 dep->dependency_name = str_dup(dependency_name); 53 if (dep->dependency_name == NULL) { 54 rc = ENOMEM; 55 goto finish; 56 } 57 58 list_append(&dep->dependencies, &dependant->dependencies); 59 dep->dependant = dependant; 60 61 rc = EOK; 62 63 finish: 64 if (rc != EOK) { 65 dep_dependency_destroy(&dep); 66 } 67 return rc; 68 } 69 70 void dep_resolve_dependency(unit_dependency_t *dep, unit_t *unit) 71 { 72 assert(dep->dependency == NULL); 73 assert(dep->dependency_name != NULL); 74 75 // TODO add to other side dependants list 76 dep->dependency = unit; 77 free(dep->dependency_name); 78 dep->dependency_name = NULL; 79 } 80 5 81 6 82 /** … … 10 86 int dep_add_dependency(unit_t *dependant, unit_t *dependency) 11 87 { 12 unit_dependency_t * edge = malloc(sizeof(unit_dependency_t));13 if ( edge== NULL) {88 unit_dependency_t *dep = dep_dependency_create(); 89 if (dep == NULL) { 14 90 return ENOMEM; 15 91 } 16 link_initialize(&edge->dependants);17 link_initialize(&edge->dependencies);18 92 19 // TODO check existence of the edge93 // TODO check existence of the dep 20 94 // TODO locking 21 95 // TODO check types and states of connected units 22 list_append(& edge->dependants, &dependency->dependants);23 list_append(& edge->dependencies, &dependant->dependencies);96 list_append(&dep->dependants, &dependency->dependants); 97 list_append(&dep->dependencies, &dependant->dependencies); 24 98 25 edge->dependant = dependant;26 edge->dependency = dependency;99 dep->dependant = dependant; 100 dep->dependency = dependency; 27 101 return EOK; 28 102 } 103 104 /** Remove dependency from dependency graph 105 * 106 * Given dependency is removed from graph and unallocated. 107 */ 108 void dep_remove_dependency(unit_dependency_t **dep_ptr) 109 { 110 // TODO here should be some checks, othewise replace this wrapper with 111 // direct destroy 112 dep_dependency_destroy(dep_ptr); 113 } -
uspace/srv/sysman/dep.h
r6006f35 rbb154c6 6 6 #include "unit.h" 7 7 8 /** Dependency edge between unit in dependency graph */ 8 typedef enum { 9 DEP_EMBRYO, 10 DEP_VALID 11 } dependency_state_t; 12 13 /** Dependency edge between unit in dependency graph 14 * 15 * @code 16 * dependant ---> dependency 17 * @endcode 18 * 19 */ 9 20 typedef struct { 21 /** Link to dependants list */ 10 22 link_t dependants; 23 /** Link to dependencies list */ 11 24 link_t dependencies; 25 26 dependency_state_t state; 12 27 13 28 /** Unit that depends on another */ 14 29 unit_t *dependant; 30 15 31 /** Unit that is dependency for another */ 16 32 unit_t *dependency; 33 34 /** Name of the dependency unit, for resolved dependencies it's NULL 35 * 36 * @note Either dependency or dependency_name is set. Never both nor 37 * none. 38 */ 39 char *dependency_name; 17 40 } unit_dependency_t; 18 41 42 extern unit_dependency_t *dep_dependency_create(void); 43 extern void dep_dependency_destroy(unit_dependency_t **); 44 45 extern int dep_sprout_dependency(unit_t *, const char *); 46 extern void dep_resolve_dependency(unit_dependency_t *, unit_t *); 47 19 48 extern int dep_add_dependency(unit_t *, unit_t *); 49 extern void dep_remove_dependency(unit_dependency_t **); 50 20 51 21 52 #endif -
uspace/srv/sysman/job.c
r6006f35 rbb154c6 137 137 138 138 /* Enqueue jobs */ 139 list_foreach_safe(*jobs, cur_link, next_lin ) {139 list_foreach_safe(*jobs, cur_link, next_link) { 140 140 list_remove(cur_link); 141 141 list_append(cur_link, &job_queue); -
uspace/srv/sysman/main.c
r6006f35 rbb154c6 36 36 goto fail; 37 37 } 38 mnt_initrd->name = str_dup("initrd.mnt"); 38 39 // TODO Use RDFMT 39 mnt_initrd->data.mnt.type = str_dup("ext4fs");40 mnt_initrd->data.mnt.mountpoint = str_dup("/");41 mnt_initrd->data.mnt.device = str_dup("bd/initrd");40 CAST_MNT(mnt_initrd)->type = str_dup("ext4fs"); 41 CAST_MNT(mnt_initrd)->mountpoint = str_dup("/"); 42 CAST_MNT(mnt_initrd)->device = str_dup("bd/initrd"); 42 43 43 44 cfg_init = unit_create(UNIT_CONFIGURATION); … … 46 47 goto fail; 47 48 } 48 cfg_init->data.cfg.path = str_dup("/cfg/"); 49 cfg_init->name = str_dup("init.cfg"); 50 CAST_CFG(cfg_init)->path = str_dup("/cfg/sysman"); 49 51 50 52 tgt_default = unit_create(UNIT_TARGET); … … 53 55 goto fail; 54 56 } 57 tgt_default->name = str_dup("default.tgt"); 55 58 56 59 … … 58 61 * Add units to configuration and start the default target. 59 62 */ 63 configuration_start_update(); 64 60 65 configuration_add_unit(mnt_initrd); 61 66 configuration_add_unit(cfg_init); -
uspace/srv/sysman/sysman.c
r6006f35 rbb154c6 22 22 job->unit = unit; 23 23 24 list_foreach(unit->dependencies, dependencies, unit_dependency_t, edge) {24 list_foreach(unit->dependencies, dependencies, unit_dependency_t, dep) { 25 25 job_t *blocking_job = NULL; 26 rc = sysman_create_closure_jobs( edge->dependency, &blocking_job,26 rc = sysman_create_closure_jobs(dep->dependency, &blocking_job, 27 27 accumulator, type); 28 28 if (rc != EOK) { … … 55 55 56 56 job_t *job = NULL; 57 // TODO shouldn't be here read-lock on configuration? 57 58 int rc = sysman_create_closure_jobs(unit, &job, &new_jobs, JOB_START); 58 59 if (rc != EOK) { -
uspace/srv/sysman/unit.c
r6006f35 rbb154c6 2 2 #include <errno.h> 3 3 #include <fibril_synch.h> 4 #include <conf/configuration.h> 5 #include <conf/ini.h> 4 6 #include <mem.h> 7 #include <stddef.h> 5 8 #include <stdio.h> 6 9 #include <stdlib.h> 10 #include <str.h> 7 11 12 #include "dep.h" 8 13 #include "log.h" 9 14 #include "unit.h" 10 15 11 16 /** Virtual method table for each unit type */ 12 static unit_ops_t *unit_type_vmts[] = {17 unit_vmt_t *unit_type_vmts[] = { 13 18 [UNIT_TARGET] = &unit_tgt_ops, 14 19 [UNIT_MOUNT] = &unit_mnt_ops, … … 16 21 }; 17 22 23 static const char *section_name = "Unit"; 24 25 static config_item_t unit_configuration[] = { 26 {"After", &unit_parse_unit_list, 0, ""}, 27 CONFIGURATION_ITEM_SENTINEL 28 }; 29 30 18 31 static void unit_init(unit_t *unit, unit_type_t type) 19 32 { 20 33 assert(unit); 21 34 35 // TODO is this necessary? 22 36 memset(unit, 0, sizeof(unit_t)); 23 link_initialize(&unit->units);24 37 25 38 unit->type = type; 39 unit->name = NULL; 40 26 41 unit->state = STATE_EMBRYO; 27 42 fibril_mutex_initialize(&unit->state_mtx); … … 31 46 list_initialize(&unit->dependencies); 32 47 33 unit_type_vmts[unit->type]->init(unit);48 UNIT_VMT(unit)->init(unit); 34 49 } 35 50 36 51 unit_t *unit_create(unit_type_t type) 37 52 { 38 unit_t *unit = malloc(sizeof(unit_t)); 53 size_t size = unit_type_vmts[type]->size; 54 unit_t *unit = malloc(size); 39 55 if (unit != NULL) { 40 56 unit_init(unit, type); … … 50 66 return; 51 67 52 unit_type_vmts[unit->type]->destroy(unit);68 UNIT_VMT(unit)->destroy(unit); 53 69 /* TODO: 54 70 * edges, … … 56 72 * other resources to come 57 73 */ 74 free(unit->name); 58 75 free(unit); 59 76 unit_ptr = NULL; … … 75 92 int unit_start(unit_t *unit) 76 93 { 77 sysman_log(LVL_DEBUG, "%s( %p)", __func__, unit);78 return unit_type_vmts[unit->type]->start(unit);94 sysman_log(LVL_DEBUG, "%s('%s')", __func__, unit_name(unit)); 95 return UNIT_VMT(unit)->start(unit); 79 96 } 97 98 int unit_load(unit_t *unit, ini_configuration_t *ini_conf, 99 text_parse_t *text_parse) 100 { 101 sysman_log(LVL_DEBUG, "%s('%s')", __func__, unit_name(unit)); 102 103 int rc = EOK; 104 ini_section_t *unit_section = ini_get_section(ini_conf, section_name); 105 if (unit_section) { 106 rc = config_load_ini_section(unit_configuration, 107 unit_section, unit, text_parse); 108 } 109 110 if (rc != EOK) { 111 return rc; 112 } else { 113 return UNIT_VMT(unit)->load(unit, ini_conf, text_parse); 114 } 115 } 116 117 unit_type_t unit_type_name_to_type(const char *type_name) 118 { 119 if (str_cmp(type_name, "cfg") == 0) 120 return UNIT_CONFIGURATION; 121 122 else if (str_cmp(type_name, "mnt") == 0) 123 return UNIT_MOUNT; 124 125 else if (str_cmp(type_name, "tgt") == 0) 126 return UNIT_TARGET; 127 128 else 129 return UNIT_TYPE_INVALID; 130 } 131 132 /** Format unit name to be presented to user */ 133 const char *unit_name(const unit_t *unit) 134 { 135 return unit->name ? unit->name : ""; 136 } 137 138 139 140 141 bool unit_parse_unit_list(const char *value, void *dst, text_parse_t *parse, 142 size_t lineno) 143 { 144 unit_t *unit = dst; 145 bool result; 146 char *my_value = str_dup(value); 147 148 if (!my_value) { 149 result = false; 150 goto finish; 151 } 152 153 char *to_split = my_value; 154 char *cur_tok; 155 156 while ((cur_tok = str_tok(to_split, " ", &to_split))) { 157 if (dep_sprout_dependency(unit, cur_tok) != EOK) { 158 result = false; 159 goto finish; 160 } 161 } 162 163 result = true; 164 165 finish: 166 free(my_value); 167 return result; 168 } -
uspace/srv/sysman/unit.h
r6006f35 rbb154c6 1 /* 2 * Unit terminology and OOP based on systemd. 3 */ 1 4 #ifndef SYSMAN_UNIT_H 2 5 #define SYSMAN_UNIT_H 3 6 7 #include <adt/hash_table.h> 4 8 #include <adt/list.h> 9 #include <conf/configuration.h> 10 #include <conf/ini.h> 11 #include <conf/text_parse.h> 5 12 #include <fibril_synch.h> 6 13 7 #include "unit_mnt.h" 8 #include "unit_cfg.h" 9 #include "unit_tgt.h" 10 #include "unit_types.h" 14 typedef enum { 15 UNIT_TYPE_INVALID = -1, 16 UNIT_TARGET = 0, 17 UNIT_MOUNT, 18 UNIT_CONFIGURATION, 19 } unit_type_t; 11 20 12 struct unit { 13 link_t units; 21 typedef enum { 22 STATE_EMBRYO = 0, 23 STATE_STARTING, 24 STATE_STARTED, 25 STATE_STOPPED, 26 STATE_FAILED 27 } unit_state_t; 28 29 typedef struct { 30 ht_link_t units; 14 31 15 32 unit_type_t type; 33 char *name; 16 34 17 35 unit_state_t state; … … 21 39 list_t dependencies; 22 40 list_t dependants; 41 } unit_t; 23 42 24 union { 25 unit_mnt_t mnt; 26 unit_cfg_t cfg; 27 } data; 43 typedef struct unit_vmt unit_vmt_t; 44 struct unit_vmt; 45 46 #include "unit_cfg.h" 47 #include "unit_mnt.h" 48 #include "unit_tgt.h" 49 50 #define DEFINE_CAST(NAME, TYPE, ENUM_TYPE) \ 51 static inline TYPE *CAST_##NAME(unit_t *u) \ 52 { \ 53 if (u->type == ENUM_TYPE) \ 54 return (TYPE *)u; \ 55 else \ 56 return NULL; \ 57 } \ 58 59 DEFINE_CAST(CFG, unit_cfg_t, UNIT_CONFIGURATION) 60 DEFINE_CAST(MNT, unit_mnt_t, UNIT_MOUNT) 61 DEFINE_CAST(TGT, unit_tgt_t, UNIT_TARGET) 62 63 struct unit_vmt { 64 size_t size; 65 66 void (*init)(unit_t *); 67 68 void (*destroy)(unit_t *); 69 70 int (*load)(unit_t *, ini_configuration_t *, text_parse_t *); 71 72 int (*start)(unit_t *); 28 73 }; 29 74 75 extern unit_vmt_t *unit_type_vmts[]; 76 77 #define DEFINE_UNIT_VMT(PREFIX) \ 78 unit_vmt_t PREFIX##_ops = { \ 79 .size = sizeof(PREFIX##_t), \ 80 .init = &PREFIX##_init, \ 81 .load = &PREFIX##_load, \ 82 .destroy = &PREFIX##_destroy, \ 83 .start = &PREFIX##_start \ 84 }; 85 86 #define UNIT_VMT(UNIT) unit_type_vmts[(UNIT)->type] 30 87 31 88 extern unit_t *unit_create(unit_type_t); … … 35 92 extern void unit_set_state(unit_t *, unit_state_t); 36 93 94 extern int unit_load(unit_t *, ini_configuration_t *, text_parse_t *); 37 95 extern int unit_start(unit_t *); 38 96 97 extern unit_type_t unit_type_name_to_type(const char *); 98 99 extern const char *unit_name(const unit_t *); 100 101 extern bool unit_parse_unit_list(const char *, void *, text_parse_t *, size_t); 102 39 103 #endif -
uspace/srv/sysman/units/unit_cfg.c
r6006f35 rbb154c6 1 #include <adt/list.h> 2 #include <assert.h> 3 #include <conf/configuration.h> 4 #include <conf/ini.h> 5 #include <conf/text_parse.h> 6 #include <dirent.h> 1 7 #include <errno.h> 2 3 #include "unit_cfg.h" 8 #include <stdlib.h> 9 #include <str.h> 10 11 #include "configuration.h" 12 #include "log.h" 13 #include "unit.h" 14 #include "util.h" 15 16 static const char *section_name = "Configuration"; 17 18 static config_item_t unit_configuration[] = { 19 {"Path", &config_parse_string, offsetof(unit_cfg_t, path), NULL}, 20 CONFIGURATION_ITEM_SENTINEL 21 }; 22 23 /** 24 * TODO refactor path handling and rename to 'load from file' 25 * 26 * @param[out] unit_ptr Unit loaded from the file. Undefined when function fails. 27 */ 28 static int cfg_parse_file(const char *dirname, const char *filename, 29 unit_t **unit_ptr) 30 { 31 int rc = EOK; 32 unit_t *new_unit = NULL; 33 char *fn = NULL; 34 ini_configuration_t ini_conf; 35 text_parse_t text_parse; 36 37 ini_configuration_init(&ini_conf); 38 text_parse_init(&text_parse); 39 40 const char *last_dot = str_rchr(filename, '.'); 41 if (last_dot == NULL) { 42 rc = EINVAL; 43 goto finish; 44 } 45 46 const char *unit_name = filename; 47 const char *unit_type_name = last_dot + 1; 48 49 unit_type_t unit_type = unit_type_name_to_type(unit_type_name); 50 if (unit_type == UNIT_TYPE_INVALID) { 51 rc = EINVAL; 52 goto finish; 53 } 54 55 unit_t *u = configuration_find_unit_by_name(unit_name); 56 if (u != NULL) { 57 // TODO allow updating configuration of existing unit 58 rc = EEXISTS; 59 goto finish; 60 } else { 61 new_unit = u = unit_create(unit_type); 62 new_unit->name = str_dup(unit_name); 63 if (new_unit->name == NULL) { 64 rc = ENOMEM; 65 goto finish; 66 } 67 } 68 if (u == NULL) { 69 rc = ENOMEM; 70 goto finish; 71 } 72 assert(u->type == unit_type); 73 74 fn = compose_path(dirname, filename); 75 if (fn == NULL) { 76 rc = ENOMEM; 77 goto finish; 78 } 79 80 /* Parse INI file to ini_conf structure */ 81 rc = ini_parse_file(fn, &ini_conf, &text_parse); 82 switch (rc) { 83 case EOK: 84 /* This is fine */ 85 break; 86 case EINVAL: 87 goto dump_parse; 88 break; 89 default: 90 sysman_log(LVL_WARN, 91 "Cannot parse '%s' (%i).", fn, rc); 92 goto finish; 93 } 94 95 /* Parse ini structure */ 96 rc = unit_load(u, &ini_conf, &text_parse); 97 *unit_ptr = u; 98 99 /* 100 * Here we just continue undisturbed by errors, they'll be returned in 101 * 'finish' block and potential parse errors (or none) will be logged 102 * in 'dump_parse' block. 103 */ 104 105 dump_parse: 106 list_foreach(text_parse.errors, link, text_parse_error_t, err) { 107 sysman_log(LVL_WARN, 108 "Error (%i) when parsing '%s' on line %i.", 109 err->parse_errno, fn, err->lineno); 110 } 111 112 finish: 113 free(fn); 114 ini_configuration_deinit(&ini_conf); 115 text_parse_deinit(&text_parse); 116 if (rc != EOK) { 117 unit_destroy(&new_unit); 118 } 119 120 return rc; 121 } 122 123 static int cfg_load_configuration(const char *path) 124 { 125 DIR *dir; 126 struct dirent *de; 127 128 dir = opendir(path); 129 if (dir == NULL) { 130 sysman_log(LVL_ERROR, 131 "Cannot open configuration directory '%s'", path); 132 return EIO; 133 } 134 135 configuration_start_update(); 136 137 while ((de = readdir(dir))) { 138 unit_t *unit = NULL; 139 int rc = cfg_parse_file(path, de->d_name, &unit); 140 if (rc != EOK) { 141 sysman_log(LVL_WARN, "Cannot load unit from file %s/%s", 142 path, de->d_name); 143 /* 144 * Ignore error for now, we'll fail only when we're 145 * unable to resolve dependency names. 146 */ 147 continue; 148 } 149 150 assert(unit->state = STATE_EMBRYO); 151 configuration_add_unit(unit); 152 } 153 closedir(dir); 154 155 int rc = configuration_resolve_dependecies(); 156 if (rc != EOK) { 157 configuration_rollback(); 158 return rc; 159 } 160 161 configuration_commit(); 162 return EOK; 163 } 4 164 5 165 static void unit_cfg_init(unit_t *unit) 6 166 { 7 // TODO 167 unit_cfg_t *u_cfg = CAST_CFG(unit); 168 assert(u_cfg); 169 170 u_cfg->path = NULL; 171 } 172 173 174 175 static void unit_cfg_destroy(unit_t *unit) 176 { 177 unit_cfg_t *u_cfg = CAST_CFG(unit); 178 assert(u_cfg); 179 180 free(u_cfg->path); 181 } 182 183 static int unit_cfg_load(unit_t *unit, ini_configuration_t *ini_conf, 184 text_parse_t *text_parse) 185 { 186 unit_cfg_t *u_cfg = CAST_CFG(unit); 187 assert(u_cfg); 188 189 ini_section_t *section = ini_get_section(ini_conf, section_name); 190 if (section == NULL) { 191 sysman_log(LVL_ERROR, 192 "Expected section '%s' in configuration of unit '%s'", 193 section_name, unit_name(unit)); 194 return ENOENT; 195 } 196 197 return config_load_ini_section(unit_configuration, section, u_cfg, 198 text_parse); 8 199 } 9 200 10 201 static int unit_cfg_start(unit_t *unit) 11 202 { 12 //TODO 13 return EOK; 14 } 15 16 static void unit_cfg_destroy(unit_t *unit) 17 { 18 //TODO 19 } 20 21 22 DEFINE_UNIT_OPS(unit_cfg) 23 203 unit_cfg_t *u_cfg = CAST_CFG(unit); 204 assert(u_cfg); 205 206 /* 207 * Skip starting state and hold state lock during whole configuration 208 * load. 209 */ 210 fibril_mutex_lock(&unit->state_mtx); 211 int rc = cfg_load_configuration(u_cfg->path); 212 213 if (rc == EOK) { 214 unit->state = STATE_STARTED; 215 } else { 216 unit->state = STATE_FAILED; 217 } 218 fibril_condvar_broadcast(&unit->state_cv); 219 fibril_mutex_unlock(&unit->state_mtx); 220 221 return rc; 222 } 223 224 DEFINE_UNIT_VMT(unit_cfg) 225 -
uspace/srv/sysman/units/unit_cfg.h
r6006f35 rbb154c6 2 2 #define SYSMAN_UNIT_CFG_H 3 3 4 #include "unit _types.h"4 #include "unit.h" 5 5 6 6 typedef struct { 7 const char *path; 7 unit_t unit; 8 9 char *path; 8 10 } unit_cfg_t; 9 11 10 extern unit_ ops_t unit_cfg_ops;12 extern unit_vmt_t unit_cfg_ops; 11 13 12 14 #endif -
uspace/srv/sysman/units/unit_mnt.c
r6006f35 rbb154c6 7 7 #include "log.h" 8 8 #include "unit.h" 9 #include "unit_mnt.h" 9 10 static const char *section_name = "Mount"; 11 12 static config_item_t unit_configuration[] = { 13 {"What", &config_parse_string, offsetof(unit_mnt_t, device), NULL}, 14 {"Where", &config_parse_string, offsetof(unit_mnt_t, mountpoint), NULL}, 15 {"Type", &config_parse_string, offsetof(unit_mnt_t, type), NULL}, 16 CONFIGURATION_ITEM_SENTINEL 17 }; 10 18 11 19 static void unit_mnt_init(unit_t *unit) 12 20 { 13 assert(unit->data.mnt.type == NULL); 14 assert(unit->data.mnt.mountpoint == NULL); 15 assert(unit->data.mnt.device == NULL); 21 unit_mnt_t *u_mnt = CAST_MNT(unit); 22 assert(u_mnt); 23 24 u_mnt->type = NULL; 25 u_mnt->mountpoint = NULL; 26 u_mnt->device = NULL; 27 } 28 29 static void unit_mnt_destroy(unit_t *unit) 30 { 31 assert(unit->type == UNIT_MOUNT); 32 unit_mnt_t *u_mnt = CAST_MNT(unit); 33 34 sysman_log(LVL_DEBUG2, "%s, %p, %p, %p", __func__, 35 u_mnt->type, u_mnt->mountpoint, u_mnt->device); 36 free(u_mnt->type); 37 free(u_mnt->mountpoint); 38 free(u_mnt->device); 39 } 40 41 static int unit_mnt_load(unit_t *unit, ini_configuration_t *ini_conf, 42 text_parse_t *text_parse) 43 { 44 unit_mnt_t *u_mnt = CAST_MNT(unit); 45 assert(u_mnt); 46 47 ini_section_t *section = ini_get_section(ini_conf, section_name); 48 if (section == NULL) { 49 sysman_log(LVL_ERROR, 50 "Expected section '%s' in configuration of unit '%s'", 51 section_name, unit_name(unit)); 52 return ENOENT; 53 } 54 55 return config_load_ini_section(unit_configuration, section, u_mnt, 56 text_parse); 16 57 } 17 58 18 59 static int unit_mnt_start(unit_t *unit) 19 60 { 61 unit_mnt_t *u_mnt = CAST_MNT(unit); 62 assert(u_mnt); 63 20 64 fibril_mutex_lock(&unit->state_mtx); 21 65 … … 28 72 29 73 30 unit_mnt_t *data = &unit->data.mnt;31 32 74 // TODO use other mount parameters 33 int rc = mount( data->type, data->mountpoint, data->device, "",75 int rc = mount(u_mnt->type, u_mnt->mountpoint, u_mnt->device, "", 34 76 IPC_FLAG_BLOCKING, 0); 35 77 36 78 if (rc == EOK) { 37 sysman_log(LVL_NOTE, "Mount ( %p) mounted", unit);79 sysman_log(LVL_NOTE, "Mount ('%s') mounted", unit_name(unit)); 38 80 unit_set_state(unit, STATE_STARTED); 39 81 } else { 40 sysman_log(LVL_ERROR, "Mount (%p) failed (%i)", unit, rc); 82 sysman_log(LVL_ERROR, "Mount ('%s') failed (%i)", 83 unit_name(unit), rc); 41 84 unit_set_state(unit, STATE_FAILED); 42 85 } … … 45 88 } 46 89 47 static void unit_mnt_destroy(unit_t *unit) 48 { 49 free(unit->data.mnt.type); 50 free(unit->data.mnt.mountpoint); 51 free(unit->data.mnt.device); 52 } 90 DEFINE_UNIT_VMT(unit_mnt) 53 91 54 55 DEFINE_UNIT_OPS(unit_mnt)56 -
uspace/srv/sysman/units/unit_mnt.h
r6006f35 rbb154c6 2 2 #define SYSMAN_UNIT_MNT_H 3 3 4 #include "unit _types.h"4 #include "unit.h" 5 5 6 6 typedef struct { 7 const char *type; 8 const char *mountpoint; 9 const char *device; 7 unit_t unit; 8 9 char *type; 10 char *mountpoint; 11 char *device; 10 12 } unit_mnt_t; 11 13 12 extern unit_ops_t unit_mnt_ops; 13 14 extern unit_vmt_t unit_mnt_ops; 14 15 15 16 #endif -
uspace/srv/sysman/units/unit_tgt.c
r6006f35 rbb154c6 1 1 #include <errno.h> 2 2 3 #include "unit _tgt.h"3 #include "unit.h" 4 4 5 5 static void unit_tgt_init(unit_t *unit) 6 6 { 7 // TODO 7 unit_tgt_t *u_tgt = CAST_TGT(unit); 8 assert(u_tgt); 9 /* Nothing more to do */ 10 } 11 12 static void unit_tgt_destroy(unit_t *unit) 13 { 14 unit_tgt_t *u_tgt = CAST_TGT(unit); 15 assert(u_tgt); 16 /* Nothing more to do */ 17 } 18 19 static int unit_tgt_load(unit_t *unit, ini_configuration_t *ini_conf, 20 text_parse_t *text_parse) 21 { 22 unit_tgt_t *u_tgt = CAST_TGT(unit); 23 assert(u_tgt); 24 25 return EOK; 8 26 } 9 27 10 28 static int unit_tgt_start(unit_t *unit) 11 29 { 12 //TODO 30 unit_tgt_t *u_tgt = CAST_TGT(unit); 31 assert(u_tgt); 32 13 33 return EOK; 14 34 } 15 35 16 static void unit_tgt_destroy(unit_t *unit) 17 { 18 //TODO 19 } 36 DEFINE_UNIT_VMT(unit_tgt) 20 37 21 22 DEFINE_UNIT_OPS(unit_tgt)23 -
uspace/srv/sysman/units/unit_tgt.h
r6006f35 rbb154c6 2 2 #define SYSMAN_UNIT_TGT_H 3 3 4 #include "unit _types.h"4 #include "unit.h" 5 5 6 extern unit_ops_t unit_tgt_ops; 6 typedef struct { 7 unit_t unit; 8 } unit_tgt_t; 9 10 extern unit_vmt_t unit_tgt_ops; 7 11 8 12 #endif
Note:
See TracChangeset
for help on using the changeset viewer.