As early as possible, create a link /bsd.booted to the /bsd kernel we
authorderaadt <deraadt@openbsd.org>
Mon, 19 Jun 2017 22:50:50 +0000 (22:50 +0000)
committerderaadt <deraadt@openbsd.org>
Mon, 19 Jun 2017 22:50:50 +0000 (22:50 +0000)
presume we booted from.  If you boot from another kernel, we cannot help
you later with hibernate, sorry -- The kernel does not get a useable
filename from the bootblocks.

In the bootblocks, detect a live hibernate signature and boot from
/bsd.booted instead.

with yasuoka, lots of discussion with mlarkin, ok tom

etc/rc
sys/arch/amd64/include/biosvar.h
sys/arch/amd64/stand/boot/Makefile
sys/arch/amd64/stand/efiboot/Makefile.common
sys/arch/amd64/stand/libsa/diskprobe.c
sys/arch/i386/include/biosvar.h
sys/arch/i386/stand/boot/Makefile
sys/arch/i386/stand/libsa/diskprobe.c
sys/stand/boot/boot.c

diff --git a/etc/rc b/etc/rc
index 4a1e190..1bdac68 100644 (file)
--- a/etc/rc
+++ b/etc/rc
@@ -1,4 +1,4 @@
-#      $OpenBSD: rc,v 1.502 2017/06/14 21:39:53 rpe Exp $
+#      $OpenBSD: rc,v 1.503 2017/06/19 22:50:50 deraadt Exp $
 
 # System startup script run by init on autoboot or after single-user.
 # Output and error are redirected to console by init, and the console is the
@@ -377,6 +377,7 @@ mount -a -t nonfs,vnd
 # others aren't hurt.)
 mount -uw /
 chmod og-rwx /bsd
+ln -fh /bsd /bsd.booted
 
 rm -f /fastboot
 
index 2ffd366..8eaf605 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: biosvar.h,v 1.22 2015/08/30 10:05:09 yasuoka Exp $    */
+/*     $OpenBSD: biosvar.h,v 1.23 2017/06/19 22:50:50 deraadt Exp $    */
 
 /*
  * Copyright (c) 1997-1999 Michael Shalayeff
@@ -131,6 +131,7 @@ typedef struct _bios_diskinfo {
 #define BDI_GOODLABEL  0x00000002      /* Had SCSI or ST506/ESDI disklabel */
 #define BDI_BADLABEL   0x00000004      /* Had another disklabel */
 #define BDI_EL_TORITO  0x00000008      /* 2,048-byte sectors */
+#define BDI_HIBVALID   0x00000010      /* hibernate signiture valid */
 #define BDI_PICKED     0x80000000      /* kernel-only: cksum matched */
 
 } __packed bios_diskinfo_t;
index ebb431a..aab8a1e 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.37 2017/05/30 22:32:10 naddy Exp $
+#      $OpenBSD: Makefile,v 1.38 2017/06/19 22:50:50 deraadt Exp $
 
 COPTS?=
 MAN?=  boot.8
@@ -75,6 +75,7 @@ CPPFLAGS+=-DSOFTRAID
 .endif
 CPPFLAGS+=-DBOOTMAGIC=$(BOOTMAGIC) ${DEBUGFLAGS} -DLINKADDR=${LINKADDR}
 CPPFLAGS+=-DSLOW -DSMALL -DNOBYFOUR -DNO_GZIP -DDYNAMIC_CRC_TABLE
+CPPFLAGS+=-DHIBERNATE
 CPPFLAGS+=-DHEAP_LIMIT=${HEAP_LIMIT} -I${S}/stand/boot #-DCOMPAT_UFS
 CFLAGS+=-m32 $(SACFLAGS) -D__INTERNAL_LIBSA_CREAD -fno-pie
 AFLAGS+=${NO_INTEGR_AS}
index d821e0b..6dc1cde 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile.common,v 1.10 2016/09/18 16:34:59 jsing Exp $
+#      $OpenBSD: Makefile.common,v 1.11 2017/06/19 22:50:50 deraadt Exp $
 
 S=             ${.CURDIR}/../../../../..
 SADIR=         ${.CURDIR}/../..
@@ -68,7 +68,7 @@ ${PROG}: ${PROG.so}
 .include <bsd.prog.mk>
 CFLAGS+=       -Wno-pointer-sign
 CPPFLAGS+=     -DSMALL -DSLOW -DNOBYFOUR -D__INTERNAL_LIBSA_CREAD
-CPPFLAGS+=     -DHEAP_LIMIT=${EFI_HEAP_LIMIT}
+CPPFLAGS+=     -DHEAP_LIMIT=${EFI_HEAP_LIMIT} -DHIBERNATE
 
 ${PROG.so}: ${OBJS}
        ${LD} ${LDFLAGS} -o ${.TARGET}.tmp ${OBJS} ${LDADD}
index ba6f875..48dfb61 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: diskprobe.c,v 1.17 2016/09/11 15:54:11 jsing Exp $    */
+/*     $OpenBSD: diskprobe.c,v 1.18 2017/06/19 22:50:50 deraadt Exp $  */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
@@ -34,6 +34,7 @@
 #include <sys/queue.h>
 #include <sys/reboot.h>
 #include <sys/disklabel.h>
+#include <sys/hibernate.h>
 
 #include <lib/libz/zlib.h>
 #include <machine/biosvar.h>
@@ -54,6 +55,9 @@
 
 /* Local Prototypes */
 static int disksum(int);
+static void check_hibernate(struct diskinfo *);
+
+int bootdev_has_hibernate(void);               /* export for loadfile() */
 
 /* List of disk devices we found/probed */
 struct disklist_lh disklist;
@@ -169,8 +173,9 @@ hardprobe(void)
 
                dip->bios_info.checksum = 0; /* just in case */
                /* Fill out best we can */
-               dip->bios_info.bsd_dev =
+               dip->bsddev = dip->bios_info.bsd_dev =
                    MAKEBOOTDEV(type, 0, 0, bsdunit, RAW_PART);
+               check_hibernate(dip);
 
                /* Add to queue of disks */
                TAILQ_INSERT_TAIL(&disklist, dip, list);
@@ -224,8 +229,9 @@ efi_hardprobe(void)
 
                dip->bios_info.checksum = 0; /* just in case */
                /* Fill out best we can */
-               dip->bios_info.bsd_dev =
+               dip->bsddev = dip->bios_info.bsd_dev =
                    MAKEBOOTDEV(type, 0, 0, bsdunit, RAW_PART);
+               check_hibernate(dip);
 
                /* Add to queue of disks */
                TAILQ_INSERT_TAIL(&disklist, dip, list);
@@ -459,3 +465,31 @@ disksum(int blk)
 
        return reprobe;
 }
+
+int
+bootdev_has_hibernate(void)
+{
+       return ((bootdev_dip->bios_info.flags & BDI_HIBVALID)? 1 : 0);
+}
+
+static void
+check_hibernate(struct diskinfo *dip)
+{
+       daddr_t sec;
+       int error;
+       union hibernate_info hib;
+
+       /* read hibernate */
+       if (dip->disklabel.d_partitions[1].p_fstype != FS_SWAP ||
+           DL_GETPSIZE(&dip->disklabel.d_partitions[1]) == 0)
+               return;
+
+       sec = DL_GETPOFFSET(&dip->disklabel.d_partitions[1]) +
+           DL_GETPSIZE(&dip->disklabel.d_partitions[1]) -
+            (sizeof(union hibernate_info) / DEV_BSIZE);
+
+       error = dip->strategy(dip, F_READ, (daddr32_t)sec, sizeof hib, &hib, NULL);
+       if (error == 0 && hib.magic == HIBERNATE_MAGIC) /* Hibernate present */
+               dip->bios_info.flags |= BDI_HIBVALID;
+       printf("&");
+}
index f51b2d0..2811c94 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: biosvar.h,v 1.64 2015/09/03 15:52:16 deraadt Exp $    */
+/*     $OpenBSD: biosvar.h,v 1.65 2017/06/19 22:50:50 deraadt Exp $    */
 
 /*
  * Copyright (c) 1997-1999 Michael Shalayeff
@@ -161,6 +161,7 @@ typedef struct _bios_diskinfo {
 #define BDI_GOODLABEL  0x00000002      /* Had SCSI or ST506/ESDI disklabel */
 #define BDI_BADLABEL   0x00000004      /* Had another disklabel */
 #define BDI_EL_TORITO  0x00000008      /* 2,048-byte sectors */
+#define BDI_HIBVALID   0x00000010      /* hibernate signiture valid */
 #define BDI_PICKED     0x80000000      /* kernel-only: cksum matched */
 
 } __packed bios_diskinfo_t;
index 52b440e..82dc91f 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.65 2017/06/01 11:18:53 naddy Exp $
+#      $OpenBSD: Makefile,v 1.66 2017/06/19 22:50:50 deraadt Exp $
 
 COPTS?=
 MAN?=  boot.8
@@ -79,6 +79,7 @@ CPPFLAGS+=-DSOFTRAID
 .endif
 CPPFLAGS+=-DBOOTMAGIC=$(BOOTMAGIC) ${DEBUGFLAGS} -DLINKADDR=${LINKADDR}
 CPPFLAGS+=-DSLOW -DSMALL -DNOBYFOUR -DNO_GZIP -DDYNAMIC_CRC_TABLE
+CPPFLAGS+=-DHIBERNATE
 CPPFLAGS+=-DHEAP_LIMIT=${HEAP_LIMIT} -I${S}/stand/boot #-DCOMPAT_UFS
 CFLAGS+=-m32 $(SACFLAGS) -D__INTERNAL_LIBSA_CREAD -fno-pie
 AFLAGS+=${NO_INTEGR_AS}
index 9b8947c..2d30b9d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: diskprobe.c,v 1.41 2016/09/11 15:54:11 jsing Exp $    */
+/*     $OpenBSD: diskprobe.c,v 1.42 2017/06/19 22:50:50 deraadt Exp $  */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
@@ -34,6 +34,7 @@
 #include <sys/queue.h>
 #include <sys/reboot.h>
 #include <sys/disklabel.h>
+#include <sys/hibernate.h>
 
 #include <lib/libz/zlib.h>
 #include <machine/biosvar.h>
@@ -54,6 +55,9 @@
 
 /* Local Prototypes */
 static int disksum(int);
+static void check_hibernate(struct diskinfo *);
+
+int bootdev_has_hibernate(void);               /* export for loadfile() */
 
 /* List of disk devices we found/probed */
 struct disklist_lh disklist;
@@ -169,8 +173,9 @@ hardprobe(void)
 
                dip->bios_info.checksum = 0; /* just in case */
                /* Fill out best we can */
-               dip->bios_info.bsd_dev =
+               dip->bsddev = dip->bios_info.bsd_dev =
                    MAKEBOOTDEV(type, 0, 0, bsdunit, RAW_PART);
+               check_hibernate(dip);
 
                /* Add to queue of disks */
                TAILQ_INSERT_TAIL(&disklist, dip, list);
@@ -224,8 +229,9 @@ efi_hardprobe(void)
 
                dip->bios_info.checksum = 0; /* just in case */
                /* Fill out best we can */
-               dip->bios_info.bsd_dev =
+               dip->bsddev = dip->bios_info.bsd_dev =
                    MAKEBOOTDEV(type, 0, 0, bsdunit, RAW_PART);
+               check_hibernate(dip);
 
                /* Add to queue of disks */
                TAILQ_INSERT_TAIL(&disklist, dip, list);
@@ -459,3 +465,31 @@ disksum(int blk)
 
        return reprobe;
 }
+
+int
+bootdev_has_hibernate(void)
+{
+       return ((bootdev_dip->bios_info.flags & BDI_HIBVALID)? 1 : 0);
+}
+
+static void
+check_hibernate(struct diskinfo *dip)
+{
+       daddr_t sec;
+       int error;
+       union hibernate_info hib;
+
+       /* read hibernate */
+       if (dip->disklabel.d_partitions[1].p_fstype != FS_SWAP ||
+           DL_GETPSIZE(&dip->disklabel.d_partitions[1]) == 0)
+               return;
+
+       sec = DL_GETPOFFSET(&dip->disklabel.d_partitions[1]) +
+           DL_GETPSIZE(&dip->disklabel.d_partitions[1]) -
+            (sizeof(union hibernate_info) / DEV_BSIZE);
+
+       error = dip->strategy(dip, F_READ, (daddr32_t)sec, sizeof hib, &hib, NULL);
+       if (error == 0 && hib.magic == HIBERNATE_MAGIC) /* Hibernate present */
+               dip->bios_info.flags |= BDI_HIBVALID;
+       printf("&");
+}
index 1365daf..fc8b0fc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: boot.c,v 1.43 2014/02/19 22:02:15 miod Exp $  */
+/*     $OpenBSD: boot.c,v 1.44 2017/06/19 22:50:50 deraadt Exp $       */
 
 /*
  * Copyright (c) 2003 Dale Rahn
@@ -77,6 +77,16 @@ boot(dev_t bootdev)
        cmd.timeout = boottimeout;
 
        st = read_conf();
+
+#ifdef HIBERNATE
+       int bootdev_has_hibernate(void);
+
+       if (bootdev_has_hibernate()) {
+               strlcpy(cmd.image, "/bsd.booted", sizeof(cmd.image));
+               printf("unhibernate detected: switching to %s\n", cmd.image);
+       }
+#endif
+
        if (!bootprompt)
                snprintf(cmd.path, sizeof cmd.path, "%s:%s",
                    cmd.bootdev, cmd.image);