Changeset 5559712 in mainline for uspace/srv/sysman/main.c


Ignore:
Timestamp:
2019-08-03T09:28:50Z (5 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
c0e4fc50
Parents:
2dda1d4
git-author:
Michal Koutný <xm.koutny+hos@…> (2015-05-07 11:49:47)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2019-08-03 09:28:50)
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/sysman/main.c

    r2dda1d4 r5559712  
    3030#include <errno.h>
    3131#include <fibril.h>
     32#include <ipc/sysman.h>
     33#include <macros.h>
     34#include <ns.h>
    3235#include <stddef.h>
    3336#include <stdio.h>
     
    3538
    3639#include "configuration.h"
     40#include "connection_broker.h"
     41#include "connection_ctl.h"
    3742#include "dep.h"
    3843#include "job.h"
     
    4348#define NAME "sysman"
    4449
    45 static void sysman_connection(ipc_callid_t callid, ipc_call_t *call, void *arg)
    46 {
    47         /* TODO handle client connections */
     50#define INITRD_DEVICE       "bd/initrd"
     51#define INITRD_MOUNT_POINT  "/"
     52#define INITRD_CFG_PATH     "/cfg/sysman"
     53
     54#define TARGET_INIT     "initrd.tgt"
     55#define TARGET_ROOTFS   "rootfs.tgt"
     56#define TARGET_DEFAULT  "default.tgt"
     57
     58#define UNIT_MNT_INITRD "initrd.mnt"
     59#define UNIT_CFG_INITRD "init.cfg"
     60
     61static const char *target_sequence[] = {
     62        TARGET_INIT,
     63        TARGET_ROOTFS,
     64        TARGET_DEFAULT,
     65        NULL
     66};
     67
     68/*
     69 * Forward declarations
     70 */
     71static void prepare_and_run_job(const char **target_name_ptr);
     72
     73/*
     74 * Static functions
     75 */
     76
     77static void sysman_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     78{
     79        sysman_interface_t iface = IPC_GET_ARG1(*icall);
     80        switch (iface) {
     81        case SYSMAN_PORT_BROKER:
     82                sysman_connection_broker(iid, icall);
     83                break;
     84        case SYSMAN_PORT_CTL:
     85                sysman_connection_ctl(iid, icall);
     86                break;
     87        default:
     88                /* Unknown interface */
     89                async_answer_0(iid, ENOENT);
     90        }
    4891}
    4992
    5093/** Build hard coded configuration */
    51 static job_t *create_entry_configuration(void) {
    52         int result = EOK;
     94static int create_entry_configuration(void) {
     95        int rc;
    5396        unit_t *mnt_initrd = NULL;
    5497        unit_t *cfg_init = NULL;
    55         unit_t *tgt_default = NULL;
     98        unit_t *tgt_init = NULL;
    5699
    57100        mnt_initrd = unit_create(UNIT_MOUNT);
    58101        if (mnt_initrd == NULL) {
    59                 result = ENOMEM;
     102                rc = ENOMEM;
    60103                goto fail;
    61104        }
    62         mnt_initrd->name                 = str_dup("initrd.mnt");
    63         // TODO Use RDFMT
    64         CAST_MNT(mnt_initrd)->type       = str_dup("ext4fs");
    65         CAST_MNT(mnt_initrd)->mountpoint = str_dup("/");
    66         CAST_MNT(mnt_initrd)->device     = str_dup("bd/initrd");
     105        mnt_initrd->name                 = str_dup(UNIT_MNT_INITRD);
     106        CAST_MNT(mnt_initrd)->type       = str_dup(STRING(RDFMT));
     107        CAST_MNT(mnt_initrd)->mountpoint = str_dup(INITRD_MOUNT_POINT);
     108        CAST_MNT(mnt_initrd)->device     = str_dup(INITRD_DEVICE);
     109        CAST_MNT(mnt_initrd)->autostart  = false;
     110        CAST_MNT(mnt_initrd)->blocking   = true;
    67111
    68112        cfg_init = unit_create(UNIT_CONFIGURATION);
    69113        if (cfg_init == NULL) {
    70                 result = ENOMEM;
     114                rc = ENOMEM;
    71115                goto fail;
    72116        }
    73         cfg_init->name           = str_dup("init.cfg");
    74         CAST_CFG(cfg_init)->path = str_dup("/cfg/sysman");
     117        cfg_init->name           = str_dup(UNIT_CFG_INITRD);
     118        CAST_CFG(cfg_init)->path = str_dup(INITRD_CFG_PATH);
    75119       
    76         tgt_default = unit_create(UNIT_TARGET);
    77         if (tgt_default == NULL) {
    78                 result = ENOMEM;
     120        tgt_init = unit_create(UNIT_TARGET);
     121        if (tgt_init == NULL) {
     122                rc = ENOMEM;
    79123                goto fail;
    80124        }
    81         tgt_default->name = str_dup("default.tgt");
     125        tgt_init->name = str_dup(TARGET_INIT);
    82126       
    83127
     
    89133        configuration_add_unit(mnt_initrd);
    90134        configuration_add_unit(cfg_init);
    91         configuration_add_unit(tgt_default);
    92 
    93         result = dep_add_dependency(tgt_default, cfg_init);
    94         if (result != EOK) {
    95                 goto fail;
    96         }
    97 
    98         result = dep_add_dependency(cfg_init, mnt_initrd);
    99         if (result != EOK) {
    100                 goto fail;
     135        configuration_add_unit(tgt_init);
     136
     137        rc = dep_add_dependency(tgt_init, cfg_init);
     138        if (rc != EOK) {
     139                goto rollback;
     140        }
     141
     142        rc = dep_add_dependency(cfg_init, mnt_initrd);
     143        if (rc != EOK) {
     144                goto rollback;
    101145        }
    102146
    103147        configuration_commit();
    104148
    105         job_t *first_job = job_create(tgt_default, STATE_STARTED);
    106         if (first_job == NULL) {
    107                 goto fail;
    108         }
    109         return first_job;
     149        return EOK;
    110150
    111151fail:
    112         // TODO cannot destroy units after they're added to configuration
    113         unit_destroy(&tgt_default);
     152        unit_destroy(&tgt_init);
    114153        unit_destroy(&cfg_init);
    115154        unit_destroy(&mnt_initrd);
    116         return NULL;
    117 }
    118 
    119 static void first_job_handler(void *object, void *unused)
     155        return rc;
     156
     157rollback:
     158        configuration_rollback();
     159        return rc;
     160}
     161
     162static void sequence_job_handler(void *object, void *arg)
    120163{
    121164        job_t *job = object;
    122         sysman_log(LVL_DEBUG, "First job retval: %i.", job->retval);
     165        if (job->retval == JOB_FAILED) {
     166                sysman_log(LVL_ERROR, "Failed to start '%s'.", unit_name(job->unit));
     167                job_del_ref(&job);
     168                return;
     169        }
    123170        job_del_ref(&job);
     171       
     172        const char **target_name_ptr = arg;
     173        prepare_and_run_job(target_name_ptr + 1);
     174}
     175
     176static void prepare_and_run_job(const char **target_name_ptr)
     177{
     178        const char *target_name = *target_name_ptr;
     179
     180        if (target_name == NULL) {
     181                sysman_log(LVL_NOTE, "All initial units started.");
     182                return;
     183        }
     184
     185        /* Previous targets should have loaded new units */
     186        unit_t *tgt = configuration_find_unit_by_name(target_name);
     187        if (tgt == NULL) {
     188                sysman_log(LVL_ERROR,
     189                    "Expected unit '%s' not found in configuration.",
     190                    target_name);
     191                return;
     192        }
     193
     194        int rc = sysman_queue_job(tgt, STATE_STARTED, &sequence_job_handler,
     195            target_name_ptr);
     196
     197        if (rc != EOK) {
     198                sysman_log(LVL_FATAL, "Cannot create job for '%s'.", target_name);
     199        }
    124200}
    125201
     
    136212
    137213        /*
    138          * Create initial configuration while we are in a single fibril, keep
    139          * the job and run it when event loop is running.
    140          */
    141         job_t *first_job = create_entry_configuration();
     214         * Create initial configuration while we are in a single fibril
     215         */
     216        int rc = create_entry_configuration();
     217        if (rc != EOK) {
     218                sysman_log(LVL_FATAL,
     219                    "Could not create initial configuration (%i).", rc);
     220                return rc;
     221        }
    142222
    143223        /*
     
    148228        fibril_add_ready(event_loop_fibril);
    149229
    150         /* Queue first job for processing */
    151         job_add_ref(first_job);
    152         sysman_object_observer(first_job, &first_job_handler, NULL);
    153         job_add_ref(first_job);
    154         sysman_raise_event(&sysman_event_job_process, first_job);
    155        
    156         /*
    157          * Releasing our own reference (could be merged with previous add_ref,
    158          * this is more explicit though.
    159          */
    160         job_del_ref(&first_job);
     230        /* Queue first job from sequence */
     231        prepare_and_run_job(&target_sequence[0]);
     232
     233        /* We're service too */
     234        rc = service_register(SERVICE_SYSMAN);
     235        if (rc != EOK) {
     236                sysman_log(LVL_FATAL,
     237                    "Cannot register at naming service (%i).", rc);
     238                return rc;
     239        }
    161240
    162241        /* Start sysman server */
Note: See TracChangeset for help on using the changeset viewer.