All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: [PATCH] Move environment context handling out of kernel.
Date: Sun, 20 Dec 2009 14:26:14 +0100	[thread overview]
Message-ID: <4B2E25F6.4000900@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 26047 bytes --]

This is a multi-part message in MIME format.
--------------040505020001050308040003
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hello, all. Rescue mode doesn't need contexts so I propose to move
context handling to normal.mod rather than have it in kernel. Saves 314
bytes. Available in experimental

--=20
Regards
Vladimir '=CF=86-coder/phcoder' Serbinenko


--------------040505020001050308040003
Content-Type: text/x-diff;
 name="newenv.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline;
 filename="newenv.diff"

=3D=3D=3D added file 'ChangeLog.newenv'
--- ChangeLog.newenv	1970-01-01 00:00:00 +0000
+++ ChangeLog.newenv	2009-12-20 13:20:06 +0000
@@ -0,0 +1,55 @@
+2009-12-20  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Move context handling out of the kernel.
+
+	* conf/any-emu.rmk (grub_emu_SOURCES): Add normal/context.c.
+	* conf/common.rmk (normal_mod_SOURCES): Add normal/context.c.
+	* conf/i386-coreboot.rmk (kernel_img_HEADERS): Add env_private.h.
+	* conf/i386-efi.rmk: Likewise.
+	* conf/i386-ieee1275.rmk: Likewise.
+	* conf/i386-pc.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	* conf/sparc64-ieee1275.rmk: Likewise.
+	* conf/x86_64-efi.rmk: Likewise.
+	* include/grub/env.h: Include grub/menu.h.
+	(grub_env_var_type): Removed.
+	(grub_env_var): Replaced field 'type' with 'global'.
+	(grub_env_find): New prototype.
+	(grub_env_context_open): Remove EXPORT_FUNC.
+	(grub_env_context_close): Likewise.
+	(grub_env_export): Likewise.
+	(grub_env_set_data_slot): Removed.
+	(grub_env_get_data_slot): Likewise.
+	(grub_env_unset_data_slot): Likewise.
+	(grub_env_unset_menu): New prototype.
+	(grub_env_set_menu): Likewise.
+	(grub_env_get_menu): Likewise.
+	* include/grub/env_private.h: New file.
+	* include/grub/normal.h (grub_context_init): New prototype.
+	(grub_context_fini): Likewise.
+	* kern/corecmd.c (grub_core_cmd_export): Moved from here ...
+	* normal/context.c (grub_cmd_export): ... to here.
+	* kern/env.c: Include env_private.h.
+	(HASHSZ): Moved to include/grub/env_private.h.
+	(grub_env_context): Likewise.
+	(grub_env_sorted_var): Likewise.
+	(current_context): Renamed from this ...
+	(grub_current_context): ...to this. 'static' removed. All users updated=
=2E
+	(grub_env_find): Removed 'static'.
+	(grub_env_context_open): Moved to normal/context.c.
+	(grub_env_context_close): Likewise.
+	(grub_env_export): Likewise.
+	(mangle_data_slot_name): Removed.
+	(grub_env_set_data_slot): Likewise.
+	(grub_env_get_data_slot): Likewise.
+	(grub_env_unset_data_slot): Likewise.
+	* kern/main.c (grub_set_root_dev): Don't export root.
+	It will be done later.
+	(grub_main): Don't export prefix.
+	It will be done later.
+	* normal/context.c: New file.
+	* normal/main.c (free_menu): Use grub_env_unset_menu.
+	(grub_normal_add_menu_entry): Use grub_env_get_menu.
+	(read_config_file): Use grub_env_get_menu and grub_env_set_menu.
+	(GRUB_MOD_INIT(normal)): Call grub_context_init.
+	(GRUB_MOD_FINI(normal)): Call grub_context_fini.

=3D=3D=3D modified file 'conf/any-emu.rmk'
--- conf/any-emu.rmk	2009-11-30 15:39:59 +0000
+++ conf/any-emu.rmk	2009-12-20 01:26:58 +0000
@@ -27,7 +27,7 @@
 	normal/handler.c normal/auth.c normal/autofs.c			\
 	normal/completion.c normal/main.c normal/color.c		\
 	normal/menu.c normal/menu_entry.c normal/menu_viewer.c		\
-	normal/menu_text.c						\
+	normal/menu_text.c normal/context.c				\
 	script/main.c script/execute.c script/function.c		\
 	script/lexer.c script/script.c grub_script.tab.c		\
 	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\

=3D=3D=3D modified file 'conf/common.rmk'
--- conf/common.rmk	2009-12-18 02:57:32 +0000
+++ conf/common.rmk	2009-12-20 01:26:58 +0000
@@ -543,7 +543,7 @@
 	normal/auth.c normal/autofs.c normal/handler.c \
 	normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
 	normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \
-	normal/misc.c
+	normal/misc.c normal/context.c
 normal_mod_CFLAGS =3D $(COMMON_CFLAGS)
 normal_mod_LDFLAGS =3D $(COMMON_LDFLAGS)
=20

=3D=3D=3D modified file 'conf/i386-coreboot.rmk'
--- conf/i386-coreboot.rmk	2009-12-03 23:07:29 +0000
+++ conf/i386-coreboot.rmk	2009-12-20 01:26:58 +0000
@@ -35,7 +35,8 @@
 	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
 	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \=

 	machine/boot.h machine/console.h machine/init.h \
-	machine/memory.h machine/loader.h list.h handler.h command.h i18n.h
+	machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \
+	env_private.h
 kernel_img_CFLAGS =3D $(COMMON_CFLAGS)
 kernel_img_ASFLAGS =3D $(COMMON_ASFLAGS)
 kernel_img_LDFLAGS =3D $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_=
MACHINE_LINK_ADDR),-Bstatic

=3D=3D=3D modified file 'conf/i386-efi.rmk'
--- conf/i386-efi.rmk	2009-12-18 02:57:32 +0000
+++ conf/i386-efi.rmk	2009-12-20 01:26:58 +0000
@@ -51,7 +51,8 @@
 kernel_img_HEADERS =3D boot.h cache.h device.h disk.h dl.h elf.h elfload=
=2Eh \
 	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
 	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \=

-	efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h i=
18n.h
+	efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h \=

+	i18n.h env_private.h
 kernel_img_CFLAGS =3D $(COMMON_CFLAGS)
 kernel_img_ASFLAGS =3D $(COMMON_ASFLAGS)
 kernel_img_LDFLAGS =3D $(COMMON_LDFLAGS)

=3D=3D=3D modified file 'conf/i386-ieee1275.rmk'
--- conf/i386-ieee1275.rmk	2009-11-26 00:45:53 +0000
+++ conf/i386-ieee1275.rmk	2009-12-20 01:26:58 +0000
@@ -33,7 +33,7 @@
 	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
 	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \=

 	ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h =
\
-	list.h handler.h command.h i18n.h
+	list.h handler.h command.h i18n.h env_private.h
 kernel_img_CFLAGS =3D $(COMMON_CFLAGS)
 kernel_img_ASFLAGS =3D $(COMMON_ASFLAGS)
 kernel_img_LDFLAGS =3D $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstat=
ic

=3D=3D=3D modified file 'conf/i386-pc.rmk'
--- conf/i386-pc.rmk	2009-12-18 02:57:32 +0000
+++ conf/i386-pc.rmk	2009-12-20 01:26:58 +0000
@@ -64,7 +64,8 @@
 	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \=

 	machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
 	machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
-	machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h i1=
8n.h
+	machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h \
+	i18n.h env_private.h
 kernel_img_CFLAGS =3D $(COMMON_CFLAGS)  $(TARGET_IMG_CFLAGS)
 kernel_img_ASFLAGS =3D $(COMMON_ASFLAGS)
 kernel_img_LDFLAGS =3D $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KER=
NEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)

=3D=3D=3D modified file 'conf/powerpc-ieee1275.rmk'
--- conf/powerpc-ieee1275.rmk	2009-11-26 00:45:53 +0000
+++ conf/powerpc-ieee1275.rmk	2009-12-20 01:26:58 +0000
@@ -17,7 +17,7 @@
 	env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \
 	symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \
 	msdos_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h=
 \
-	command.h i18n.h
+	command.h i18n.h env_private.h
=20
 symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gen=
symlist.sh
 	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)

=3D=3D=3D modified file 'conf/sparc64-ieee1275.rmk'
--- conf/sparc64-ieee1275.rmk	2009-12-03 11:18:56 +0000
+++ conf/sparc64-ieee1275.rmk	2009-12-20 01:26:58 +0000
@@ -31,7 +31,7 @@
 	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \=

 	list.h handler.h command.h i18n.h \
 	sparc64/libgcc.h ieee1275/ieee1275.h machine/kernel.h \
-	sparc64/ieee1275/ieee1275.h
+	sparc64/ieee1275/ieee1275.h env_private.h
 kernel_img_SOURCES =3D kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.=
c	\
 	kern/ieee1275/ieee1275.c kern/main.c kern/device.c		\
 	kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c		\

=3D=3D=3D modified file 'conf/x86_64-efi.rmk'
--- conf/x86_64-efi.rmk	2009-12-18 02:57:32 +0000
+++ conf/x86_64-efi.rmk	2009-12-20 01:26:58 +0000
@@ -51,7 +51,7 @@
 	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
 	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \=

 	efi/efi.h efi/time.h efi/disk.h machine/loader.h i386/pit.h list.h \
-	handler.h command.h i18n.h
+	handler.h command.h i18n.h env_private.h
 kernel_img_CFLAGS =3D $(COMMON_CFLAGS)
 kernel_img_ASFLAGS =3D $(COMMON_ASFLAGS)
 kernel_img_LDFLAGS =3D $(COMMON_LDFLAGS)

=3D=3D=3D modified file 'include/grub/env.h'
--- include/grub/env.h	2009-03-22 10:45:06 +0000
+++ include/grub/env.h	2009-12-20 01:46:19 +0000
@@ -22,6 +22,7 @@
 #include <grub/symbol.h>
 #include <grub/err.h>
 #include <grub/types.h>
+#include <grub/menu.h>
=20
 struct grub_env_var;
=20
@@ -30,18 +31,6 @@
 typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var,
 					const char *val);
=20
-enum grub_env_var_type
-  {
-    /* The default variable type which is local in current context.  */
-    GRUB_ENV_VAR_LOCAL,
-
-    /* The exported type, which is passed to new contexts.  */
-    GRUB_ENV_VAR_GLOBAL,
-
-    /* The data slot type, which is used to store arbitrary data.  */
-    GRUB_ENV_VAR_DATA
-  };
-
 struct grub_env_var
 {
   char *name;
@@ -50,23 +39,24 @@
   grub_env_write_hook_t write_hook;
   struct grub_env_var *next;
   struct grub_env_var **prevp;
-  enum grub_env_var_type type;
+  int global;
 };
=20
 grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val)=
;
 char *EXPORT_FUNC(grub_env_get) (const char *name);
 void EXPORT_FUNC(grub_env_unset) (const char *name);
 void EXPORT_FUNC(grub_env_iterate) (int (*func) (struct grub_env_var *va=
r));
+struct grub_env_var *EXPORT_FUNC(grub_env_find) (const char *name);
 grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name,
 						     grub_env_read_hook_t read_hook,
 						     grub_env_write_hook_t write_hook);
-grub_err_t EXPORT_FUNC(grub_env_context_open) (int export);
-grub_err_t EXPORT_FUNC(grub_env_context_close) (void);
-grub_err_t EXPORT_FUNC(grub_env_export) (const char *name);
-
-grub_err_t EXPORT_FUNC(grub_env_set_data_slot) (const char *name,
-						const void *ptr);
-void *EXPORT_FUNC(grub_env_get_data_slot) (const char *name);
-void EXPORT_FUNC(grub_env_unset_data_slot) (const char *name);
+
+grub_err_t grub_env_context_open (int export);
+grub_err_t grub_env_context_close (void);
+grub_err_t grub_env_export (const char *name);
+
+void grub_env_unset_menu (void);
+grub_menu_t grub_env_get_menu (void);
+void grub_env_set_menu (grub_menu_t nmenu);
=20
 #endif /* ! GRUB_ENV_HEADER */

=3D=3D=3D added file 'include/grub/env_private.h'
--- include/grub/env_private.h	1970-01-01 00:00:00 +0000
+++ include/grub/env_private.h	2009-12-20 01:21:05 +0000
@@ -0,0 +1,46 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2009  Free Software Foundation, In=
c.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by=

+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ENV_PRIVATE_HEADER
+#define GRUB_ENV_PRIVATE_HEADER	1
+
+#include <grub/env.h>
+
+/* The size of the hash table.  */
+#define	HASHSZ	13
+
+/* A hashtable for quick lookup of variables.  */
+struct grub_env_context
+{
+  /* A hash table for variables.  */
+  struct grub_env_var *vars[HASHSZ];
+
+  /* One level deeper on the stack.  */
+  struct grub_env_context *prev;
+};
+
+/* This is used for sorting only.  */
+struct grub_env_sorted_var
+{
+  struct grub_env_var *var;
+  struct grub_env_sorted_var *next;
+};
+
+extern struct grub_env_context *EXPORT_VAR(grub_current_context);
+
+#endif /* ! GRUB_ENV_PRIVATE_HEADER */

=3D=3D=3D modified file 'include/grub/normal.h'
--- include/grub/normal.h	2009-12-19 23:00:30 +0000
+++ include/grub/normal.h	2009-12-20 13:20:15 +0000
@@ -90,6 +90,8 @@
 /* Defined in `autofs.c'.  */
 void read_fs_list (void);
=20
+void grub_context_init (void);
+void grub_context_fini (void);
=20
 #ifdef GRUB_UTIL
 void grub_normal_init (void);

=3D=3D=3D modified file 'kern/corecmd.c'
--- kern/corecmd.c	2009-06-10 21:04:23 +0000
+++ kern/corecmd.c	2009-12-20 01:26:58 +0000
@@ -73,18 +73,6 @@
   return 0;
 }
=20
-static grub_err_t
-grub_core_cmd_export (struct grub_command *cmd __attribute__ ((unused)),=

-		      int argc, char **args)
-{
-  if (argc < 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-		       "no environment variable specified");
-
-  grub_env_export (args[0]);
-  return 0;
-}
-
 /* insmod MODULE */
 static grub_err_t
 grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),=

@@ -193,8 +181,6 @@
 			 "set [ENVVAR=3DVALUE]", "set an environment variable");
   grub_register_command ("unset", grub_core_cmd_unset,
 			 "unset ENVVAR", "remove an environment variable");
-  grub_register_command ("export", grub_core_cmd_export,
-			 "export ENVVAR", "Export a variable.");
   grub_register_command ("ls", grub_core_cmd_ls,
 			 "ls [ARG]", "list devices or files");
   grub_register_command ("insmod", grub_core_cmd_insmod,

=3D=3D=3D modified file 'kern/env.c'
--- kern/env.c	2009-07-16 22:14:09 +0000
+++ kern/env.c	2009-12-20 01:54:58 +0000
@@ -18,34 +18,15 @@
  */
=20
 #include <grub/env.h>
+#include <grub/env_private.h>
 #include <grub/misc.h>
 #include <grub/mm.h>
=20
-/* The size of the hash table.  */
-#define	HASHSZ	13
-
-/* A hashtable for quick lookup of variables.  */
-struct grub_env_context
-{
-  /* A hash table for variables.  */
-  struct grub_env_var *vars[HASHSZ];
-
-  /* One level deeper on the stack.  */
-  struct grub_env_context *prev;
-};
-
-/* This is used for sorting only.  */
-struct grub_env_sorted_var
-{
-  struct grub_env_var *var;
-  struct grub_env_sorted_var *next;
-};
-
 /* The initial context.  */
 static struct grub_env_context initial_context;
=20
 /* The current context.  */
-static struct grub_env_context *current_context =3D &initial_context;
+struct grub_env_context *grub_current_context =3D &initial_context;
=20
 /* Return the hash representation of the string S.  */
 static unsigned int
@@ -60,87 +41,20 @@
   return i % HASHSZ;
 }
=20
-static struct grub_env_var *
+struct grub_env_var *
 grub_env_find (const char *name)
 {
   struct grub_env_var *var;
   int idx =3D grub_env_hashval (name);
=20
   /* Look for the variable in the current context.  */
-  for (var =3D current_context->vars[idx]; var; var =3D var->next)
+  for (var =3D grub_current_context->vars[idx]; var; var =3D var->next)
     if (grub_strcmp (var->name, name) =3D=3D 0)
       return var;
=20
   return 0;
 }
=20
-grub_err_t
-grub_env_context_open (int export)
-{
-  struct grub_env_context *context;
-  int i;
-
-  context =3D grub_zalloc (sizeof (*context));
-  if (! context)
-    return grub_errno;
-
-  context->prev =3D current_context;
-  current_context =3D context;
-
-  /* Copy exported variables.  */
-  for (i =3D 0; i < HASHSZ; i++)
-    {
-      struct grub_env_var *var;
-
-      for (var =3D context->prev->vars[i]; var; var =3D var->next)
-	{
-	  if (export && var->type =3D=3D GRUB_ENV_VAR_GLOBAL)
-	    {
-	      if (grub_env_set (var->name, var->value) !=3D GRUB_ERR_NONE)
-		{
-		  grub_env_context_close ();
-		  return grub_errno;
-		}
-	      grub_register_variable_hook (var->name, var->read_hook, var->writ=
e_hook);
-	    }
-	}
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_env_context_close (void)
-{
-  struct grub_env_context *context;
-  int i;
-
-  if (! current_context->prev)
-    grub_fatal ("cannot close the initial context");
-
-  /* Free the variables associated with this context.  */
-  for (i =3D 0; i < HASHSZ; i++)
-    {
-      struct grub_env_var *p, *q;
-
-      for (p =3D current_context->vars[i]; p; p =3D q)
-	{
-	  q =3D p->next;
-          grub_free (p->name);
-          if (p->type !=3D GRUB_ENV_VAR_DATA)
-            grub_free (p->value);
-	  grub_free (p);
-	}
-    }
-
-  /* Restore the previous context.  */
-  context =3D current_context->prev;
-  grub_free (current_context);
-  current_context =3D context;
-
-  return GRUB_ERR_NONE;
-}
-
 static void
 grub_env_insert (struct grub_env_context *context,
 		 struct grub_env_var *var)
@@ -165,18 +79,6 @@
 }
=20
 grub_err_t
-grub_env_export (const char *name)
-{
-  struct grub_env_var *var;
-
-  var =3D grub_env_find (name);
-  if (var)
-    var->type =3D GRUB_ENV_VAR_GLOBAL;
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
 grub_env_set (const char *name, const char *val)
 {
   struct grub_env_var *var;
@@ -207,9 +109,8 @@
   if (! var)
     return grub_errno;
=20
-  /* This is not necessary, because GRUB_ENV_VAR_LOCAL =3D=3D 0. But lea=
ve
-     this for readability.  */
-  var->type =3D GRUB_ENV_VAR_LOCAL;
+  /* This is not necessary. But leave this for readability.  */
+  var->global =3D 0;
=20
   var->name =3D grub_strdup (name);
   if (! var->name)
@@ -219,7 +120,7 @@
   if (! var->value)
     goto fail;
=20
-  grub_env_insert (current_context, var);
+  grub_env_insert (grub_current_context, var);
=20
   return GRUB_ERR_NONE;
=20
@@ -263,8 +164,7 @@
   grub_env_remove (var);
=20
   grub_free (var->name);
-  if (var->type !=3D GRUB_ENV_VAR_DATA)
-    grub_free (var->value);
+  grub_free (var->value);
   grub_free (var);
 }
=20
@@ -280,14 +180,10 @@
     {
       struct grub_env_var *var;
=20
-      for (var =3D current_context->vars[i]; var; var =3D var->next)
+      for (var =3D grub_current_context->vars[i]; var; var =3D var->next=
)
 	{
 	  struct grub_env_sorted_var *p, **q;
=20
-	  /* Ignore data slots.  */
-	  if (var->type =3D=3D GRUB_ENV_VAR_DATA)
-	    continue;
-
 	  sorted_var =3D grub_malloc (sizeof (*sorted_var));
 	  if (! sorted_var)
 	    goto fail;
@@ -343,84 +239,3 @@
=20
   return GRUB_ERR_NONE;
 }
-
-static char *
-mangle_data_slot_name (const char *name)
-{
-  char *mangled_name;
-
-  mangled_name =3D grub_malloc (grub_strlen (name) + 2);
-  if (! mangled_name)
-    return 0;
-
-  grub_sprintf (mangled_name, "\e%s", name);
-  return mangled_name;
-}
-
-grub_err_t
-grub_env_set_data_slot (const char *name, const void *ptr)
-{
-  char *mangled_name;
-  struct grub_env_var *var;
-
-  mangled_name =3D mangle_data_slot_name (name);
-  if (! mangled_name)
-    goto fail;
-
-  /* If the variable does already exist, just update the variable.  */
-  var =3D grub_env_find (mangled_name);
-  if (var)
-    {
-      var->value =3D (char *) ptr;
-      return GRUB_ERR_NONE;
-    }
-
-  /* The variable does not exist, so create a new one.  */
-  var =3D grub_zalloc (sizeof (*var));
-  if (! var)
-    goto fail;
-
-  var->type =3D GRUB_ENV_VAR_DATA;
-  var->name =3D mangled_name;
-  var->value =3D (char *) ptr;
-
-  grub_env_insert (current_context, var);
-
-  return GRUB_ERR_NONE;
-
- fail:
-
-  grub_free (mangled_name);
-  return grub_errno;
-}
-
-void *
-grub_env_get_data_slot (const char *name)
-{
-  char *mangled_name;
-  void *ptr =3D 0;
-
-  mangled_name =3D mangle_data_slot_name (name);
-  if (! mangled_name)
-    goto fail;
-
-  ptr =3D grub_env_get (mangled_name);
-  grub_free (mangled_name);
-
- fail:
-
-  return ptr;
-}
-
-void
-grub_env_unset_data_slot (const char *name)
-{
-  char *mangled_name;
-
-  mangled_name =3D mangle_data_slot_name (name);
-  if (! mangled_name)
-    return;
-
-  grub_env_unset (mangled_name);
-  grub_free (mangled_name);
-}

=3D=3D=3D modified file 'kern/main.c'
--- kern/main.c	2009-06-10 21:04:23 +0000
+++ kern/main.c	2009-12-20 01:26:58 +0000
@@ -114,7 +114,6 @@
   const char *prefix;
=20
   grub_register_variable_hook ("root", 0, grub_env_write_root);
-  grub_env_export ("root");
=20
   prefix =3D grub_env_get ("prefix");
=20
@@ -164,7 +163,6 @@
   /* It is better to set the root device as soon as possible,
      for convenience.  */
   grub_machine_set_prefix ();
-  grub_env_export ("prefix");
   grub_set_root_dev ();
=20
   grub_register_core_commands ();

=3D=3D=3D added file 'normal/context.c'
--- normal/context.c	1970-01-01 00:00:00 +0000
+++ normal/context.c	2009-12-20 01:46:46 +0000
@@ -0,0 +1,172 @@
+/* env.c - Environment variables */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2008,2009  Free Software Foundatio=
n, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by=

+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/env_private.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/command.h>
+
+struct menu_pointer
+{
+  grub_menu_t menu;
+  struct menu_pointer *prev;
+};
+
+struct menu_pointer initial_menu;
+struct menu_pointer *current_menu =3D &initial_menu;
+
+void
+grub_env_unset_menu (void)
+{
+  current_menu->menu =3D NULL;
+}
+
+grub_menu_t
+grub_env_get_menu (void)
+{
+  return current_menu->menu;
+}
+
+void
+grub_env_set_menu (grub_menu_t nmenu)
+{
+  current_menu->menu =3D nmenu;
+}
+
+grub_err_t
+grub_env_context_open (int export)
+{
+  struct grub_env_context *context;
+  int i;
+  struct menu_pointer *menu;
+
+  context =3D grub_zalloc (sizeof (*context));
+  if (! context)
+    return grub_errno;
+  menu =3D grub_zalloc (sizeof (*menu));
+  if (! menu)
+    return grub_errno;
+
+  context->prev =3D grub_current_context;
+  grub_current_context =3D context;
+
+  menu->prev =3D current_menu;
+  current_menu =3D menu;
+
+  /* Copy exported variables.  */
+  for (i =3D 0; i < HASHSZ; i++)
+    {
+      struct grub_env_var *var;
+
+      for (var =3D context->prev->vars[i]; var; var =3D var->next)
+	{
+	  if (export && var->global)
+	    {
+	      if (grub_env_set (var->name, var->value) !=3D GRUB_ERR_NONE)
+		{
+		  grub_env_context_close ();
+		  return grub_errno;
+		}
+	      grub_register_variable_hook (var->name, var->read_hook, var->writ=
e_hook);
+	    }
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_env_context_close (void)
+{
+  struct grub_env_context *context;
+  int i;
+  struct menu_pointer *menu;
+
+  if (! grub_current_context->prev)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "cannot close the initial context");
+
+  /* Free the variables associated with this context.  */
+  for (i =3D 0; i < HASHSZ; i++)
+    {
+      struct grub_env_var *p, *q;
+
+      for (p =3D grub_current_context->vars[i]; p; p =3D q)
+	{
+	  q =3D p->next;
+          grub_free (p->name);
+	  grub_free (p->value);
+	  grub_free (p);
+	}
+    }
+
+  /* Restore the previous context.  */
+  context =3D grub_current_context->prev;
+  grub_free (grub_current_context);
+  grub_current_context =3D context;
+
+  menu =3D current_menu->prev;
+  grub_free (current_menu);
+  current_menu =3D menu;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_env_export (const char *name)
+{
+  struct grub_env_var *var;
+
+  var =3D grub_env_find (name);
+  if (var)
+    var->global =3D 1;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t export_cmd;
+
+static grub_err_t
+grub_cmd_export (struct grub_command *cmd __attribute__ ((unused)),
+		 int argc, char **args)
+{
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "no environment variable specified");
+
+  grub_env_export (args[0]);
+  return 0;
+}
+
+void
+grub_context_init (void)
+{
+  grub_env_export ("root");
+  grub_env_export ("prefix");
+
+  export_cmd =3D grub_register_command ("export", grub_cmd_export,
+				      "export ENVVAR", "Export a variable.");
+}
+
+void
+grub_context_fini (void)
+{
+  grub_unregister_command (export_cmd);
+}

=3D=3D=3D modified file 'normal/main.c'
--- normal/main.c	2009-12-19 23:00:30 +0000
+++ normal/main.c	2009-12-20 13:20:15 +0000
@@ -133,7 +133,7 @@
     }
=20
   grub_free (menu);
-  grub_env_unset_data_slot ("menu");
+  grub_env_unset_menu ();
 }
=20
 static void
@@ -174,7 +174,7 @@
     return grub_errno;
   classes_tail =3D classes_head;
=20
-  menu =3D grub_env_get_data_slot ("menu");
+  menu =3D grub_env_get_menu ();
   if (! menu)
     return grub_error (GRUB_ERR_MENU, "no menu context");
=20
@@ -357,14 +357,14 @@
=20
   grub_menu_t newmenu;
=20
-  newmenu =3D grub_env_get_data_slot ("menu");
+  newmenu =3D grub_env_get_menu ();
   if (! newmenu)
     {
       newmenu =3D grub_zalloc (sizeof (*newmenu));
       if (! newmenu)
 	return 0;
=20
-      grub_env_set_data_slot ("menu", newmenu);
+      grub_env_set_menu (newmenu);
     }
=20
   /* Try to open the config file.  */
@@ -575,6 +575,8 @@
=20
 GRUB_MOD_INIT(normal)
 {
+  grub_context_init ();
+
   /* Normal mode shouldn't be unloaded.  */
   if (mod)
     grub_dl_ref (mod);
@@ -602,6 +604,8 @@
=20
 GRUB_MOD_FINI(normal)
 {
+  grub_context_fini ();
+
   grub_set_history (0);
   grub_reader_unregister (&grub_normal_reader);
   grub_register_variable_hook ("pager", 0, 0);


--------------040505020001050308040003--

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 293 bytes --]

             reply	other threads:[~2009-12-20 13:27 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-20 13:26 Vladimir 'φ-coder/phcoder' Serbinenko [this message]
2010-01-07 19:19 ` [PATCH] Move environment context handling out of kernel Robert Millan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4B2E25F6.4000900@gmail.com \
    --to=phcoder@gmail.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.