[PATCH] [UPDATED]user-specified config file on Yaboot's prompt

Leonardo Rangel lrangel at linux.vnet.ibm.com
Thu Apr 5 07:06:31 EST 2007


Hi all,

here is a new patch to replace this old one. With this new patch, the  
user is able to specify the config file name, and device and partition  
in which it is stored on. He can do it all on Yaboot's prompt, so he  
doesn't need to enter open firmware's command line. One more important  
thing is that he doesn't need to specify all these armuments at once.  
He can just pass one, two or all of them, by just typing:

conf file=blah
conf dev=bleh file=blah
conf part=blih file=blah dev=bleh

Paulo and me worked on this new patch and we guess it overcome the two  
previous patches, (conf arg on OF prompt and conf arg on yaboot's  
prompt (first version)) since allows the user to recover from problems  
on loading config file

running "conf" with no parameters show the current configuration for  
device, partition and config file

If yaboot fails on loading the new file, it recovers the default  
values, used before "conf" call.

please feel free to suggest more improvements,

Kind regards

Leo and Paulo

diff --git a/second/cfg.c b/second/cfg.c
index 4167582..970323f 100644
--- a/second/cfg.c
+++ b/second/cfg.c
@@ -350,6 +350,30 @@ static void check_for_obsolete(const char *label)
     }
  }

+static int cfg_reset ()
+{
+    CONFIG *walk;
+#if DEBUG
+    prom_printf("Resetting image table\n");
+#endif
+    line_num = 0;
+    images = NULL;
+    curr_table = NULL;
+    curr_table = cf_options;
+    for (walk = curr_table; walk->type != cft_end; walk++) {
+#if DEBUG
+        prom_printf("ItemA %s = %s\n", walk->name, walk->data);
+#endif
+        if (walk->data != NULL)
+            walk->data = NULL;
+#if DEBUG
+        prom_printf("ItemB %s = %s\n\n", walk->name, walk->data);
+#endif
+    }
+
+    return 0;
+}
+
  static int cfg_set (char *item, char *value)
  {
       CONFIG *walk;
@@ -429,6 +453,8 @@ int cfg_parse (char *cfg_file, char *buff, int len)
       currp = buff;
       endp = currp + len;

+     cfg_reset();
+
       if (setjmp (env))
       return -1;
       while (1) {
diff --git a/second/yaboot.c b/second/yaboot.c
index 3fbb103..d8d718c 100644
--- a/second/yaboot.c
+++ b/second/yaboot.c
@@ -345,9 +345,12 @@ load_config_file(struct boot_fspec_t *orig_fspec)
       else
       conf_path[0] = 0;
       if (fspec.file && *fspec.file)
-     strcat(conf_path, fspec.file);
+      if (!strncmp (fspec.file, "/", 1))
+       strcpy(conf_path, fspec.file);
+      else
+       strcat(conf_path, fspec.file);
       else
-     strcat(conf_path, CONFIG_FILE_NAME);
+      strcat(conf_path, CONFIG_FILE_NAME);

       /* Open it */
       fspec.file = conf_path;
@@ -706,6 +709,7 @@ int get_params(struct boot_param_t* params)
  {
       int defpart;
       char *defdevice = 0;
+     char defdevice_bak[1024];
       char *p, *q, *endp;
       int c, n;
       char *imagename = 0, *label;
@@ -801,6 +805,8 @@ int get_params(struct boot_param_t* params)
       label = 0;
       defdevice = boot.dev;

+     strcpy(defdevice_bak,defdevice);
+
       if (useconf) {
       defdevice = cfg_get_strg(0, "device");
       p = cfg_get_strg(0, "partition");
@@ -874,6 +880,91 @@ int get_params(struct boot_param_t* params)
       return 1;
       }

+     if (!strncmp (imagename, "conf", 4)) {
+
+         // imagename = "conf file=blah dev=bleh part=blih"
+         DEBUG_F("Loading user-specified config file: %s\n",imagename);
+         if (password) {
+             check_password ("Restricted command.");
+             return 1;
+         }
+
+         // args= "file=blah dev=bleh part=blih"
+         char *args = params->args;
+
+         if (strlen(args)){
+
+            // set a pointer to the first space in args
+            char *space = strchr(args,' ');
+
+            int loop = 3;
+            while (loop > 0){
+                char temp[1024] = "0";
+
+                // copy next argument to temp
+                strncpy(temp, args, space-args);
+
+                // parse temp and set boot arguments
+                if (!strncmp (temp, "file=", 5)){
+                   DEBUG_F("conf file: %s\n", temp+5);
+                   strcpy(boot.file, temp+5);
+                } else if (!strncmp (temp, "device=", 7)){
+                   DEBUG_F("conf device: %s\n", temp+7);
+                   strcpy(boot.dev, temp+7);
+                } else if (!strncmp (temp, "partition=", 10)){
+                   DEBUG_F("conf partition: %s\n", temp+10);
+                   boot.part=simple_strtol(temp+10,NULL,10);
+                } else
+                   space = NULL;
+
+                // set the pointer to the next space in args;
+                // set the loop control variable
+                if (strlen(space)>1){
+                    // Go to the next argument
+                    args = space+1;
+
+                    loop--;
+                    if (strchr(args,' ') == NULL)
+                        space = &args[strlen(args)];
+                    else
+                        space = strchr(args,' ');
+                } else {
+                    loop = -1;
+                    space = NULL;
+                }
+            }
+
+            prom_printf("Loading config file...\n");
+            useconf = load_config_file(&boot);
+            if (useconf > 0){
+                if ((q = cfg_get_strg(0, "timeout")) != 0 && *q != 0)
+                   timeout = simple_strtol(q, NULL, 0);
+            } else {
+               prom_printf("Restoring default values.\n");
+               strcpy(boot.file,"");
+               strcpy(boot.dev, defdevice_bak);
+               boot.part = defpart;
+            }
+         } else {
+             prom_printf("Current configuration:\n");
+             prom_printf("device: %s\n", boot.dev);
+             if (boot.part < 0)
+                 prom_printf("partition: auto\n");
+             else
+                 prom_printf("partition: %d\n", boot.part);
+             if (strlen(boot.file))
+                 prom_printf("file: %s\n", boot.file);
+             else
+                 prom_printf("file: /etc/%s\n",CONFIG_FILE_NAME);
+         }
+
+         imagename = "\0";
+         params->args = "\0";
+
+         return 0;
+     }
+
       if (imagename[0] == '$') {
       /* forth command string */
       if (password)


==== end patch =====




Quoting Leonardo Rangel <lrangel at linux.vnet.ibm.com>:

> Hi all,
>
> In addition to the confarg patch Paulo has just sent, we worked on a way
> to specify the config file on Yaboot's prompt.
>
> With this patch, the user can simply type "conf=/etc/yaboot2.conf" or
> "conf=yaboot2.conf" (/etc is assumed as default location), on Yaboot's
> prompt (not in the Open Firmware's prompt), to load a new config file.
>
> Doing so, if Yaboot fails on loading a config file (that one
> specified as a conf argument on Open Firmware's prompt - our previous patch;
> or /etc/yaboot.conf if no OF argument is passed on), the user is able to
> load a new config file. The user can also run this to override the default
> options even when a default config file is successfully loaded.
>
> load_config_file has a known issue. It currently doesn't look into other
> partitions for config files, just that one which contains the root
> filesystem. This patch doesn't solves this. We're constrained to the
> same partition as well.
>
> One important point: before loading the new file, we clean the previous
> configurations.
>
> We had a problem setting up timeout parameter. We haven't found a way
> to restart timer when loading a new config file. I think it's not important
> here... Since user is already interacting with the boot loader, I guess
> he doesn't expect to wait for the timer to run out to boot up the system
> :o)
>
> Oh, I've also replaced all "exit" calls inside util/addnote.c to
> "return" calls. It was causing some compilation warnings. I believe there
> are no impacts on doing that :-)
>
> Kind regards,
>
> Leo
>
>
> diff --git a/second/cfg.c b/second/cfg.c
> index 4167582..a500216 100644
> --- a/second/cfg.c
> +++ b/second/cfg.c
> @@ -350,6 +350,30 @@ static void check_for_obsolete(const char *label)
>     }
>  }
>
> +static int cfg_reset ()
> +{
> +    CONFIG *walk;
> +#if DEBUG
> +    prom_printf("Resetting image table\n");
> +#endif
> +    line_num = 0;
> +    images = NULL;
> +    curr_table = NULL;
> +    curr_table = cf_options;
> +    for (walk = curr_table; walk->type != cft_end; walk++) {
> +#if DEBUG
> +        prom_printf("ItemA %s = %s\n", walk->name, walk->data);
> +#endif
> +        if (walk->data != NULL)
> +            walk->data = NULL;
> +#if DEBUG
> +        prom_printf("ItemB %s = %s\n\n", walk->name, walk->data);
> +#endif
> +    }
> +
> +    return 0;
> +}
> +
>  static int cfg_set (char *item, char *value)
>  {
>       CONFIG *walk;
> @@ -429,6 +453,8 @@ int cfg_parse (char *cfg_file, char *buff, int len)
>       currp = buff;
>       endp = currp + len;
>
> +     cfg_reset();
> +
>       if (setjmp (env))
>       return -1;
>       while (1) {
> diff --git a/second/yaboot.c b/second/yaboot.c
> index 3fbb103..7012f66 100644
> --- a/second/yaboot.c
> +++ b/second/yaboot.c
> @@ -345,9 +345,12 @@ load_config_file(struct boot_fspec_t *orig_fspec)
>       else
>       conf_path[0] = 0;
>       if (fspec.file && *fspec.file)
> -     strcat(conf_path, fspec.file);
> +      if (!strncmp (fspec.file, "/", 1))
> +       strcpy(conf_path, fspec.file);
> +      else
> +       strcat(conf_path, fspec.file);
>       else
> -     strcat(conf_path, CONFIG_FILE_NAME);
> +      strcat(conf_path, CONFIG_FILE_NAME);
>
>       /* Open it */
>       fspec.file = conf_path;
> @@ -874,6 +877,24 @@ int get_params(struct boot_param_t* params)
>       return 1;
>       }
>
> +     if (!strncmp (imagename, "conf", 4)) {
> +         DEBUG_F("Loading user-specified config file: %s\n",imagename);
> +         if (password) {
> +             check_password ("Restricted command.");
> +             return 1;
> +         }
> +         strcpy(boot.file, imagename+5);
> +         if (strlen(boot.file)){
> +             useconf = load_config_file(&boot);
> +             DEBUG_F("Config file loaded\n");
> +             if (useconf && (q = cfg_get_strg(0, "timeout")) != 0   
> && *q != 0)
> +                 timeout = simple_strtol(q, NULL, 0);
> +         } else {
> +             DEBUG_F("empty config file name\n");
> +         }
> +         return 0;
> +     }
> +
>       if (imagename[0] == '$') {
>       /* forth command string */
>       if (password)
> diff --git a/util/addnote.c b/util/addnote.c
> index 351c4fc..56de0c7 100644
> --- a/util/addnote.c
> +++ b/util/addnote.c
> @@ -105,12 +105,12 @@ main(int ac, char **av)
>
>       if (ac != 2) {
>       fprintf(stderr, "Usage: %s elf-file\n", av[0]);
> -     exit(1);
> +     return(1);
>       }
>       fd = open(av[1], O_RDWR);
>       if (fd < 0) {
>       perror(av[1]);
> -     exit(1);
> +     return(1);
>       }
>
>       nnote = 12 + ROUNDUP(strlen(arch) + 1) + sizeof(descr);
> @@ -119,7 +119,7 @@ main(int ac, char **av)
>       n = read(fd, buf, sizeof(buf));
>       if (n < 0) {
>       perror("read");
> -     exit(1);
> +     return(1);
>       }
>
>       if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0)
> @@ -129,7 +129,7 @@ main(int ac, char **av)
>      || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) {
>       fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n",
>           av[1]);
> -     exit(1);
> +     return(1);
>       }
>
>       ph = GET_32BE(E_PHOFF);
> @@ -144,7 +144,7 @@ main(int ac, char **av)
>       if (GET_32BE(ph + PH_TYPE) == PT_NOTE) {
>            fprintf(stderr, "%s already has a note entry\n",
>                av[1]);
> -          exit(0);
> +          return(0);
>       }
>       ph += ps;
>       }
> @@ -193,23 +193,23 @@ main(int ac, char **av)
>       i = write(fd, buf, n);
>       if (i < 0) {
>       perror("write");
> -     exit(1);
> +     return(1);
>       }
>       if (i < n) {
>       fprintf(stderr, "%s: write truncated\n", av[1]);
> -     exit(1);
> +     return(1);
>       }
>
> -     exit(0);
> +     return(0);
>
>  notelf:
>       fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]);
> -     exit(1);
> +     return(1);
>
>  nospace:
>       fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
>          av[1]);
> -     exit(1);
> +     return(1);
>  }
>
>  /*


-------------- next part --------------
A non-text attachment was scrubbed...
Name: conf_arg.patch
Type: text/x-diff
Size: 5193 bytes
Desc: not available
URL: <http://lists.ozlabs.org/pipermail/yaboot-devel/attachments/20070404/5745f52e/attachment.patch>


More information about the Yaboot-devel mailing list