Changeset bb154c6 in mainline for uspace/srv/sysman/units


Ignore:
Timestamp:
2019-08-03T08:15:25Z (6 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
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)
Message:

Add skeleton for configuration files loading

  • Create content of /cfg directory,
  • create sample configuration file,
  • refactored polymorphism.

Conflicts:

boot/Makefile

Location:
uspace/srv/sysman/units
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • 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>
    17#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
     16static const char *section_name = "Configuration";
     17
     18static 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 */
     28static 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
     105dump_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
     112finish:
     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
     123static 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}
    4164
    5165static void unit_cfg_init(unit_t *unit)
    6166{
    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
     175static 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
     183static 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);
    8199}
    9200
    10201static int unit_cfg_start(unit_t *unit)
    11202{
    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
     224DEFINE_UNIT_VMT(unit_cfg)
     225
  • uspace/srv/sysman/units/unit_cfg.h

    r6006f35 rbb154c6  
    22#define SYSMAN_UNIT_CFG_H
    33
    4 #include "unit_types.h"
     4#include "unit.h"
    55
    66typedef struct {
    7         const char *path;
     7        unit_t unit;
     8
     9        char *path;
    810} unit_cfg_t;
    911
    10 extern unit_ops_t unit_cfg_ops;
     12extern unit_vmt_t unit_cfg_ops;
    1113
    1214#endif
  • uspace/srv/sysman/units/unit_mnt.c

    r6006f35 rbb154c6  
    77#include "log.h"
    88#include "unit.h"
    9 #include "unit_mnt.h"
     9
     10static const char *section_name = "Mount";
     11
     12static 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};
    1018
    1119static void unit_mnt_init(unit_t *unit)
    1220{
    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
     29static 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
     41static 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);
    1657}
    1758
    1859static int unit_mnt_start(unit_t *unit)
    1960{
     61        unit_mnt_t *u_mnt = CAST_MNT(unit);
     62        assert(u_mnt);
     63
    2064        fibril_mutex_lock(&unit->state_mtx);
    2165       
     
    2872
    2973
    30         unit_mnt_t *data = &unit->data.mnt;
    31 
    3274        // 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, "",
    3476            IPC_FLAG_BLOCKING, 0);
    3577
    3678        if (rc == EOK) {
    37                 sysman_log(LVL_NOTE, "Mount (%p) mounted", unit);
     79                sysman_log(LVL_NOTE, "Mount ('%s') mounted", unit_name(unit));
    3880                unit_set_state(unit, STATE_STARTED);
    3981        } 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);
    4184                unit_set_state(unit, STATE_FAILED);
    4285        }
     
    4588}
    4689
    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 }
     90DEFINE_UNIT_VMT(unit_mnt)
    5391
    54 
    55 DEFINE_UNIT_OPS(unit_mnt)
    56 
  • uspace/srv/sysman/units/unit_mnt.h

    r6006f35 rbb154c6  
    22#define SYSMAN_UNIT_MNT_H
    33
    4 #include "unit_types.h"
     4#include "unit.h"
    55
    66typedef 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;
    1012} unit_mnt_t;
    1113
    12 extern unit_ops_t unit_mnt_ops;
    13 
     14extern unit_vmt_t unit_mnt_ops;
    1415
    1516#endif
  • uspace/srv/sysman/units/unit_tgt.c

    r6006f35 rbb154c6  
    11#include <errno.h>
    22
    3 #include "unit_tgt.h"
     3#include "unit.h"
    44
    55static void unit_tgt_init(unit_t *unit)
    66{
    7         // TODO
     7        unit_tgt_t *u_tgt = CAST_TGT(unit);
     8        assert(u_tgt);
     9        /* Nothing more to do */
     10}
     11
     12static 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
     19static 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;
    826}
    927
    1028static int unit_tgt_start(unit_t *unit)
    1129{
    12         //TODO
     30        unit_tgt_t *u_tgt = CAST_TGT(unit);
     31        assert(u_tgt);
     32
    1333        return EOK;
    1434}
    1535
    16 static void unit_tgt_destroy(unit_t *unit)
    17 {
    18         //TODO
    19 }
     36DEFINE_UNIT_VMT(unit_tgt)
    2037
    21 
    22 DEFINE_UNIT_OPS(unit_tgt)
    23 
  • uspace/srv/sysman/units/unit_tgt.h

    r6006f35 rbb154c6  
    22#define SYSMAN_UNIT_TGT_H
    33
    4 #include "unit_types.h"
     4#include "unit.h"
    55
    6 extern unit_ops_t unit_tgt_ops;
     6typedef struct {
     7        unit_t unit;
     8} unit_tgt_t;
     9
     10extern unit_vmt_t unit_tgt_ops;
    711
    812#endif
Note: See TracChangeset for help on using the changeset viewer.