[2145] 2009-04-27 Vladimir Serbinenko <[email protected]>

Vladimir Serbinenko <[email protected]>
Newsgroups gmane.comp.boot-loaders.grub.cvs
Message-ID <[email protected]>
Revision: 2145
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=2145
Author:   phcoder
Date:     2009-04-27 16:48:58 +0000 (Mon, 27 Apr 2009)
Log Message:
-----------
2009-04-27  Vladimir Serbinenko <[email protected]>

	Preboot hooks support

	* commands/boot.c (struct grub_preboot_t): new declaration
	(preboots_head): new variable
	(preboots_tail): likewise
	(grub_loader_register_preboot_hook): new function
	(grub_loader_unregister_preboot_hook): likewise
	(grub_loader_set): launch preboot hooks
	* include/grub/loader.h (grub_loader_preboot_hook_prio_t): new type
	(grub_loader_register_preboot_hook): new declaration
	(grub_loader_unregister_preboot_hook): likewise

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/commands/boot.c
    trunk/grub2/include/grub/loader.h

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog	2009-04-27 15:39:39 UTC (rev 2144)
+++ trunk/grub2/ChangeLog	2009-04-27 16:48:58 UTC (rev 2145)
@@ -1,3 +1,17 @@
+2009-04-27  Vladimir Serbinenko <[email protected]>
+
+	Preboot hooks support
+
+	* commands/boot.c (struct grub_preboot_t): new declaration
+	(preboots_head): new variable
+	(preboots_tail): likewise
+	(grub_loader_register_preboot_hook): new function
+	(grub_loader_unregister_preboot_hook): likewise
+	(grub_loader_set): launch preboot hooks
+	* include/grub/loader.h (grub_loader_preboot_hook_prio_t): new type
+	(grub_loader_register_preboot_hook): new declaration
+	(grub_loader_unregister_preboot_hook): likewise
+
 2009-04-27  Vladimir Serbinenko  <[email protected]>
 
 	Warning fix

Modified: trunk/grub2/commands/boot.c
===================================================================
--- trunk/grub2/commands/boot.c	2009-04-27 15:39:39 UTC (rev 2144)
+++ trunk/grub2/commands/boot.c	2009-04-27 16:48:58 UTC (rev 2145)
@@ -22,12 +22,24 @@
 #include <grub/misc.h>
 #include <grub/loader.h>
 #include <grub/kernel.h>
+#include <grub/mm.h>
 
 static grub_err_t (*grub_loader_boot_func) (void);
 static grub_err_t (*grub_loader_unload_func) (void);
 static int grub_loader_noreturn;
 
+struct grub_preboot_t
+{
+  grub_err_t (*preboot_func) (int);
+  grub_err_t (*preboot_rest_func) (void);
+  grub_loader_preboot_hook_prio_t prio;
+  struct grub_preboot_t *next;
+  struct grub_preboot_t *prev;
+};
+
 static int grub_loader_loaded;
+static struct grub_preboot_t *preboots_head = 0, 
+  *preboots_tail = 0;
 
 int
 grub_loader_is_loaded (void)
@@ -35,6 +47,68 @@
   return grub_loader_loaded;
 }
 
+/* Register a preboot hook. */
+void *
+grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noreturn),
+				   grub_err_t (*preboot_rest_func) (void),
+				   grub_loader_preboot_hook_prio_t prio)
+{
+  struct grub_preboot_t *cur, *new_preboot;
+
+  if (! preboot_func && ! preboot_rest_func)
+    return 0;
+
+  new_preboot = (struct grub_preboot_t *) 
+    grub_malloc (sizeof (struct grub_preboot_t));
+  if (! new_preboot)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "hook not added");
+      return 0;
+    }
+
+  new_preboot->preboot_func = preboot_func;
+  new_preboot->preboot_rest_func = preboot_rest_func;
+  new_preboot->prio = prio;
+
+  for (cur = preboots_head; cur && cur->prio > prio; cur = cur->next);
+
+  if (cur)
+    {
+      new_preboot->next = cur;
+      new_preboot->prev = cur->prev;
+      cur->prev = new_preboot;
+    }
+  else
+    {
+      new_preboot->next = 0;
+      new_preboot->prev = preboots_tail;
+      preboots_tail = new_preboot;
+    }
+  if (new_preboot->prev)
+    new_preboot->prev->next = new_preboot;
+  else
+    preboots_head = new_preboot;
+
+  return new_preboot;
+}
+
+void 
+grub_loader_unregister_preboot_hook (void *hnd)
+{
+  struct grub_preboot_t *preb = hnd;
+
+  if (preb->next)
+    preb->next->prev = preb->prev;
+  else
+    preboots_tail = preb->prev;
+  if (preb->prev)
+    preb->prev->next = preb->next;
+  else
+    preboots_head = preb->next;
+
+  grub_free (preb);
+}
+
 void
 grub_loader_set (grub_err_t (*boot) (void),
 		 grub_err_t (*unload) (void),
@@ -65,16 +139,36 @@
 grub_err_t
 grub_loader_boot (void)
 {
+  grub_err_t err = GRUB_ERR_NONE;
+  struct grub_preboot_t *cur;
+
   if (! grub_loader_loaded)
     return grub_error (GRUB_ERR_NO_KERNEL, "no loaded kernel");
 
   if (grub_loader_noreturn)
     grub_machine_fini ();
-  
-  return (grub_loader_boot_func) ();
+
+  for (cur = preboots_head; cur; cur = cur->next)
+    {
+      err = cur->preboot_func (grub_loader_noreturn);
+      if (err)
+	{
+	  for (cur = cur->prev; cur; cur = cur->prev)
+	    cur->preboot_rest_func ();
+	  return err;
+	}
+    }
+  err = (grub_loader_boot_func) ();
+
+  for (cur = preboots_tail; cur; cur = cur->prev)
+    if (! err) 
+      err = cur->preboot_rest_func ();
+    else
+      cur->preboot_rest_func ();
+
+  return err;
 }
 
-
 /* boot */
 static grub_err_t
 grub_cmd_boot (struct grub_command *cmd __attribute__ ((unused)),

Modified: trunk/grub2/include/grub/loader.h
===================================================================
--- trunk/grub2/include/grub/loader.h	2009-04-27 15:39:39 UTC (rev 2144)
+++ trunk/grub2/include/grub/loader.h	2009-04-27 16:48:58 UTC (rev 2145)
@@ -41,4 +41,26 @@
    depending on the setting by grub_loader_set.  */
 grub_err_t grub_loader_boot (void);
 
+/* The space between numbers is intentional for the simplicity of adding new
+   values even if external modules use them. */
+typedef enum {
+  /* A preboot hook which can use everything and turns nothing off. */
+  GRUB_LOADER_PREBOOT_HOOK_PRIO_NORMAL = 400,
+  /* A preboot hook which can't use disks and may stop disks. */
+  GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK = 300,
+  /* A preboot hook which can't use disks or console and may stop console. */
+  GRUB_LOADER_PREBOOT_HOOK_PRIO_CONSOLE = 200,
+  /* A preboot hook which can't use disks or console, can't modify memory map
+     and may stop memory services or finalize memory map. */
+  GRUB_LOADER_PREBOOT_HOOK_PRIO_MEMORY = 100,
+} grub_loader_preboot_hook_prio_t;
+
+/* Register a preboot hook. */
+void *grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noret),
+					 grub_err_t (*preboot_rest_func) (void),
+					 grub_loader_preboot_hook_prio_t prio);
+
+/* Unregister given preboot hook. */
+void grub_loader_unregister_preboot_hook (void *hnd);
+
 #endif /* ! GRUB_LOADER_HEADER */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.