bug-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Fwd: Changed config file processing .. patch]


From: Christoph Plattner
Subject: [Fwd: Changed config file processing .. patch]
Date: Sun, 14 Oct 2001 01:52:15 +0200

Hello Mr. Okuji,

I sent the patch only to bug-grub not to you.

Read below mre details.

In simple words: The preset menu is executed first in any way,
and is replaced (concerning menu entries) and overridden 
concerning settings) when a main config file (local or via net)
is present. The network environment will be activated (if using
the diskless version) between the preset and the main menu.

This new implementation does NOT violate your initial idea, but
gives the user the possibility to - for example - activate the
serial interface before running "bootp". Otherwise if the
server is not responding to the target (or other problems
concerning the ethernet link, etc) will lead to an "hanging"
GRUB, as no output is shown on the serial line.

See more details below.

With friendly regards
        Christoph P.





-- 
-------------------------------------------------------
private:        address@hidden
company:        address@hidden
--- Begin Message --- Subject: Changed config file processing .. patch Date: Mon, 08 Oct 2001 23:20:24 +0200
Hello GRUB hackers:

An open problem concerning the preset menu was for me,
that if I want to use a serial console, the BOOTP,etc..
was not visible. The preset menu was only executied, if
no "normal" config file was present and AFTER the netboot
stuff (bootp, etc) was executed.

So I tried to find a way to ...
 * achive the goal to setup serial before BOOTP is executed
 * do not break the idea of the current version of GRUB, that
   the preset menu entries (title.... ) are only used, if
   the main config file `menu.lst' is not present or defined
   as TAG-150 in the diskless version.

I introduced 3 states:
        0: try preset menu
        1: init network stuff in the diskless version (BOOTP,...)
        2: try main menu file

In state 0:
The system tries to open the preset menu file. Configurations
are parsed and interpreted. The menu items are passed also.
The system switches to config state 1

In state 1:
In the diskless version the BOOTP and ethernet setup is done.
Otherwise this state is a dummy state.
The system switches to config state 2 (and falls through to state 2)

In state 2:
The system tries to open the main config file `config_file'.
If it is present, all menu item counters are reset to the
initial values. Only settings like serial terminal are selected
root devices, etc, stay active.
Now the menu is parsed as under the current GRUB version.
Settings in this file (inclusive terminal settings, etc...) override
the setting of the preset menu file.

I think this approach is really acceptable and it is in my oppinion
a good solution to the problem concerning the serial interface setup.
Otherwise GRUB simple seems to block, if no boot server is answering
or there is a cabeling failure.

Here is the patch for this changes. The patch is locally done
in stage2/stage2.c. The diskless environment setup was moved
from common.c to stage2.c, as it is called now in stage2 and
not before calling `cmain ()'.

With friendly regards

        Christoph P.


PS: Ignore the second entry in the ChangeLog file, this was for
the other patch, I provided some days before.

-- 
-------------------------------------------------------
private:        address@hidden
company:        address@hidden
Index: stage2/stage2.c
===================================================================
RCS file: /cvs/grub/stage2/stage2.c,v
retrieving revision 1.31
diff -u -r1.31 stage2.c
--- stage2/stage2.c     2001/05/25 07:57:57     1.31
+++ stage2/stage2.c     2001/10/08 21:17:07
@@ -20,6 +20,10 @@
 
 #include "shared.h"
 
+#ifdef SUPPORT_DISKLESS
+# include <etherboot.h>
+#endif
+
 grub_jmp_buf restart_env;
 
 #ifdef PRESET_MENU_STRING
@@ -891,6 +895,25 @@
   return pos;
 }
 
+#ifdef SUPPORT_DISKLESS
+/* Set up the diskless environment so that GRUB can get a configuration
+   file from a network.  */
+static int
+setup_diskless_environment (void)
+{
+  /* For now, there is no difference between BOOTP and DHCP in GRUB.  */
+  if (! bootp ())
+    {
+      grub_printf ("BOOTP/DHCP fails.\n");
+      return 0;
+    }
+
+  /* This will be erased soon, though...  */
+  print_network_configuration ();
+  return 1;
+}
+#endif /* SUPPORT_DISKLESS */
+
 
 /* This is the starting function in C.  */
 void
@@ -899,8 +922,24 @@
   int config_len, menu_len, num_entries;
   char *config_entries, *menu_entries;
   char *kill_buf = (char *) KILL_BUF;
+  
+  /* config_state: 0..uninitialized, 1..preset menu, 2..config file */
+  int config_state = 0;
+
+  int is_opened = 0;
+  int is_preset = 0;
 
   /* Initialize the environment for restarting Stage 2.  */
+
+  /* init only to avoid warning concerning uninitialized data,
+     the field are initialized in the states propriately */
+  auto_fill = 1;
+  config_len = 0;
+  menu_len = 0;
+  num_entries = 0;
+  config_entries = (char *) mbi.drives_addr + mbi.drives_length;
+  menu_entries = (char *) MENU_BUF;
+  init_config ();
   grub_setjmp (restart_env);
   
   /* Initialize the kill buffer.  */
@@ -909,133 +948,176 @@
   /* Never return.  */
   for (;;)
     {
-      int is_opened = 0;
-      int is_preset = 0;
-      
-      auto_fill = 1;
-      config_len = 0;
-      menu_len = 0;
-      num_entries = 0;
-      config_entries = (char *) mbi.drives_addr + mbi.drives_length;
-      menu_entries = (char *) MENU_BUF;
-      init_config ();
-
-      /* Here load the configuration file.  */
-
 #ifdef GRUB_UTIL
       if (use_config_file)
 #endif /* GRUB_UTIL */
        {
-         is_opened = grub_open (config_file);
-         errnum = ERR_NONE;
-         if (! is_opened)
-           is_opened = is_preset = open_preset_menu ();
-       }
-      
-      if (is_opened)
-       {
-         /* STATE 0:  Before any title command.
-            STATE 1:  In a title command.
-            STATE >1: In a entry after a title command.  */
-         int state = 0, prev_config_len = 0, prev_menu_len = 0;
-         char *cmdline;
-
-         cmdline = (char *) CMDLINE_BUF;
-         while (get_line_from_config (cmdline, NEW_HEAPSIZE, ! is_preset))
-           {
-             struct builtin *builtin;
-
-             /* Get the pointer to the builtin structure.  */
-             builtin = find_command (cmdline);
-             errnum = 0;
-             if (! builtin)
-               /* Unknown command. Just skip now.  */
-               continue;
+         do
+           {
+               /* reset in every cycle */
+               is_opened = 0;
+               is_preset = 0;
 
-             if (builtin->flags & BUILTIN_TITLE)
+               switch (config_state)
                {
-                 char *ptr;
+               case 0:
+                   is_preset = is_opened = open_preset_menu ();
+                   
+                   if (is_opened)
+                   {
+                       auto_fill = 1;
+                       config_len = 0;
+                       menu_len = 0;
+                       num_entries = 0;
+                       config_entries = (char *) mbi.drives_addr + 
+                           mbi.drives_length;
+                       menu_entries = (char *) MENU_BUF;
+                       init_config ();
+                   }
+                   config_state = 1;
+                   break;
+               case 1:
+#ifdef SUPPORT_DISKLESS
+                   /* if diskless support, init diskless environment */
+                   if (! setup_diskless_environment ())
+                   {
+                       printf ("Error initializing diskless environment\n");
+                       /* abort here? */
+                   }
+#endif
+                   config_state = 2;
+
+                   /* !! here fall through !! */
+
+               case 2:
+                   is_opened = grub_open (config_file);
+                   errnum = ERR_NONE;
+                   if (is_opened)
+                   {
+                       auto_fill = 1;
+                       config_len = 0;
+                       menu_len = 0;
+                       num_entries = 0;
+                       config_entries = (char *) mbi.drives_addr + 
+                           mbi.drives_length;
+                       menu_entries = (char *) MENU_BUF;
+                       init_config ();                   
+                   }
+                   break;
+               default:
+                   /* ignore error */
+                   break;
+               }
 
-                 /* the command "title" is specially treated.  */
+             if (is_opened)
+               {
+                 /* STATE 0:  Before any title command.
+                    STATE 1:  In a title command.
+                    STATE >1: In a entry after a title command.  */
+                 int state = 0, prev_config_len = 0, prev_menu_len = 0;
+                 char *cmdline;
+                 
+                 cmdline = (char *) CMDLINE_BUF;
+                 while (get_line_from_config (cmdline, NEW_HEAPSIZE, 
+                                              ! is_preset))
+                   {
+                     struct builtin *builtin;
+                     
+                     /* Get the pointer to the builtin structure.  */
+                     builtin = find_command (cmdline);
+                     errnum = 0;
+                     if (! builtin)
+                       /* Unknown command. Just skip now.  */
+                       continue;
+                     
+                     if (builtin->flags & BUILTIN_TITLE)
+                       {
+                         char *ptr;
+                         
+                         /* the command "title" is specially treated.  */
+                         if (state > 1)
+                           {
+                             /* The next title is found.  */
+                             num_entries++;
+                             config_entries[config_len++] = 0;
+                             prev_menu_len = menu_len;
+                             prev_config_len = config_len;
+                           }
+                         else
+                           {
+                             /* The first title is found.  */
+                             menu_len = prev_menu_len;
+                             config_len = prev_config_len;
+                           }
+                         
+                         /* Reset the state.  */
+                         state = 1;
+                         
+                         /* Copy title into menu area.  */
+                         ptr = skip_to (1, cmdline);
+                         while ((menu_entries[menu_len++] = *(ptr++)) != 0)
+                           ;
+                       }
+                     else if (! state)
+                       {
+                         /* Run a command found is possible.  */
+                         if (builtin->flags & BUILTIN_MENU)
+                           {
+                             char *arg = skip_to (1, cmdline);
+                             (builtin->func) (arg, BUILTIN_MENU);
+                             errnum = 0;
+                           }
+                         else
+                           /* Ignored.  */
+                           continue;
+                       }
+                     else
+                       {
+                         char *ptr = cmdline;
+                         
+                         state++;
+                         /* Copy config file data to config area.  */
+                         while ((config_entries[config_len++] = *ptr++) != 0)
+                           ;
+                       }
+                   }
+                 
                  if (state > 1)
                    {
-                     /* The next title is found.  */
+                     /* Finish the last entry.  */
                      num_entries++;
                      config_entries[config_len++] = 0;
-                     prev_menu_len = menu_len;
-                     prev_config_len = config_len;
                    }
                  else
                    {
-                     /* The first title is found.  */
                      menu_len = prev_menu_len;
                      config_len = prev_config_len;
                    }
-
-                 /* Reset the state.  */
-                 state = 1;
-
-                 /* Copy title into menu area.  */
-                 ptr = skip_to (1, cmdline);
-                 while ((menu_entries[menu_len++] = *(ptr++)) != 0)
-                   ;
-               }
-             else if (! state)
-               {
-                 /* Run a command found is possible.  */
-                 if (builtin->flags & BUILTIN_MENU)
+                 
+                 menu_entries[menu_len++] = 0;
+                 config_entries[config_len++] = 0;
+                 grub_memmove (config_entries + config_len, menu_entries, 
+                               menu_len);
+                 menu_entries = config_entries + config_len;
+                 
+                 /* Check if the default entry is present. Otherwise reset
+                    it to fallback if fallback is valid, or to DEFAULT_ENTRY 
+                    if not.  */
+                 if (default_entry >= num_entries)
                    {
-                     char *arg = skip_to (1, cmdline);
-                     (builtin->func) (arg, BUILTIN_MENU);
-                     errnum = 0;
+                     if (fallback_entry < 0 || fallback_entry >= num_entries)
+                       default_entry = 0;
+                     else
+                       default_entry = fallback_entry;
                    }
+                 
+                 if (is_preset)
+                   close_preset_menu ();
                  else
-                   /* Ignored.  */
-                   continue;
+                   grub_close ();
                }
-             else
-               {
-                 char *ptr = cmdline;
-
-                 state++;
-                 /* Copy config file data to config area.  */
-                 while ((config_entries[config_len++] = *ptr++) != 0)
-                   ;
-               }
-           }
-
-         if (state > 1)
-           {
-             /* Finish the last entry.  */
-             num_entries++;
-             config_entries[config_len++] = 0;
            }
-         else
-           {
-             menu_len = prev_menu_len;
-             config_len = prev_config_len;
-           }
-
-         menu_entries[menu_len++] = 0;
-         config_entries[config_len++] = 0;
-         grub_memmove (config_entries + config_len, menu_entries, menu_len);
-         menu_entries = config_entries + config_len;
-
-         /* Check if the default entry is present. Otherwise reset
-            it to fallback if fallback is valid, or to DEFAULT_ENTRY 
-            if not.  */
-         if (default_entry >= num_entries)
-           {
-             if (fallback_entry < 0 || fallback_entry >= num_entries)
-               default_entry = 0;
-             else
-               default_entry = fallback_entry;
-           }
-
-         if (is_preset)
-           close_preset_menu ();
-         else
-           grub_close ();
+         while (config_state < 2); /* do .. while () */
        }
 
       if (! num_entries)
Index: stage2/common.c
===================================================================
RCS file: /cvs/grub/stage2/common.c,v
retrieving revision 1.17
diff -u -r1.17 common.c
--- stage2/common.c     2001/08/02 20:05:54     1.17
+++ stage2/common.c     2001/10/08 21:17:07
@@ -21,10 +21,6 @@
 
 #include <shared.h>
 
-#ifdef SUPPORT_DISKLESS
-# include <etherboot.h>
-#endif
-
 /*
  *  Shared BIOS/boot data.
  */
@@ -133,25 +129,6 @@
 }
 #endif /* ! STAGE1_5 */
 
-#ifdef SUPPORT_DISKLESS
-/* Set up the diskless environment so that GRUB can get a configuration
-   file from a network.  */
-static int
-setup_diskless_environment (void)
-{
-  /* For now, there is no difference between BOOTP and DHCP in GRUB.  */
-  if (! bootp ())
-    {
-      grub_printf ("BOOTP/DHCP fails.\n");
-      return 0;
-    }
-
-  /* This will be erased soon, though...  */
-  print_network_configuration ();
-  return 1;
-}
-#endif /* SUPPORT_DISKLESS */
-
 /* This queries for BIOS information.  */
 void
 init_bios_info (void)
@@ -330,12 +307,6 @@
     mbi.flags |= MB_INFO_APM_TABLE;
 
 #endif /* STAGE1_5 */
-
-#ifdef SUPPORT_DISKLESS
-  /* If SUPPORT_DISKLESS is defined, initialize the network here.  */
-  if (! setup_diskless_environment ())
-    return;
-#endif
 
   /* Set boot drive and partition.  */
   saved_drive = boot_drive;
Index: ChangeLog
===================================================================
RCS file: /cvs/grub/ChangeLog,v
retrieving revision 1.430
diff -u -r1.430 ChangeLog
--- ChangeLog   2001/09/24 08:43:38     1.430
+++ ChangeLog   2001/10/08 21:17:16
@@ -1,3 +1,18 @@
+2001-10-08  Christoph Plattner  <address@hidden>
+
+       * stage2/stage2.c (cmain): Changes to execute preset menu 
+       before executing main menu. If main menu exist, only configs
+       of the preset menu are taken, no menu items.
+
+       * stage2/common.c: moved function setup_diskless_environment ()
+       to stage2/stage2.c, as this function is now called in stage2.c
+
+2001-10-03  Christoph Plattner  <address@hidden>
+
+       * stage2/Makefile.am: Added build for `stage2-diskless' to
+       load "diskless" GRUB from local devices (floppy, harddisk),
+       but loads config from server (instead of use of etherboot/netboot)
+
 2001-09-24  Jochen Hoenicke  <address@hidden>
 
        * stage2/fsys_reiserfs.c (reiserfs_dir):  Set errnum to 

--- End Message ---

reply via email to

[Prev in Thread] Current Thread [Next in Thread]