aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2005-09-22 04:03:24 +0000
committerhpa <hpa>2005-09-22 04:03:24 +0000
commit2e1fede4d545435395af8c98e44163956d9572fb (patch)
tree2466eff70ab6db4f20a292305d72089ce5b03bdf
parent8f4e42608d6b0a5b1889c0d7e3906a24f0fe283f (diff)
downloadsyslinux-elf-2e1fede4d545435395af8c98e44163956d9572fb.tar.gz
syslinux-elf-2e1fede4d545435395af8c98e44163956d9572fb.tar.xz
syslinux-elf-2e1fede4d545435395af8c98e44163956d9572fb.zip
Add update-only mode to extlinux; use it
-rw-r--r--extlinux.doc11
-rw-r--r--extlinux/extlinux.c70
-rw-r--r--syslinux.spec.in5
3 files changed, 60 insertions, 26 deletions
diff --git a/extlinux.doc b/extlinux.doc
index 79ca7a34..dcc511a2 100644
--- a/extlinux.doc
+++ b/extlinux.doc
@@ -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.
diff --git a/extlinux/extlinux.c b/extlinux/extlinux.c
index 195b4e5a..e9c7ba37 100644
--- a/extlinux/extlinux.c
+++ b/extlinux/extlinux.c
@@ -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);
}
diff --git a/syslinux.spec.in b/syslinux.spec.in
index ec060905..05bd31e5 100644
--- a/syslinux.spec.in
+++ b/syslinux.spec.in
@@ -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.