summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mdk-stage1/.cvsignore1
-rw-r--r--mdk-stage1/Makefile4
-rw-r--r--mdk-stage1/frontend.h2
-rw-r--r--mdk-stage1/newt-frontend.c4
-rw-r--r--mdk-stage1/rescue-gui.c206
-rw-r--r--mdk-stage1/stdio-frontend.c4
-rw-r--r--rescue/Makefile2
-rwxr-xr-xrescue/guessmounts30
-rwxr-xr-xrescue/install_bootloader47
-rwxr-xr-xrescue/lsparts124
-rwxr-xr-xrescue/make_rescue_img4
-rw-r--r--rescue/tree/etc/issue3
-rwxr-xr-xrescue/tree/etc/rc.sysinit9
13 files changed, 422 insertions, 18 deletions
diff --git a/mdk-stage1/.cvsignore b/mdk-stage1/.cvsignore
index 36f56f6b5..af2397e4b 100644
--- a/mdk-stage1/.cvsignore
+++ b/mdk-stage1/.cvsignore
@@ -9,3 +9,4 @@ debug.log
mkinitrd_helper.tar.bz2
hack_*
stage1-usbnet
+rescue-gui
diff --git a/mdk-stage1/Makefile b/mdk-stage1/Makefile
index 3b1482724..1e4b25653 100644
--- a/mdk-stage1/Makefile
+++ b/mdk-stage1/Makefile
@@ -236,6 +236,10 @@ tar-mkinitrd_helper: clean
tar cfj mkinitrd_helper.tar.bz2 mkinitrd_helper-subdir --exclude CVS
rm -rf mkinitrd_helper-subdir
+rescue-gui: rescue-gui.o frontend-common.o $(FRONTEND_LINK) $(STAGE1_LIBC)
+ $(CC) $(LDFLAGS_STAGE1) -o $@ $^
+ $(STRIPCMD) $@
+
.depend:
$(CPP) $(CFLAGS) -M $(ALLSRC) > .depend
diff --git a/mdk-stage1/frontend.h b/mdk-stage1/frontend.h
index 167291798..9c2609281 100644
--- a/mdk-stage1/frontend.h
+++ b/mdk-stage1/frontend.h
@@ -41,6 +41,8 @@ enum return_type ask_from_list(char *msg, char ** elems, char ** choice);
enum return_type ask_from_list_comments(char *msg, char ** elems, char ** elems_comments, char ** choice);
enum return_type ask_from_entries(char *msg, char ** questions, char *** answers, int entry_size, void (*callback_func)(char ** strings));
+void suspend_to_console(void);
+void resume_from_suspend(void);
void verror_message(char *msg, va_list ap);
void vinfo_message(char *msg, va_list ap);
diff --git a/mdk-stage1/newt-frontend.c b/mdk-stage1/newt-frontend.c
index e0bc7c5ce..15221c91f 100644
--- a/mdk-stage1/newt-frontend.c
+++ b/mdk-stage1/newt-frontend.c
@@ -390,3 +390,7 @@ enum return_type ask_from_entries(char *msg, char ** questions, char *** answers
return RETURN_OK;
}
+
+
+void suspend_to_console(void) { newtSuspend(); }
+void resume_from_suspend(void) { newtResume(); }
diff --git a/mdk-stage1/rescue-gui.c b/mdk-stage1/rescue-gui.c
new file mode 100644
index 000000000..bed0b403c
--- /dev/null
+++ b/mdk-stage1/rescue-gui.c
@@ -0,0 +1,206 @@
+/*
+ * Guillaume Cottenceau (gc@mandrakesoft.com)
+ *
+ * Copyright 2001 MandrakeSoft
+ *
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * public license.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdlib.h>
+#define _USE_BSD
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/mount.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/unistd.h>
+#include <sys/select.h>
+
+#include "config-stage1.h"
+#include "frontend.h"
+#include "tools.h"
+
+char * env[] = {
+ "PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sbin:/mnt/usr/sbin:/mnt/bin:/mnt/usr/bin",
+ "LD_LIBRARY_PATH=/lib:/usr/lib:/mnt/lib:/mnt/usr/lib:/usr/X11R6/lib:/mnt/usr/X11R6/lib",
+ "HOME=/",
+ "TERM=linux",
+ "TERMINFO=/etc/terminfo",
+ NULL
+};
+
+void pause(void) { unsigned char t; fflush(stdout); read(0, &t, 1); }
+
+
+/* ------ UUURGH this is duplicated from `init.c', don't edit here........ */
+static inline _syscall3(int, reboot, int, magic, int, magic2, int, flag);
+#define LOOP_CLR_FD 0x4C01
+void del_loop(char *device)
+{
+ int fd;
+ if ((fd = open(device, O_RDONLY, 0)) < 0) {
+ printf("del_loop open failed\n");
+ return;
+ }
+
+ if (ioctl(fd, LOOP_CLR_FD, 0) < 0) {
+ printf("del_loop ioctl failed");
+ return;
+ }
+
+ close(fd);
+}
+struct filesystem { char * dev; char * name; char * fs; int mounted; };
+void unmount_filesystems(void)
+{
+ int fd, size;
+ char buf[65535]; /* this should be big enough */
+ char *p;
+ struct filesystem fs[500];
+ int numfs = 0;
+ int i, nb;
+
+ printf("unmounting filesystems...\n");
+
+ fd = open("/proc/mounts", O_RDONLY, 0);
+ if (fd < 1) {
+ printf("ERROR: failed to open /proc/mounts");
+ sleep(2);
+ return;
+ }
+
+ size = read(fd, buf, sizeof(buf) - 1);
+ buf[size] = '\0';
+
+ close(fd);
+
+ p = buf;
+ while (*p) {
+ fs[numfs].mounted = 1;
+ fs[numfs].dev = p;
+ while (*p != ' ') p++;
+ *p++ = '\0';
+ fs[numfs].name = p;
+ while (*p != ' ') p++;
+ *p++ = '\0';
+ fs[numfs].fs = p;
+ while (*p != ' ') p++;
+ *p++ = '\0';
+ while (*p != '\n') p++;
+ p++;
+ if (strcmp(fs[numfs].name, "/") != 0) numfs++; /* skip if root, no need to take initrd root in account */
+ }
+
+ /* Pixel's ultra-optimized sorting algorithm:
+ multiple passes trying to umount everything until nothing moves
+ anymore (a.k.a holy shotgun method) */
+ do {
+ nb = 0;
+ for (i = 0; i < numfs; i++) {
+ /*printf("trying with %s\n", fs[i].name);*/
+ if (fs[i].mounted && umount(fs[i].name) == 0) {
+ if (strncmp(fs[i].dev + sizeof("/dev/") - 1, "loop",
+ sizeof("loop") - 1) == 0)
+ del_loop(fs[i].dev);
+
+ printf("\t%s\n", fs[i].name);
+ fs[i].mounted = 0;
+ nb++;
+ }
+ }
+ } while (nb);
+
+ for (i = nb = 0; i < numfs; i++)
+ if (fs[i].mounted) {
+ printf("\t%s umount failed\n", fs[i].name);
+ if (strcmp(fs[i].fs, "ext2") == 0) nb++; /* don't count not-ext2 umount failed */
+ }
+
+ if (nb) {
+ printf("failed to umount some filesystems\n");
+ while (1);
+ }
+}
+/* ------ UUURGH -- end */
+
+
+int main(int argc, char **argv)
+{
+ enum return_type results;
+
+ char install_bootloader[] = "Re-install Boot Loader";
+ char mount_parts[] = "Mount your partitions under /mnt";
+ char go_to_console[] = "Go to console";
+ char reboot_[] = "Reboot";
+
+ char * actions[] = { install_bootloader, mount_parts, go_to_console, reboot_, NULL };
+ char * choice;
+
+ init_frontend("Welcome to " DISTRIB_NAME " Rescue (" VERSION ") " __DATE__ " " __TIME__);
+
+ do {
+ int pid;
+ char * binary = NULL;
+
+ choice = "";
+ results = ask_from_list("Please choose the desired action.", actions, &choice);
+
+ if (ptr_begins_static_str(choice, install_bootloader)) {
+ binary = "/usr/bin/install_bootloader";
+ }
+ if (ptr_begins_static_str(choice, mount_parts)) {
+ binary = "/usr/bin/guessmounts";
+ }
+ if (ptr_begins_static_str(choice, reboot_)) {
+ finish_frontend();
+ unmount_filesystems();
+ printf("rebooting system\n");
+ sleep(2);
+ reboot(0xfee1dead, 672274793, 0x01234567);
+ }
+
+ if (binary) {
+ int wait_status;
+ suspend_to_console();
+ if (!(pid = fork())) {
+
+ char * child_argv[2];
+ child_argv[0] = binary;
+ child_argv[1] = NULL;
+
+ execve(child_argv[0], child_argv, env);
+ printf("Can't execute binary (%s)\n<press Enter>\n", binary);
+ pause();
+
+ return 33;
+ }
+ while (wait4(-1, &wait_status, 0, NULL) != pid) {};
+ printf("<press Enter to return to Rescue GUI>");
+ pause();
+ resume_from_suspend();
+ if (!WIFEXITED(wait_status) || WEXITSTATUS(wait_status) != 0) {
+ error_message("Program exited abnormally (return code %d).", WEXITSTATUS(wait_status));
+ if (WIFSIGNALED(wait_status))
+ error_message("(received signal %d)", WTERMSIG(wait_status));
+ }
+ }
+
+ } while (results == RETURN_OK && !ptr_begins_static_str(choice, go_to_console));
+
+ finish_frontend();
+ printf("Bye.\n");
+
+ return 0;
+}
diff --git a/mdk-stage1/stdio-frontend.c b/mdk-stage1/stdio-frontend.c
index 0eda5d76c..83e8fd76d 100644
--- a/mdk-stage1/stdio-frontend.c
+++ b/mdk-stage1/stdio-frontend.c
@@ -360,3 +360,7 @@ enum return_type ask_from_entries(char *msg, char ** questions, char *** answers
return RETURN_OK;
}
}
+
+
+void suspend_to_console(void) {}
+void resume_from_suspend(void) {}
diff --git a/rescue/Makefile b/rescue/Makefile
index 59de38f3d..d236ac579 100644
--- a/rescue/Makefile
+++ b/rescue/Makefile
@@ -7,7 +7,7 @@ ROOTDEST = /export
install: rescue_stage2.bz2
cp -f $< $(ROOTDEST)/Mandrake/base
-rescue_stage2.bz2: kernel_read_part list list.$(ARCH) drvinst guessmounts make_rescue_img
+rescue_stage2.bz2: kernel_read_part list list.$(ARCH) drvinst guessmounts lsparts make_rescue_img
./make_rescue_img
clean:
diff --git a/rescue/guessmounts b/rescue/guessmounts
index e2c9f2c55..5adb33d92 100755
--- a/rescue/guessmounts
+++ b/rescue/guessmounts
@@ -1,5 +1,4 @@
#!/usr/bin/perl
-
#
# Guillaume Cottenceau (gc@mandrakesoft.com)
#
@@ -15,9 +14,13 @@
sub cat_ { local *F; open F, $_[0] or $_[1] ? die "cat of file $_[0] failed: $!\n" : return; my @l = <F>; wantarray ? @l : join '', @l }
+sub chomp_ { my @l = map { my $l = $_; chomp $l; $l } @_; wantarray ? @l : $l[0] }
+
+
+my @mounts = cat_('/proc/mounts');
+grep { (split)[1] =~ m|^/mnt$| } @mounts and print("/mnt is already mounted (according to /proc/mounts)\n"), exit 0;
-#- start
system('drvinst'); #- class2text seems broken, I can't detect easily only modules for SCSI storage :-(
print "\nPlease wait, trying to find your root device...\n";
@@ -38,8 +41,10 @@ M: foreach (@parts) {
for my $fs ('ext3', 'ext2', 'reiserfs', 'xfs', 'jfs') {
my $where = $target;
if (!system("mount -t $fs $dev $where 2>/dev/null")) {
- if (-f "$where/etc/fstab") {
- print "Found a probable root partition on $dev (type $fs)\n";
+ if (-r "$where/etc/fstab" && -r "$where/etc/mandrake-release") {
+ print "=> found a Mandrake root partition on $dev\n=> type $fs, version `",
+ chomp_(cat_ "$where/etc/mandrake-release"),
+ "'\n";
@fstab = cat_("$where/etc/fstab");
$root = $dev;
last M;
@@ -52,7 +57,7 @@ M: foreach (@parts) {
}
if ($root) {
- print "\nMounting other partition from fstab on $target...\n";
+ print "\nMounting other partitions from fstab on $target...\n";
foreach (@fstab) {
my ($dev, $where, $type, $opts) = split;
next if (!$type || $dev eq 'none' || $opts =~ /noauto/ ||
@@ -63,17 +68,24 @@ if ($root) {
$opts = join(',', grep { !/codepage=/ && !/iocharset/ } split(',', $opts)); #- vfat opts, we don't have the modules in rescue
$where = "$target$where";
-d $where || mkdir($where) or die "couldn't create $where\n";
- print "Mounting $dev on $where type $type\n";
+ print "\t$dev on $where type $type\n";
system("mount -t $type $dev $where -o $opts");
}
- print "Your partitions are mounted on $target.\n".
- "For example you can use 'chroot $target' to simulate your system.\n".
- "(you can reinstall lilo that way if necessary).\n\n";
+ print "\nYour system is ready on $target.\n\n";
+} else {
+ die "Could not find your root device :-(.\n";
}
+
#-------------------------------------------------
#- $Log$
+#- Revision 1.4 2001/10/24 22:34:01 gc
+#- - add a GUI to the rescue
+#- - provide guessmounts with better efficiency and output, go to console, and reboot
+#- - provide install_bootloader which runs lilo from /mnt if it seems safe
+#- - add lsparts to rescue, which prints partitions with detected types
+#-
#- Revision 1.3 2001/09/07 18:22:54 gc
#- ext3, xfs, jfs
#-
diff --git a/rescue/install_bootloader b/rescue/install_bootloader
new file mode 100755
index 000000000..8bbd6886c
--- /dev/null
+++ b/rescue/install_bootloader
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+#
+# Guillaume Cottenceau (gc@mandrakesoft.com)
+#
+# Copyright 2001 MandrakeSoft
+#
+# This software may be freely redistributed under the terms of the GNU
+# public license.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+
+sub cat_ { local *F; open F, $_[0] or $_[1] ? die "cat of file $_[0] failed: $!\n" : return; my @l = <F>; wantarray ? @l : join '', @l }
+sub chomp_ { my @l = map { my $l = $_; chomp $l; $l } @_; wantarray ? @l : $l[0] }
+
+system('guessmounts') and die;
+
+#- this is dangerous, try to take care
+my @mounts = cat_('/proc/mounts');
+grep { (split)[1] =~ m|^/mnt$| } @mounts or die "Your root device isn't mounted on /mnt (according to /proc/mounts)\n";
+-x '/mnt/sbin/lilo' or die "/mnt/sbin/lilo isn't executable, exiting.\n";
+-r '/mnt/etc/lilo.conf' or die "/mnt/etc/lilo.conf isn't readable, exiting.\n";
+cat_('/mnt/etc/mandrake-release') =~ /Mandrake/ or die "/mnt/etc/mandrake-release doesn't contain 'Mandrake', exiting.\n";
+
+print "About to re-install Boot Loader of following Mandrake distro:\n\t",
+ chomp_(cat_ "/mnt/etc/mandrake-release"),
+ "\n=> ok? <press Enter to continue, 'n' and Enter to cancel> ";
+<STDIN> =~ /^n/i and exit 0;
+
+exec '/mnt/sbin/lilo', '-r', '/mnt';
+
+die "error: couldn't exec /mnt/sbin/lilo.\n";
+
+
+#-------------------------------------------------
+#- $Log$
+#- Revision 1.1 2001/10/24 22:34:01 gc
+#- - add a GUI to the rescue
+#- - provide guessmounts with better efficiency and output, go to console, and reboot
+#- - provide install_bootloader which runs lilo from /mnt if it seems safe
+#- - add lsparts to rescue, which prints partitions with detected types
+#-
+#-
+#-
diff --git a/rescue/lsparts b/rescue/lsparts
new file mode 100755
index 000000000..c73e1ad21
--- /dev/null
+++ b/rescue/lsparts
@@ -0,0 +1,124 @@
+#!/usr/bin/perl
+#
+# Main author Pascal Rigaux (pixel@mandrakesoft.com)
+# Put together by Guillaume Cottenceau (gc@mandrakesoft.com)
+#
+# Copyright 1999,2000,2001 MandrakeSoft
+#
+# This software may be freely redistributed under the terms of the GNU
+# public license.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#
+# This code is extracted from DrakX, the Mandrake Linux graphical installer.
+# http://www.mandrakelinux.com/drakx/
+# Open development rulz, find CVS here:
+# http://www.mandrakelinux.com/cgi-bin/cvsweb.cgi/gi/
+#
+# Detects partition types using signatures
+#
+
+sub cat_ { local *F; open F, $_[0] or $_[1] ? die "cat of file $_[0] failed: $!\n" : return; my @l = <F>; wantarray ? @l : join '', @l }
+
+sub arch() {
+ my $t = `uname -m`;
+ chomp $t;
+ $t;
+}
+
+# from Perl Cookbook / Pleac
+# http://pleac.sourceforge.net/pleac_perl/numbers.html#AEN121
+sub commify {
+ my $text = reverse $_[0];
+ $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
+ return scalar reverse $text;
+}
+
+my @partitions_signatures = (
+ [ 0x8e, 0, "HM\1\0" ],
+ [ 0x83, 0x438, "\x53\xEF" ],
+ [ 0x183, 0x10034, "ReIsErFs" ],
+ [ 0x183, 0x10034, "ReIsEr2Fs" ],
+ [ 0x283, 0, 'XFSB', 0x200, 'XAGF', 0x400, 'XAGI' ],
+ [ 0x383, 0x8000, 'JFS1' ],
+ [ 0x82, 4086, "SWAP-SPACE" ],
+ [ 0x82, 4086, "SWAPSPACE2" ],
+ [ 0x7, 0x1FE, "\x55\xAA", 0x3, "NTFS" ],
+ [ 0xc, 0x1FE, "\x55\xAA", 0x52, "FAT32" ],
+arch() !~ /^sparc/ ? (
+ [ 0x6, 0x1FE, "\x55\xAA", 0x36, "FAT" ],
+) : (),
+);
+
+sub typeFromMagic {
+ my $f = shift;
+ local *F; sysopen F, $f, 0 or return;
+
+ my $tmp;
+ M: foreach (@partitions_signatures) {
+ my ($name, @l) = @$_;
+ while (@l) {
+ my ($offset, $signature) = splice(@l, 0, 2);
+ sysseek(F, $offset, 0) or next M;
+ sysread(F, $tmp, length $signature);
+ $tmp eq $signature or next M;
+ }
+ return $name;
+ }
+ return -1;
+}
+
+my %type2name = (
+ 0x1 => 'DOS 12-bit FAT',
+ 0x4 => 'DOS 16-bit FAT (up to 32M)',
+ 0x5 => 'DOS 3.3+ Extended Partition',
+ 0x6 => 'DOS FAT16',
+ 0x7 => 'NTFS (or HPFS)',
+ 0xb => 'Win98 FAT32',
+ 0xc => 'Win98 FAT32, LBA-mapped',
+ 0xe => 'Win95: DOS 16-bit FAT, LBA-mapped',
+ 0xf => 'Win95: Extended partition, LBA-mapped',
+ 0x82 => 'Linux Swap',
+ 0x83 => 'Ext2',
+ 0x183 => 'ReiserFS',
+ 0x283 => 'XFS',
+ 0x383 => 'JFS',
+ 0x85 => 'Linux extended partition',
+ 0x87 => 'NTFS volume set',
+ 0x8e => 'Linux LVM',
+ -1 => 'unknown'
+ );
+
+
+my $params = join '', @ARGV;
+
+$params =~ /-h/ and die "usage: lsparts [-v]\n";
+$params =~ /-v/ and $verbose = 1;
+
+
+my (undef, undef, @parts) = cat_('/proc/partitions');
+
+P: foreach (@parts) {
+ my (undef, undef, $blocks, $dev) = split or next;
+ my %skip_conditions = (
+ "Skipping <$dev> because too little blocks ($blocks)" => ($blocks <= 1),
+ "Skipping <$dev> because doesn't end with a number (e.g. seems to not be a partition)" => ($dev !~ /\d$/),
+ );
+ $skip_conditions{$_} and ($verbose and print(STDERR $_, "\n")), next P foreach keys %skip_conditions;
+ my $type = typeFromMagic("/dev/$dev");
+ $type and printf "$dev: %6s Mbytes, type <0x%x> (%s)\n", commify($blocks >> 10), $type, $type2name{$type};
+}
+
+
+#-------------------------------------------------
+#- $Log$
+#- Revision 1.1 2001/10/24 22:34:01 gc
+#- - add a GUI to the rescue
+#- - provide guessmounts with better efficiency and output, go to console, and reboot
+#- - provide install_bootloader which runs lilo from /mnt if it seems safe
+#- - add lsparts to rescue, which prints partitions with detected types
+#-
+#
diff --git a/rescue/make_rescue_img b/rescue/make_rescue_img
index e3bb4e8ed..e6c744e53 100755
--- a/rescue/make_rescue_img
+++ b/rescue/make_rescue_img
@@ -86,6 +86,10 @@ _ "cp ../all.modules/$main/modules.dep $tmp/modules";
installown("drvinst", "/usr/bin");
installown("guessmounts", "/usr/bin");
+installown("install_bootloader", "/usr/bin");
+installown("lsparts", "/usr/bin");
+_ "cd ../mdk-stage1 && make rescue-gui";
+installown("../mdk-stage1/rescue-gui", "/usr/bin");
__ "strip $tmp/{lib,bin,sbin}/* $tmp/usr/{bin,sbin}/* 2>/dev/null";
diff --git a/rescue/tree/etc/issue b/rescue/tree/etc/issue
index 55da5cd1e..a38b2f1a3 100644
--- a/rescue/tree/etc/issue
+++ b/rescue/tree/etc/issue
@@ -18,9 +18,10 @@
      

-Mandrake Linux release 8.1 (Cooker)
+Mandrake Linux release 8.2 (Cooker)
Use loadkeys to change your keyboard layout (eg: loadkeys fr)
Use modprobe to load modules (eg: modprobe snd-card-fm801)
Use drvinst to install drivers according to detected devices
+Use lsparts to list your partitions with types
diff --git a/rescue/tree/etc/rc.sysinit b/rescue/tree/etc/rc.sysinit
index c33983cca..444e0c064 100755
--- a/rescue/tree/etc/rc.sysinit
+++ b/rescue/tree/etc/rc.sysinit
@@ -41,11 +41,6 @@ grep -q oem /proc/cmdline && exec /etc/oem -f
/sbin/ifconfig lo 127.0.0.1 netmask 255.0.0.0
/sbin/route add 127.0.0.1 lo
-if ! grep -q noguessmounts /proc/cmdline; then
- echo "I will try now to guess your mountpoints;"
- echo -e "If any problems, reboot and enter \\033[1;37mrescue noguessmounts\\033[0;39m to disable this."
- echo ""
- guessmounts
- echo "Press <enter> to continue"
- read
+if ! grep -q expert /proc/cmdline; then
+ rescue-gui
fi