source: mainline/uspace/srv/sysman/units/unit_mnt.c@ e8747bd8

Last change on this file since e8747bd8 was 3f05ef7, checked in by Matthieu Riolo <matthieu.riolo@…>, 6 years ago

sysman: Catch debug log output to file (temporary version)

  • Property mode set to 100644
File size: 6.6 KB
Line 
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
29#include <assert.h>
30#include <errno.h>
31#include <fibril_synch.h>
32#include <stdlib.h>
33#include <vfs/vfs.h>
34#include <str.h>
35
36#include "log.h"
37#include "sysman.h"
38#include "unit.h"
39
40static const char *section_name = "Mount";
41
42static config_item_t unit_configuration[] = {
43 {"What", &config_parse_string, offsetof(unit_mnt_t, device), NULL},
44 {"Where", &config_parse_string, offsetof(unit_mnt_t, mountpoint), NULL},
45 {"Type", &config_parse_string, offsetof(unit_mnt_t, type), NULL},
46 {"Autostart", &config_parse_bool, offsetof(unit_mnt_t, autostart), "true"},
47 {"Blocking", &config_parse_bool, offsetof(unit_mnt_t, blocking), "true"},
48 CONFIGURATION_ITEM_SENTINEL
49};
50
51typedef struct {
52 char *type;
53 char *mountpoint;
54 char *device;
55 char *options;
56 unsigned int flags;
57 unsigned int instance;
58
59 unit_t *unit;
60 bool owner;
61} mount_data_t;
62
63static void mount_data_destroy(mount_data_t **mnt_data_ptr)
64{
65 assert(mnt_data_ptr);
66 if (*mnt_data_ptr == NULL) {
67 return;
68 }
69
70 mount_data_t *mnt_data = *mnt_data_ptr;
71 free(mnt_data->type);
72 free(mnt_data->mountpoint);
73 free(mnt_data->device);
74 free(mnt_data->options);
75
76 free(mnt_data);
77 *mnt_data_ptr = NULL;
78}
79
80static bool mount_data_copy(mount_data_t *src, mount_data_t **dst_ptr)
81{
82 mount_data_t *dst = malloc(sizeof(mount_data_t));
83 if (dst == NULL) {
84 goto fail;
85 }
86
87 dst->type = str_dup(src->type);
88 if (dst->type == NULL)
89 goto fail;
90
91 dst->mountpoint = str_dup(src->mountpoint);
92 if (dst->mountpoint == NULL)
93 goto fail;
94
95 dst->device = str_dup(src->device);
96 if (dst->device == NULL)
97 goto fail;
98
99 dst->options = src->options ? str_dup(src->options) : NULL;
100 if (src->options != NULL && dst->options == NULL)
101 goto fail;
102
103 dst->flags = src->flags;
104 dst->instance = src->instance;
105 dst->unit = src->unit;
106 dst->owner = true;
107
108 *dst_ptr = dst;
109 return true;
110
111fail:
112 mount_data_destroy(&dst);
113 return false;
114}
115
116static void unit_mnt_init(unit_t *unit)
117{
118 unit_mnt_t *u_mnt = CAST_MNT(unit);
119 assert(u_mnt);
120}
121
122static void unit_mnt_destroy(unit_t *unit)
123{
124 assert(unit->type == UNIT_MOUNT);
125 unit_mnt_t *u_mnt = CAST_MNT(unit);
126
127 free(u_mnt->type);
128 free(u_mnt->mountpoint);
129 free(u_mnt->device);
130}
131
132static int unit_mnt_load(unit_t *unit, ini_configuration_t *ini_conf,
133 text_parse_t *text_parse)
134{
135 unit_mnt_t *u_mnt = CAST_MNT(unit);
136 assert(u_mnt);
137
138 ini_section_t *section = ini_get_section(ini_conf, section_name);
139 if (section == NULL) {
140 sysman_log(LVL_ERROR,
141 "Expected section '%s' in configuration of unit '%s'",
142 section_name, unit_name(unit));
143 return ENOENT;
144 }
145
146 return config_load_ini_section(unit_configuration, section, u_mnt,
147 text_parse);
148}
149
150static int mount_exec(void *arg)
151{
152 mount_data_t *mnt_data = arg;
153 sysman_log(LVL_DEBUG2, "%s(%p, %p, %p, %p, %x, %u)",
154 __func__,
155 mnt_data->type, mnt_data->mountpoint, mnt_data->device, mnt_data->options,
156 mnt_data->flags, mnt_data->instance);
157
158 int rc = mount(mnt_data->type, mnt_data->mountpoint, mnt_data->device,
159 mnt_data->options ? mnt_data->options : "",
160 mnt_data->flags, mnt_data->instance);
161
162 if (rc == EOK) {
163 sysman_log(LVL_DEBUG, "Mount ('%s') mounted",
164 unit_name(mnt_data->unit));
165 /*
166 * Emulate future VFS broker fibril that notifies about created
167 * exposee.
168 * Difference: It'll notify exposee name only, we'll have to
169 * match it...
170 */
171 sysman_raise_event(&sysman_event_unit_exposee_created,
172 mnt_data->unit);
173 } else {
174 sysman_log(LVL_ERROR, "Mount ('%s') failed (%i)",
175 unit_name(mnt_data->unit), rc);
176 /*
177 * Think about analogy of this event, probably timeout or sthing
178 */
179 sysman_raise_event(&sysman_event_unit_failed,
180 mnt_data->unit);
181 }
182
183 if (mnt_data->owner) {
184 mount_data_destroy(&mnt_data);
185 }
186
187 return EOK;
188}
189
190static int unit_mnt_start(unit_t *unit)
191{
192 unit_mnt_t *u_mnt = CAST_MNT(unit);
193 assert(u_mnt);
194 /* autostart implies blocking */
195 assert(!u_mnt->autostart || u_mnt->blocking);
196
197
198 // TODO think about unit's lifecycle (is STOPPED only acceptable?)
199 assert(unit->state == STATE_STOPPED);
200
201 mount_data_t mnt_data;
202 memset(&mnt_data, 0, sizeof(mnt_data));
203 mnt_data.type = u_mnt->type;
204 mnt_data.mountpoint = u_mnt->mountpoint;
205 mnt_data.device = u_mnt->device;
206 /* TODO use other mount parameters
207 * mnt_data.options = u_mnt->options;
208 * mnt_data.instance = u_mnt->instance;
209 */
210
211 mnt_data.flags |= u_mnt->blocking ? IPC_FLAG_BLOCKING : 0;
212 mnt_data.flags |= u_mnt->autostart ? IPC_FLAG_AUTOSTART : 0;
213 mnt_data.unit = unit;
214
215 if (u_mnt->blocking) {
216 mount_data_t *heap_mnt_data = NULL;
217 if (!mount_data_copy(&mnt_data, &heap_mnt_data)) {
218 return ENOMEM;
219 }
220 fid_t fib = fibril_create(&mount_exec, heap_mnt_data);
221 unit->state = STATE_STARTING;
222 fibril_add_ready(fib);
223 } else {
224 unit->state = STATE_STARTING;
225 mount_exec(&mnt_data);
226 }
227
228 return EOK;
229}
230
231static void unit_mnt_exposee_created(unit_t *unit)
232{
233 assert(CAST_MNT(unit));
234 assert(unit->state == STATE_STOPPED || unit->state == STATE_STARTING);
235
236 if (str_cmp(unit_name(unit), "rootfs.mnt") == 0) {
237 sysman_log_tofile();
238 }
239 unit->state = STATE_STARTED;
240 unit_notify_state(unit);
241}
242
243static void unit_mnt_fail(unit_t *unit)
244{
245 assert(CAST_MNT(unit));
246 assert(unit->state == STATE_STARTING);
247
248 unit->state = STATE_FAILED;
249 unit_notify_state(unit);
250}
251
252
253DEFINE_UNIT_VMT(unit_mnt)
254
Note: See TracBrowser for help on using the repository browser.