source: mainline/uspace/srv/sysman/main.c@ c1b2084

Last change on this file since c1b2084 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: 6.2 KB
RevLine 
[09a8006]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
[f42ee6f]29#include <async.h>
30#include <errno.h>
31#include <fibril.h>
[5559712]32#include <ipc/sysman.h>
33#include <macros.h>
34#include <ns.h>
[f42ee6f]35#include <stddef.h>
36#include <stdio.h>
[6efec7e3]37#include <str.h>
[f42ee6f]38
39#include "configuration.h"
[5559712]40#include "connection_broker.h"
41#include "connection_ctl.h"
[f42ee6f]42#include "dep.h"
[694253c]43#include "job.h"
[3f7e1f24]44#include "log.h"
[f42ee6f]45#include "sysman.h"
46#include "unit.h"
47
48#define NAME "sysman"
49
[5559712]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)
[f42ee6f]78{
[5559712]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 }
[f42ee6f]91}
92
[3f7e1f24]93/** Build hard coded configuration */
[5559712]94static int create_entry_configuration(void) {
95 int rc;
[f42ee6f]96 unit_t *mnt_initrd = NULL;
97 unit_t *cfg_init = NULL;
[5559712]98 unit_t *tgt_init = NULL;
[f42ee6f]99
100 mnt_initrd = unit_create(UNIT_MOUNT);
101 if (mnt_initrd == NULL) {
[5559712]102 rc = ENOMEM;
[f42ee6f]103 goto fail;
104 }
[5559712]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;
[f42ee6f]111
112 cfg_init = unit_create(UNIT_CONFIGURATION);
113 if (cfg_init == NULL) {
[5559712]114 rc = ENOMEM;
[f42ee6f]115 goto fail;
116 }
[5559712]117 cfg_init->name = str_dup(UNIT_CFG_INITRD);
118 CAST_CFG(cfg_init)->path = str_dup(INITRD_CFG_PATH);
[f42ee6f]119
[5559712]120 tgt_init = unit_create(UNIT_TARGET);
121 if (tgt_init == NULL) {
122 rc = ENOMEM;
[f42ee6f]123 goto fail;
124 }
[5559712]125 tgt_init->name = str_dup(TARGET_INIT);
[f42ee6f]126
127
128 /*
129 * Add units to configuration and start the default target.
130 */
[bb154c6]131 configuration_start_update();
132
[f42ee6f]133 configuration_add_unit(mnt_initrd);
134 configuration_add_unit(cfg_init);
[5559712]135 configuration_add_unit(tgt_init);
[f42ee6f]136
[5559712]137 rc = dep_add_dependency(tgt_init, cfg_init);
138 if (rc != EOK) {
139 goto rollback;
[f42ee6f]140 }
141
[5559712]142 rc = dep_add_dependency(cfg_init, mnt_initrd);
143 if (rc != EOK) {
144 goto rollback;
[f42ee6f]145 }
146
147 configuration_commit();
148
[5559712]149 return EOK;
[f42ee6f]150
151fail:
[5559712]152 unit_destroy(&tgt_init);
[f42ee6f]153 unit_destroy(&cfg_init);
154 unit_destroy(&mnt_initrd);
[5559712]155 return rc;
156
157rollback:
158 configuration_rollback();
159 return rc;
[3f7e1f24]160}
161
[5559712]162static void sequence_job_handler(void *object, void *arg)
[3f7e1f24]163{
164 job_t *job = object;
[5559712]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 }
[3f7e1f24]170 job_del_ref(&job);
[5559712]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 }
[f42ee6f]200}
201
202int main(int argc, char *argv[])
203{
204 printf(NAME ": HelenOS system daemon\n");
205
[3f7e1f24]206 /*
207 * Initialize global structures
208 */
[f42ee6f]209 configuration_init();
[3f7e1f24]210 sysman_events_init();
[694253c]211 job_queue_init();
[f42ee6f]212
213 /*
[5559712]214 * Create initial configuration while we are in a single fibril
[f42ee6f]215 */
[5559712]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 }
[3f7e1f24]222
223 /*
224 * Event loop runs in separate fibril, all consequent access to global
225 * structure is made from this fibril only.
226 */
227 fid_t event_loop_fibril = fibril_create(sysman_events_loop, NULL);
228 fibril_add_ready(event_loop_fibril);
229
[5559712]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 }
[f42ee6f]240
[3f7e1f24]241 /* Start sysman server */
[f42ee6f]242 async_set_client_connection(sysman_connection);
243
244 printf(NAME ": Accepting connections\n");
245 async_manager();
246
[3f7e1f24]247 /* not reached */
[f42ee6f]248 return 0;
249}
Note: See TracBrowser for help on using the repository browser.