Add update-only mode to extlinux; use it
authorhpa <hpa>
Thu, 22 Sep 2005 04:03:24 +0000 (04:03 +0000)
committerhpa <hpa>
Thu, 22 Sep 2005 04:03:24 +0000 (04:03 +0000)
extlinux.doc
extlinux/extlinux.c
syslinux.spec.in

index 79ca7a3..dcc511a 100644 (file)
@@ -6,13 +6,16 @@ It works the same way as SYSLINUX, with a few slight modifications.
 1. The installer is run on a *mounted* filesystem.  Run the extlinux
    installer on the directory in which you want extlinux installed:
 
-       extlinux /boot
+       extlinux -i /boot
+
+   Specify --install (-i) to install for the first time, or
+   --update (-U) to upgrade a previous installation.
 
    NOTE: this doesn't have to be the root directory of a filesystem.
    If /boot is a filesystem, you can do:
 
        mkdir -p /boot/extlinux
-       extlinux /boot/extlinux
+       extlinux -i /boot/extlinux
 
    ... to create a subdirectory and install extlinux in it. 
 
@@ -27,7 +30,7 @@ It works the same way as SYSLINUX, with a few slight modifications.
    they are relative to the extlinux directory.
 
    extlinux supports subdirectories, but the total path length is
-   limited to 255 characters.
+   limited to 511 characters.
 
 
 4. EXTLINUX now supports symbolic links.  However, extremely long
@@ -59,7 +62,7 @@ preferred way to boot is:
 - Install the MBR on *each disk*, and mark the RAID-1 partition
   active.
 
-- Run "extlinux /boot" to install extlinux.  This will install it on
+- Run "extlinux -i /boot" to install extlinux.  This will install it on
   all the drives in the RAID-1 set, which means you can boot any
   combination of drives in any order.
 
index 195b4e5..e9c7ba3 100644 (file)
@@ -66,6 +66,8 @@ static void __attribute__((noreturn)) usage(int rv)
 {
   fprintf(stderr,
          "Usage: %s [options] directory\n"
+         "  --install    -i  Install over the current bootsector\n"
+         "  --update     -U  Update a previous EXTLINUX installation\n"
          "  --zip        -z  Force zipdrive geometry (-H 64 -S 32)\n"
          "  --sectors=#  -S  Force the number of sectors per track\n"
          "  --heads=#    -H  Force number of heads\n"
@@ -83,6 +85,8 @@ static void __attribute__((noreturn)) usage(int rv)
 }
 
 static const struct option long_options[] = {
+  { "install",  0, NULL, 'i' },
+  { "update",   0, NULL, 'U' },
   { "zipdrive", 0, NULL, 'z' },
   { "sectors",  1, NULL, 'S' },
   { "heads",    1, NULL, 'H' },
@@ -91,7 +95,7 @@ static const struct option long_options[] = {
   { 0, 0, 0, 0 }
 };
     
-static const char short_options[] = "zS:H:vh";
+static const char short_options[] = "iUuzS:H:vh";
 
 
 
@@ -629,13 +633,25 @@ install_file(const char *path, int devfd, struct stat *rst)
   return 1;
 }
 
+/* EXTLINUX installs the string 'EXTLINUX' at offset 3 in the boot
+   sector; this is consistent with FAT filesystems. */
 int
-install_loader(const char *path)
+already_installed(int devfd)
+{
+  char buffer[8];
+
+  xpread(devfd, buffer, 8, 3);
+  return !memcmp(buffer, "EXTLINUX", 8);
+}
+
+int
+install_loader(const char *path, int update_only)
 {
   struct stat st, dst, fst;
   struct mntent *mnt = NULL;
   int devfd, rv;
   FILE *mtab;
+  const char *devname;
 
   if ( stat(path, &st) || !S_ISDIR(st.st_mode) ) {
     fprintf(stderr, "%s: Not a directory: %s\n", program, path);
@@ -650,40 +666,38 @@ install_loader(const char *path)
            !strcmp(mnt->mnt_type, "ext3")) &&
           !stat(mnt->mnt_fsname, &dst) &&
           dst.st_rdev == st.st_dev ) {
-       fprintf(stderr, "%s is device %s\n", path, mnt->mnt_fsname);
-       if ( (devfd = open(mnt->mnt_fsname, O_RDWR|O_SYNC)) < 0 ) {
-         fprintf(stderr, "%s: cannot open device %s\n", program, mnt->mnt_fsname);
-         return 1;
-       }
+       devname = mnt->mnt_fsname;
        break;
       }
     }
   }
 
-  if ( devfd < 0 ) {
+  if ( !devname ) {
     /* Didn't find it in /proc/mounts, try /etc/mtab */
     if ( (mtab = setmntent("/etc/mtab", "r")) ) {
       while ( (mnt = getmntent(mtab)) ) {
-       if ( (!strcmp(mnt->mnt_type, "ext2") ||
-             !strcmp(mnt->mnt_type, "ext3")) &&
-            !stat(mnt->mnt_fsname, &dst) &&
-            dst.st_rdev == st.st_dev ) {
-         fprintf(stderr, "%s is device %s\n", path, mnt->mnt_fsname);
-         if ( (devfd = open(mnt->mnt_fsname, O_RDWR|O_SYNC)) < 0 ) {
-           fprintf(stderr, "%s: cannot open device %s\n", program, mnt->mnt_fsname);
-           return 1;
-         }
-         break;
-       }
+       devname = mnt->mnt_fsname;
+       break;
       }
     }
   }
 
-  if ( devfd < 0 ) {
+  if ( !devname ) {
     fprintf(stderr, "%s: cannot find device for path %s\n", program, path);
     return 1;
   }
 
+  fprintf(stderr, "%s is device %s\n", path, devname);
+  if ( (devfd = open(devname, O_RDWR|O_SYNC)) < 0 ) {
+    fprintf(stderr, "%s: cannot open device %s\n", program, devname);
+    return 1;
+  }
+  
+  if ( update_only && !already_installed(devfd) ) {
+    fprintf(stderr, "%s: no previous extlinux installation found\n");
+    return 1;
+  }
+           
   install_file(path, devfd, &fst);
 
   if ( fst.st_dev != st.st_dev ) {
@@ -709,6 +723,7 @@ main(int argc, char *argv[])
 {
   int o;
   const char *directory;
+  int update_only = -1;
 
   program = argv[0];
 
@@ -735,6 +750,13 @@ main(int argc, char *argv[])
        exit(EX_USAGE);
       }
       break;
+    case 'i':
+      update_only = 0;
+      break;
+    case 'u':
+    case 'U':
+      update_only = 1;
+      break;
     case 'h':
       usage(0);
       break;
@@ -752,5 +774,11 @@ main(int argc, char *argv[])
   if ( !directory )
     usage(EX_USAGE);
 
-  return install_loader(directory);
+  if ( update_only == -1 ) {
+    fprintf(stderr, "%s: warning: a future version will require --install or --update\n",
+           program);
+    update_only = 0;
+  }
+
+  return install_loader(directory, update_only);
 }
index ec06090..05bd31e 100644 (file)
@@ -89,11 +89,14 @@ rm -rf %{buildroot}
 %post
 # If we have a /boot/extlinux.conf file, assume extlinux is our bootloader
 # and update it.
-if [ -f /boot/extlinux.conf ]; then extlinux /boot; fi
+if [ -f /boot/extlinux.conf ]; then extlinux --update /boot; fi
 
 %postun
 
 %changelog
+* Wed Sep 21 2005 H. Peter Anvin <hpa@zytor.com>
+- If /boot/extlinux.conf exist, run extlinux --update.
+
 * Fri Sep  9 2005 H. Peter Anvin <hpa@zytor.com>
 - Copy, don't link, *.c32 into /boot; rpm doesn't like breaking links.