[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
PATCH (updated): 'lilo -R' functionality
From: |
Keir Fraser |
Subject: |
PATCH (updated): 'lilo -R' functionality |
Date: |
Tue, 05 Mar 2002 14:26:55 +0000 |
The following is a slight modification to the patch I submitted a week
or so ago. This will cause GRUB to skip displaying the boot menu if a
one-shot default has been specified (just as lilo does with '-R').
Same caveats as for previous patch:
* The new 'savedefault' function in the GRUB shell is incomplete.
Only works if the filesystem containing stage2 file is mounted.
* Patch is against grub-0.90, but patches directly to 0.91
I hope this goes into CVS in the next round of updates :-)
-- Keir Fraser
diff -urBP grub-0.90-old/ChangeLog grub-0.90-modified/ChangeLog
--- grub-0.90-old/ChangeLog Fri Feb 22 11:59:42 2002
+++ grub-0.90-modified/ChangeLog Fri Feb 22 11:56:21 2002
@@ -1,3 +1,10 @@
+2002-02-22 Keir Fraser <address@hidden>
+
+ * stage2/shared.h: New flag STAGE2_ONCEONLY_ENTRY causes
+ SAVED_ENTRYNO to be reset to zero on next reboot.
+ * stage2/builtins.c: A new version of 'savedefault' function
+ for the GRUB shell. Provides 'lilo -R' functionality.
+
2001-07-07 OKUJI Yoshinori <address@hidden>
* netboot/compile: New file. This was also missing... How many
diff -urBP grub-0.90-old/stage2/builtins.c grub-0.90-modified/stage2/builtins.c
--- grub-0.90-old/stage2/builtins.c Fri Feb 22 11:59:57 2002
+++ grub-0.90-modified/stage2/builtins.c Fri Feb 22 13:48:36 2002
@@ -785,6 +785,17 @@
default_func (char *arg, int flags)
{
#ifndef SUPPORT_DISKLESS
+#ifndef GRUB_UTIL
+ /* Has a forced once-only default been specified? */
+ static int savedefault_helper(int);
+ if ((saved_entryno & STAGE2_ONCEONLY_ENTRY) != 0)
+ {
+ grub_timeout = 0;
+ default_entry = saved_entryno & ~STAGE2_ONCEONLY_ENTRY;
+ savedefault_helper(0);
+ return 0;
+ }
+#endif
if (grub_strcmp (arg, "saved") == 0)
{
default_entry = saved_entryno;
@@ -3074,22 +3085,15 @@
};
-/* savedefault */
+
+#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
+/* Write specified default entry number into stage2 file. */
static int
-savedefault_func (char *arg, int flags)
+savedefault_helper(int new_default)
{
-#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
char buffer[512];
int *entryno_ptr;
-
- /* This command is only useful when you boot an entry from the menu
- interface. */
- if (! (flags & BUILTIN_SCRIPT))
- {
- errnum = ERR_UNRECOGNIZED;
- return 1;
- }
-
+
/* Get the geometry of the boot drive (i.e. the disk which contains
this stage2). */
if (get_diskinfo (boot_drive, &buf_geom))
@@ -3115,10 +3119,10 @@
entryno_ptr = (int *) (buffer + STAGE2_SAVED_ENTRYNO);
/* Check if the saved entry number differs from current entry number. */
- if (*entryno_ptr != current_entryno)
+ if (*entryno_ptr != new_default)
{
/* Overwrite the saved entry number. */
- *entryno_ptr = current_entryno;
+ *entryno_ptr = new_default;
/* Save the image in the disk. */
if (! rawwrite (boot_drive, install_second_sector, buffer))
@@ -3129,6 +3133,117 @@
}
return 0;
+}
+#endif
+
+#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
+/*
+ * Full implementation of new `savedefault' for GRUB shell.
+ * XXX This needs fixing for stage2 files which aren't accessible
+ * through a mounted filesystem.
+ */
+static int
+savedefault_shell(char *arg, int flags)
+{
+ char *stage2_os_file = "/boot/grub/stage2"; /* Default filename */
+ FILE *fp;
+ char buffer[512];
+ int *entryno_ptr;
+ int new_default = 0;
+
+ while (1)
+ {
+ if (grub_memcmp ("--stage2=", arg, sizeof ("--stage2=") - 1) == 0)
+ {
+ stage2_os_file = arg + sizeof ("--stage2=") - 1;
+ arg = skip_to (0, arg);
+ nul_terminate (stage2_os_file);
+ }
+ else if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0)
+ {
+ char *p = arg + sizeof ("--default=") - 1;
+ if (! safe_parse_maxint (&p, &new_default))
+ return 1;
+ arg = skip_to (0, arg);
+ }
+ else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0)
+ {
+ new_default |= STAGE2_ONCEONLY_ENTRY;
+ arg = skip_to (0, arg);
+ }
+ else
+ break;
+ }
+
+ if (! (fp = fopen(stage2_os_file, "r+")))
+ {
+ errnum = ERR_FILE_NOT_FOUND;
+ return 1;
+ }
+
+ if (fseek (fp, SECTOR_SIZE, SEEK_SET) != 0)
+ {
+ fclose (fp);
+ errnum = ERR_BAD_VERSION;
+ return 1;
+ }
+
+ if (fread (buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
+ {
+ fclose (fp);
+ errnum = ERR_READ;
+ return 1;
+ }
+
+ /* Sanity check. */
+ if (buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2
+ || *((short *) (buffer + STAGE2_VER_MAJ_OFFS)) != COMPAT_VERSION)
+ {
+ errnum = ERR_BAD_VERSION;
+ return 1;
+ }
+
+ entryno_ptr = (int *) (buffer + STAGE2_SAVED_ENTRYNO);
+ *entryno_ptr = new_default;
+
+ if (fseek (fp, SECTOR_SIZE, SEEK_SET) != 0)
+ {
+ fclose (fp);
+ errnum = ERR_BAD_VERSION;
+ return 1;
+ }
+
+ if (fwrite (buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
+ {
+ fclose (fp);
+ errnum = ERR_WRITE;
+ return 1;
+ }
+
+ (void)fflush (fp);
+ fclose (fp);
+ return 0;
+}
+#endif
+
+/* savedefault */
+static int
+savedefault_func (char *arg, int flags)
+{
+#if !defined(SUPPORT_DISKLESS)
+#if !defined(GRUB_UTIL)
+ /* This command is only useful when you boot an entry from the menu
+ interface. */
+ if (! (flags & BUILTIN_SCRIPT))
+ {
+ errnum = ERR_UNRECOGNIZED;
+ return 1;
+ }
+
+ return savedefault_helper(current_entryno);
+#else /* defined(GRUB_UTIL) */
+ return savedefault_shell(arg, flags);
+#endif
#else /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */
errnum = ERR_UNRECOGNIZED;
return 1;
@@ -3140,8 +3255,14 @@
"savedefault",
savedefault_func,
BUILTIN_CMDLINE,
+#ifdef GRUB_UTIL
+ "savedefault [--stage2=STAGE2_FILE] [--default=DEFAULT] [--once]",
+ "Save DEFAULT as the default boot entry in STAGE2_FILE. If '--once'"
+ " is specified, the default is reset after the next reboot."
+#else
"savedefault",
"Save the current entry as the default boot entry."
+#endif
};
@@ -4217,6 +4338,15 @@
static int
timeout_func (char *arg, int flags)
{
+ /* One-shot default shenanigans -- don't piss around with the menu! */
+ if (grub_timeout != -1)
+ return 0;
+ if ((saved_entryno & STAGE2_ONCEONLY_ENTRY) != 0)
+ {
+ grub_timeout = 0;
+ return 0;
+ }
+
if (! safe_parse_maxint (&arg, &grub_timeout))
return 1;
diff -urBP grub-0.90-old/stage2/shared.h grub-0.90-modified/stage2/shared.h
--- grub-0.90-old/stage2/shared.h Fri Feb 22 11:59:53 2002
+++ grub-0.90-modified/stage2/shared.h Fri Feb 22 10:51:49 2002
@@ -199,6 +199,8 @@
#define STAGE2_FORCE_LBA 0x11
#define STAGE2_VER_STR_OFFS 0x12
+#define STAGE2_ONCEONLY_ENTRY 0x10000
+
/* Stage 2 identifiers */
#define STAGE2_ID_STAGE2 0
#define STAGE2_ID_FFS_STAGE1_5 1
- PATCH (updated): 'lilo -R' functionality,
Keir Fraser <=