FreeBSD kernel kern code
subr_boot.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
5 * All Rights Reserved.
6 * Copyright (c) 1998 Robert Nordier
7 * All Rights Reserved.
8 * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
9 * All rights reserved.
10 * Copyright (c) 2014 Roger Pau Monné <roger.pau@citrix.com>
11 * All Rights Reserved.
12 * Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org>
13 * Copyright (c) 2018 Netflix, Inc.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer
20 * in this position and unchanged.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD$");
40
41/* Note: This is compiled in both the kernel and boot loader contexts */
42
43#include <sys/param.h>
44#ifdef _KERNEL
45#include <sys/systm.h>
46#else
47#include <stand.h>
48#endif
49#include <sys/reboot.h>
50#include <sys/boot.h>
51
52#ifdef _KERNEL
53#define SETENV(k, v) kern_setenv(k, v)
54#define GETENV(k) kern_getenv(k)
55#define FREE(v) freeenv(v)
56#else /* Boot loader */
57#define SETENV(k, v) setenv(k, v, 1)
58#define GETENV(k) getenv(k)
59#define FREE(v)
60#endif
61
62static struct
63{
64 const char *ev;
65 int mask;
66} howto_names[] = {
67 { "boot_askname", RB_ASKNAME},
68 { "boot_cdrom", RB_CDROM},
69 { "boot_ddb", RB_KDB},
70 { "boot_dfltroot", RB_DFLTROOT},
71 { "boot_gdb", RB_GDB},
72 { "boot_multicons", RB_MULTIPLE},
73 { "boot_mute", RB_MUTE},
74 { "boot_pause", RB_PAUSE},
75 { "boot_serial", RB_SERIAL},
76 { "boot_single", RB_SINGLE},
77 { "boot_verbose", RB_VERBOSE},
78 { NULL, 0}
79};
80
81/*
82 * In the boot environment, we often parse a command line and have to throw away
83 * its contents. As we do so, we set environment variables that correspond to
84 * the flags we encounter. Later, to get a howto mask, we grovel through these
85 * to reconstruct it. This also allows users in their loader.conf to set them
86 * and have the kernel see them.
87 */
88
92int
94{
95 int i, howto;
96 char *val;
97
98 for (howto = 0, i = 0; howto_names[i].ev != NULL; i++) {
99 val = GETENV(howto_names[i].ev);
100 if (val != NULL && strcasecmp(val, "no") != 0)
101 howto |= howto_names[i].mask;
102 FREE(val);
103 }
104 return (howto);
105}
106
110void
112{
113 int i;
114
115 for (i = 0; howto_names[i].ev != NULL; i++)
116 if (howto & howto_names[i].mask)
117 SETENV(howto_names[i].ev, "YES");
118}
119
127int
129{
130 char *n;
131 int howto;
132
133#if 0
134/* Need to see if this is better or worse than the meat of the #else */
135static const char howto_switches[] = "aCdrgDmphsv";
136static int howto_masks[] = {
137 RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE,
138 RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE
139};
140
141 opts = strchr(kargs, '-');
142 while (opts != NULL) {
143 while (*(++opts) != '\0') {
144 sw = strchr(howto_switches, *opts);
145 if (sw == NULL)
146 break;
147 howto |= howto_masks[sw - howto_switches];
148 }
149 opts = strchr(opts, '-');
150 }
151#else
152 howto = 0;
153 if (*v == '-') {
154 while (*v != '\0') {
155 v++;
156 switch (*v) {
157 case 'a': howto |= RB_ASKNAME; break;
158 case 'C': howto |= RB_CDROM; break;
159 case 'd': howto |= RB_KDB; break;
160 case 'D': howto |= RB_MULTIPLE; break;
161 case 'm': howto |= RB_MUTE; break;
162 case 'g': howto |= RB_GDB; break;
163 case 'h': howto |= RB_SERIAL; break;
164 case 'p': howto |= RB_PAUSE; break;
165 case 'P': howto |= RB_PROBE; break;
166 case 'r': howto |= RB_DFLTROOT; break;
167 case 's': howto |= RB_SINGLE; break;
168 case 'S': SETENV("comconsole_speed", v + 1); v += strlen(v); break;
169 case 'v': howto |= RB_VERBOSE; break;
170 }
171 }
172 } else {
173 n = strsep(&v, "=");
174 if (v == NULL)
175 SETENV(n, "1");
176 else
177 SETENV(n, v);
178 }
179#endif
180 return (howto);
181}
182
186int
187boot_parse_cmdline_delim(char *cmdline, const char *delim)
188{
189 char *v;
190 int howto;
191
192 howto = 0;
193 while ((v = strsep(&cmdline, delim)) != NULL) {
194 if (*v == '\0')
195 continue;
196 howto |= boot_parse_arg(v);
197 }
198 return (howto);
199}
200
204int
205boot_parse_cmdline(char *cmdline)
206{
207
208 return (boot_parse_cmdline_delim(cmdline, " \t\n"));
209}
210
214int
215boot_parse_args(int argc, char *argv[])
216{
217 int i, howto;
218
219 howto = 0;
220 for (i = 1; i < argc; i++)
221 howto |= boot_parse_arg(argv[i]);
222 return (howto);
223}
#define SETENV(k, v)
Definition: subr_boot.c:53
int boot_parse_cmdline_delim(char *cmdline, const char *delim)
breakup the command line into args, and pass to boot_parse_arg
Definition: subr_boot.c:187
void boot_howto_to_env(int howto)
Set env vars from howto_names based on howto passed in.
Definition: subr_boot.c:111
int boot_parse_arg(char *v)
Helper routine to parse a single arg and return its mask.
Definition: subr_boot.c:128
int boot_env_to_howto(void)
convert the env vars in howto_names into a howto mask
Definition: subr_boot.c:93
static struct @9 howto_names[]
#define FREE(v)
Definition: subr_boot.c:55
#define GETENV(k)
Definition: subr_boot.c:54
__FBSDID("$FreeBSD$")
int boot_parse_args(int argc, char *argv[])
Pass a vector of strings to boot_parse_arg.
Definition: subr_boot.c:215
int mask
Definition: subr_boot.c:65
int boot_parse_cmdline(char *cmdline)
Simplified interface for common 'space or tab separated' args.
Definition: subr_boot.c:205
const char * ev
Definition: subr_boot.c:64