Skip to content
Snippets Groups Projects
Commit 5de82493 authored by Eric Vidal's avatar Eric Vidal :speech_balloon:
Browse files

allow to pass key=value from init.conf file as kernel line parameter

parent 36e4593b
No related branches found
No related tags found
No related merge requests found
...@@ -90,7 +90,7 @@ In the unusual event that any of the above processes fail, *66-boot* will try to ...@@ -90,7 +90,7 @@ In the unusual event that any of the above processes fail, *66-boot* will try to
Skeleton files are mandatory and must exist on your system to be able to boot and shutdown the machine properly. By default those files are installed at `%%skel%%`. Use the `--with-skeleton=DIR` option at compile time to change it. Skeleton files are mandatory and must exist on your system to be able to boot and shutdown the machine properly. By default those files are installed at `%%skel%%`. Use the `--with-skeleton=DIR` option at compile time to change it.
- `init` : the *66-boot* binary is not meant to be called directly or be linked to the binary directory because it takes command line options. Therefore the `init` skeleton file is used to pass any options to *66-boot. By default *66-boot* is launched with **-m** options. This file ***should be copied*** by the administrator into the binary directory of your system. - `init` : the *66-boot* binary is not meant to be called directly or be linked to the binary directory because it takes command line options. Therefore the `init` skeleton file is used to pass any options to *66-boot. By default *66-boot* is launched without options. This file ***should be copied*** by the administrator into the binary directory of your system.
- `init.conf` : this file contains a set of `key=value` pairs. ***All*** keys are mandatory where the name of the key ***must not*** be changed. This is the file available to a user to configure the boot process. By default: - `init.conf` : this file contains a set of `key=value` pairs. ***All*** keys are mandatory where the name of the key ***must not*** be changed. This is the file available to a user to configure the boot process. By default:
...@@ -112,7 +112,7 @@ Skeleton files are mandatory and must exist on your system to be able to boot an ...@@ -112,7 +112,7 @@ Skeleton files are mandatory and must exist on your system to be able to boot an
* `RESCAN=0` : forces [s6-svscan](https://skarnet.org/software/s6/s6-svscan.html) to perform a scan every *RESCAN* milliseconds. This is an overload function mostly for debugging. It should be 0 during *stage1*. It is strongly discouraged to set *RESCAN* to a positive value smaller than 500. * `RESCAN=0` : forces [s6-svscan](https://skarnet.org/software/s6/s6-svscan.html) to perform a scan every *RESCAN* milliseconds. This is an overload function mostly for debugging. It should be 0 during *stage1*. It is strongly discouraged to set *RESCAN* to a positive value smaller than 500.
* `ISHELL=%%skel%%/ishell` : an absolute path. Gets called in case *stage2* crashes. This file will try to run a *sulogin*. * `ISHELL=%%skel%%/ishell` : an absolute path. Gets called in case *stage2* crashes if define by the administrator at the `rc.init` file.
- `rc.init` : this file is called by the child of *66-boot* to process *stage2*. It invokes two commands: - `rc.init` : this file is called by the child of *66-boot* to process *stage2*. It invokes two commands:
...@@ -120,14 +120,12 @@ Skeleton files are mandatory and must exist on your system to be able to boot an ...@@ -120,14 +120,12 @@ Skeleton files are mandatory and must exist on your system to be able to boot an
* `66-dbctl -v${VERBOSITY} -l ${LIVE} -t ${TREE} -u` will bring up all `bundle` and `atomic` services inside of *TREE*. * `66-dbctl -v${VERBOSITY} -l ${LIVE} -t ${TREE} -u` will bring up all `bundle` and `atomic` services inside of *TREE*.
* If any of these two commands fail the *ISHELL* file is called to provide the means for repair. * If any of these two commands fail a warning message is sent to sdtout. It's the responsability of the administrator to call or not the `ishell` file.
- `rc.shutdown` : this file is called at shudown when the administrator requests the `shutdown`, `halt`, `poweroff` or `reboot` command. It invokes a single command: - `rc.shutdown` : this file is called at shudown when the administrator requests the `shutdown`, `halt`, `poweroff` or `reboot` command. It invokes a single command:
* `66-all -v${VERBOSITY} -l ${LIVE} -t ${TREE} -f down` to bring down all *services* for all *trees* marked as enabled. * `66-all -v${VERBOSITY} -l ${LIVE} -t ${TREE} -f down` to bring down all *services* for all *trees* marked as enabled.
* `ishell` : this file is called by `rc.init` in case *stage2* crashes. It will try to run *sulogin* to provide a means of repair.
The following skeleton files are called to execute their corresponding power related functions and are safe wrappers that accept their corresponding command options. They **should be copied or symlinked** to the binary directory of the system. The following skeleton files are called to execute their corresponding power related functions and are safe wrappers that accept their corresponding command options. They **should be copied or symlinked** to the binary directory of the system.
- `halt` : wraps [66-hpr -h](66-hpr.html). Terminates all processes and shuts down the CPU. - `halt` : wraps [66-hpr -h](66-hpr.html). Terminates all processes and shuts down the CPU.
...@@ -137,3 +135,13 @@ The following skeleton files are called to execute their corresponding power rel ...@@ -137,3 +135,13 @@ The following skeleton files are called to execute their corresponding power rel
- `reboot` : wraps [66-hpr -r](66-hpr.html). Terminates all processes and instructs a warm boot. - `reboot` : wraps [66-hpr -r](66-hpr.html). Terminates all processes and instructs a warm boot.
- `shutdown` : wraps [66-shutdown](66-shutdown.html). Like `poweroff` but also runs scripts to bring the system down in a sane way including user notification. - `shutdown` : wraps [66-shutdown](66-shutdown.html). Like `poweroff` but also runs scripts to bring the system down in a sane way including user notification.
- `ishell` : this file will try to run *sulogin* to provide a means of repair.
## Kernel command line
Any valid `key=value` pair set at the `init.conf` skeleton file can be passed on the kernel command line as parameter:
```
BOOT_IMAGE=../vmlinuz-linux root=/dev/sda3 ro vga=895 initrd=../intel-ucode.img,../initramfs-linux.img TREE=boot
```
...@@ -56,6 +56,9 @@ static char ttree[MAXENV+1] ; ...@@ -56,6 +56,9 @@ static char ttree[MAXENV+1] ;
static char confile[MAXENV+1] ; static char confile[MAXENV+1] ;
static char const *const *genv = 0 ; static char const *const *genv = 0 ;
static int fdin ; static int fdin ;
static char const *proc_cmdline="/proc/cmdline" ;
#define MAXBUF 1024*64*2
#define USAGE "66-boot [ -h ] [ -m ] [ -s skel ] [ -l log_user ] [ -e environment ] [ -d dev ] [ -b banner ]" #define USAGE "66-boot [ -h ] [ -m ] [ -s skel ] [ -l log_user ] [ -e environment ] [ -d dev ] [ -b banner ]"
...@@ -95,6 +98,67 @@ static inline void info_help (void) ...@@ -95,6 +98,67 @@ static inline void info_help (void)
if (buffer_putsflush(buffer_1, help) < 0) sulogin("","") ; if (buffer_putsflush(buffer_1, help) < 0) sulogin("","") ;
} }
static int read_line(stralloc *dst, char const *line)
{
char b[MAXBUF] ;
int fd ;
unsigned int n = 0, m = MAXBUF ;
fd = open(line, O_RDONLY) ;
if (fd == -1) return 0 ;
for(;;)
{
ssize_t r = read(fd,b+n,m-n);
if (r == -1)
{
if (errno == EINTR) continue ;
break ;
}
n += r ;
// buffer is full
if (n == m)
{
--n ;
break ;
}
// end of file
if (r == 0) break ;
}
close(fd) ;
if(n)
{
int i = n ;
// remove trailing zeroes
while (i && b[i-1] == '\0') --i ;
while (i--)
if (b[i] == '\n' || b[i] == '\0') b[i] = ' ' ;
if (b[n-1] == ' ') b[n-1] = '\0' ;
}
b[n] = '\0';
if (!stralloc_cats(dst,b) ||
!stralloc_0(dst)) sulogin("close stralloc",dst->s) ;
return n ;
}
static int get_value(stralloc *val,char const *key)
{
if (!environ_get_val_of_key(val,key)) return 0 ;
/** value may be empty, in this case we use the default one */
if (!sastr_clean_element(val))
{
log_warnu("get value of: ",key," -- keeps the default") ;
return 0 ;
}
if (!sastr_rebuild_in_oneline(val)) sulogin("rebuild line of value: ",val->s) ;
if (!stralloc_0(val)) sulogin("append stralloc of value: ",val->s) ;
return 1 ;
}
static void parse_conf(void) static void parse_conf(void)
{ {
static char const *valid[] = static char const *valid[] =
...@@ -102,6 +166,7 @@ static void parse_conf(void) ...@@ -102,6 +166,7 @@ static void parse_conf(void)
int r ; int r ;
unsigned int j = 0 ; unsigned int j = 0 ;
stralloc src = STRALLOC_ZERO ; stralloc src = STRALLOC_ZERO ;
stralloc cmdline = STRALLOC_ZERO ;
stralloc val = STRALLOC_ZERO ; stralloc val = STRALLOC_ZERO ;
if (skel[0] != '/') sulogin("skeleton directory must be an aboslute path: ",skel) ; if (skel[0] != '/') sulogin("skeleton directory must be an aboslute path: ",skel) ;
size_t skelen = strlen(skel) ; size_t skelen = strlen(skel) ;
...@@ -110,22 +175,38 @@ static void parse_conf(void) ...@@ -110,22 +175,38 @@ static void parse_conf(void)
memcpy(confile + skelen + 1, SS_BOOT_CONF, SS_BOOT_CONF_LEN) ; memcpy(confile + skelen + 1, SS_BOOT_CONF, SS_BOOT_CONF_LEN) ;
confile[skelen + 1 + SS_BOOT_CONF_LEN] = 0 ; confile[skelen + 1 + SS_BOOT_CONF_LEN] = 0 ;
size_t filesize=file_get_size(confile) ; size_t filesize=file_get_size(confile) ;
/** skeleton file */
r = openreadfileclose(confile,&src,filesize) ; r = openreadfileclose(confile,&src,filesize) ;
if(!r) sulogin("open configuration file: ",confile) ; if(!r) sulogin("open configuration file: ",confile) ;
if (!stralloc_0(&src)) sulogin("append stralloc of file: ",confile) ; if (!stralloc_0(&src)) sulogin("append stralloc of file: ",confile) ;
/** /proc/cmdline */
if (!read_line(&cmdline,proc_cmdline)) {
/** we don't want to die here */
log_warnu("read: ",proc_cmdline) ;
cmdline.len = 0 ;
}
if (!sastr_split_element_in_nline(&cmdline)) {
log_warnu("split: ",proc_cmdline) ;
cmdline.len = 0 ;
}
for (char const *const *p = valid;*p;p++,j++) for (char const *const *p = valid;*p;p++,j++)
{ {
if (!stralloc_copy(&val,&src)) sulogin("copy stralloc of file: ",confile) ; /** try first to read from /proc/cmdline.
if (!environ_get_val_of_key(&val,*p)) continue ; * If the key is not found, try to read the skeleton file.
/** value may be empty, in this case we use the default one */ * Finally keep the default value if we cannot get a correct
if (!sastr_clean_element(&val)) * key=value pair */
{ if (cmdline.len > 0) {
log_warnu("get value of: ",*p," -- keeps the default") ; if (!stralloc_copy(&val,&cmdline)) sulogin("copy stralloc of file: ",proc_cmdline) ;
continue ; }
else if (!stralloc_copy(&val,&src)) sulogin("copy stralloc of file: ",confile) ;
if (!get_value(&val,*p) && cmdline.len > 0)
{
if (!stralloc_copy(&val,&src)) sulogin("copy stralloc of file: ",confile) ;
if (!get_value(&val,*p)) continue ;
} }
if (!sastr_rebuild_in_oneline(&val)) sulogin("rebuild line of value: ",val.s) ; else continue ;
if (!stralloc_0(&val)) sulogin("append stralloc of value: ",val.s) ;
switch (j) switch (j)
{ {
...@@ -156,6 +237,7 @@ static void parse_conf(void) ...@@ -156,6 +237,7 @@ static void parse_conf(void)
} }
stralloc_free(&val) ; stralloc_free(&val) ;
stralloc_free(&cmdline) ;
stralloc_free(&src) ; stralloc_free(&src) ;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment