Author: randi
Date: Thu Jul  8 21:26:26 2010
New Revision: 209832
URL: http://svn.freebsd.org/changeset/base/209832

Log:
  Revert r209787 pending further discussion.
  
  Approved by:  cperciva (mentor)

Added:
  head/usr.sbin/sysinstall/installUpgrade.c
     - copied unchanged from r209786, head/usr.sbin/sysinstall/installUpgrade.c
Modified:
  head/usr.sbin/sysinstall/Makefile
  head/usr.sbin/sysinstall/dispatch.c
  head/usr.sbin/sysinstall/install.c
  head/usr.sbin/sysinstall/menus.c
  head/usr.sbin/sysinstall/sysinstall.8
  head/usr.sbin/sysinstall/sysinstall.h

Modified: head/usr.sbin/sysinstall/Makefile
==============================================================================
--- head/usr.sbin/sysinstall/Makefile   Thu Jul  8 21:02:31 2010        
(r209831)
+++ head/usr.sbin/sysinstall/Makefile   Thu Jul  8 21:26:26 2010        
(r209832)
@@ -8,7 +8,7 @@ PROG=   sysinstall
 MAN=   sysinstall.8
 SRCS=  anonFTP.c cdrom.c command.c config.c devices.c dhcp.c \
        disks.c dispatch.c dist.c dmenu.c doc.c dos.c floppy.c \
-       ftp.c globals.c http.c index.c install.c keymap.c \
+       ftp.c globals.c http.c index.c install.c installUpgrade.c keymap.c \
        label.c main.c makedevs.c media.c menus.c misc.c modules.c \
        mouse.c msg.c network.c nfs.c options.c package.c \
        system.c tcpip.c termcap.c ttys.c ufs.c usb.c user.c \

Modified: head/usr.sbin/sysinstall/dispatch.c
==============================================================================
--- head/usr.sbin/sysinstall/dispatch.c Thu Jul  8 21:02:31 2010        
(r209831)
+++ head/usr.sbin/sysinstall/dispatch.c Thu Jul  8 21:26:26 2010        
(r209832)
@@ -82,6 +82,7 @@ static struct _word {
     { "installCommit",         installCommit           },
     { "installExpress",                installExpress          },
     { "installStandard",       installStandard         },
+    { "installUpgrade",                installUpgrade          },
     { "installFixupBase",      installFixupBase        },
     { "installFixitHoloShell", installFixitHoloShell   },
     { "installFixitCDROM",     installFixitCDROM       },

Modified: head/usr.sbin/sysinstall/install.c
==============================================================================
--- head/usr.sbin/sysinstall/install.c  Thu Jul  8 21:02:31 2010        
(r209831)
+++ head/usr.sbin/sysinstall/install.c  Thu Jul  8 21:26:26 2010        
(r209832)
@@ -1032,11 +1032,13 @@ installFilesystems(dialogMenuItem *self)
     Device **devs;
     PartInfo *root;
     char dname[80];
+    Boolean upgrade = FALSE;
 
     /* If we've already done this, bail out */
     if (!variable_cmp(DISK_LABELLED, "written"))
        return DITEM_SUCCESS;
 
+    upgrade = !variable_cmp(SYSTEM_STATE, "upgrade");
     if (!checkLabels(TRUE))
        return DITEM_FAILURE;
 
@@ -1076,7 +1078,9 @@ installFilesystems(dialogMenuItem *self)
        if (strcmp(root->mountpoint, "/"))
            msgConfirm("Warning: %s is marked as a root partition but is 
mounted on %s", RootChunk->name, root->mountpoint);
 
-       if (root->do_newfs) {
+       if (root->do_newfs && (!upgrade ||
+           !msgNoYes("You are upgrading - are you SURE you want to newfs "
+           "the root partition?"))) {
            int i;
 
            dialog_clear_norefresh();
@@ -1089,7 +1093,9 @@ installFilesystems(dialogMenuItem *self)
            }
        }
        else {
-           msgConfirm("Warning:  Using existing root partition.");
+           if (!upgrade) {
+               msgConfirm("Warning:  Using existing root partition.");
+           }
            dialog_clear_norefresh();
            msgNotify("Checking integrity of existing %s filesystem.", dname);
            i = vsystem("fsck_ffs -y %s", dname);
@@ -1173,7 +1179,9 @@ installFilesystems(dialogMenuItem *self)
                        sprintf(dname, "%s/dev/%s",
                            RunningAsInit ? "/mnt" : "", c2->name);
 
-                       if (tmp->do_newfs) 
+                       if (tmp->do_newfs && (!upgrade ||
+                           !msgNoYes("You are upgrading - are you SURE you"
+                           " want to newfs /dev/%s?", c2->name)))
                                performNewfs(tmp, dname, QUEUE_YES);
                        else
                            command_shell_add(tmp->mountpoint,
@@ -1206,7 +1214,7 @@ installFilesystems(dialogMenuItem *self)
                }
            }
            else if (c1->type == fat && c1->private_data &&
-               (root->do_newfs)) {
+               (root->do_newfs || upgrade)) {
                char name[FILENAME_MAX];
 
                sprintf(name, "%s/%s", RunningAsInit ? "/mnt" : "", ((PartInfo 
*)c1->private_data)->mountpoint);
@@ -1219,7 +1227,9 @@ installFilesystems(dialogMenuItem *self)
                sprintf(dname, "%s/dev/%s", RunningAsInit ? "/mnt" : "",
                    c1->name);
 
-               if (pi->do_newfs)
+               if (pi->do_newfs && (!upgrade ||
+                   !msgNoYes("You are upgrading - are you SURE you want to "
+                   "newfs /dev/%s?", c1->name)))
                        performNewfs(pi, dname, QUEUE_YES);
 
                command_func_add(pi->mountpoint, Mount_msdosfs, c1->name);

Copied: head/usr.sbin/sysinstall/installUpgrade.c (from r209786, 
head/usr.sbin/sysinstall/installUpgrade.c)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/usr.sbin/sysinstall/installUpgrade.c   Thu Jul  8 21:26:26 2010        
(r209832, copy of r209786, head/usr.sbin/sysinstall/installUpgrade.c)
@@ -0,0 +1,526 @@
+/*
+ * The new sysinstall program.
+ *
+ * This is probably the last program in the `sysinstall' line - the next
+ * generation being essentially a complete rewrite.
+ *
+ * $FreeBSD$
+ *
+ * Copyright (c) 1995
+ *     Jordan Hubbard.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    verbatim and that no modifications are made prior to this
+ *    point in the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include "sysinstall.h"
+#include <sys/disklabel.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/fcntl.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/mount.h>
+
+static int installUpgradeNonInteractive(dialogMenuItem *self);
+
+typedef struct _hitList {
+    enum { JUST_COPY, CALL_HANDLER } action ;
+    char *name;
+    Boolean optional;
+    void (*handler)(struct _hitList *self);
+} HitList;
+
+/* These are the only meaningful files I know about */
+static HitList etc_files [] = {
+   { JUST_COPY,                "Xaccel.ini",           TRUE, NULL },
+   { JUST_COPY,                "X11",                  TRUE, NULL },
+   { JUST_COPY,                "adduser.conf",         TRUE, NULL },
+   { JUST_COPY,                "aliases",              TRUE, NULL },
+   { JUST_COPY,                "aliases.db",           TRUE, NULL },
+   { JUST_COPY,                "amd.map",              TRUE, NULL },
+   { JUST_COPY,                "auth.conf",            TRUE, NULL },
+   { JUST_COPY,                "crontab",              TRUE, NULL },
+   { JUST_COPY,                "csh.cshrc",            TRUE, NULL },
+   { JUST_COPY,                "csh.login",            TRUE, NULL },
+   { JUST_COPY,                "csh.logout",           TRUE, NULL },
+   { JUST_COPY,                "cvsupfile",            TRUE, NULL },
+   { JUST_COPY,                "devfs.conf",           TRUE, NULL },
+   { JUST_COPY,                "dhclient.conf",        TRUE, NULL },
+   { JUST_COPY,                "disktab",              TRUE, NULL },
+   { JUST_COPY,                "dumpdates",            TRUE, NULL },
+   { JUST_COPY,                "exports",              TRUE, NULL },
+   { JUST_COPY,                "fbtab",                TRUE, NULL },
+   { JUST_COPY,                "fstab",                FALSE, NULL },
+   { JUST_COPY,                "ftpusers",             TRUE, NULL },
+   { JUST_COPY,                "gettytab",             TRUE, NULL },
+   { JUST_COPY,                "gnats",                TRUE, NULL },
+   { JUST_COPY,                "group",                FALSE, NULL },
+   { JUST_COPY,                "hosts",                TRUE, NULL },
+   { JUST_COPY,                "hosts.allow",          TRUE, NULL },
+   { JUST_COPY,                "hosts.equiv",          TRUE, NULL },
+   { JUST_COPY,                "hosts.lpd",            TRUE, NULL },
+   { JUST_COPY,                "inetd.conf",           TRUE, NULL },
+   { JUST_COPY,                "localtime",            TRUE, NULL },
+   { JUST_COPY,                "login.access",         TRUE, NULL },
+   { JUST_COPY,                "login.conf",           TRUE, NULL },
+   { JUST_COPY,                "mail",                 TRUE, NULL },
+   { JUST_COPY,                "mail.rc",              TRUE, NULL },
+   { JUST_COPY,                "mac.conf",             TRUE, NULL },
+   { JUST_COPY,                "make.conf",            TRUE, NULL },
+   { JUST_COPY,                "manpath.config",       TRUE, NULL },
+   { JUST_COPY,                "master.passwd",        FALSE, NULL },
+   { JUST_COPY,                "mergemaster.rc",       TRUE, NULL },
+   { JUST_COPY,                "motd",                 TRUE, NULL },
+   { JUST_COPY,                "namedb",               TRUE, NULL },
+   { JUST_COPY,                "networks",             TRUE, NULL },
+   { JUST_COPY,                "newsyslog.conf",       TRUE, NULL },
+   { JUST_COPY,                "nsmb.conf",            TRUE, NULL },
+   { JUST_COPY,                "nsswitch.conf",        TRUE, NULL },
+   { JUST_COPY,                "ntp.conf",             TRUE, NULL },
+   { JUST_COPY,                "pam.conf",             TRUE, NULL },
+   { JUST_COPY,                "passwd",               TRUE, NULL },
+   { JUST_COPY,                "periodic",             TRUE, NULL },
+   { JUST_COPY,                "pf.conf",              TRUE, NULL },
+   { JUST_COPY,                "portsnap.conf",        TRUE, NULL },
+   { JUST_COPY,                "ppp",                  TRUE, NULL },
+   { JUST_COPY,                "printcap",             TRUE, NULL },
+   { JUST_COPY,                "profile",              TRUE, NULL },
+   { JUST_COPY,                "protocols",            TRUE, NULL },
+   { JUST_COPY,                "pwd.db",               TRUE, NULL },
+   { JUST_COPY,                "rc.local",             TRUE, NULL },
+   { JUST_COPY,                "rc.firewall",          TRUE, NULL },
+   { JUST_COPY,                "rc.conf.local",        TRUE, NULL },
+   { JUST_COPY,                "remote",               TRUE, NULL },
+   { JUST_COPY,                "resolv.conf",          TRUE, NULL },
+   { JUST_COPY,                "rmt",                  TRUE, NULL },
+   { JUST_COPY,                "sendmail.cf",          TRUE, NULL },
+   { JUST_COPY,                "sendmail.cw",          TRUE, NULL },
+   { JUST_COPY,                "services",             TRUE, NULL },
+   { JUST_COPY,                "shells",               TRUE, NULL },
+   { JUST_COPY,                "skeykeys",             TRUE, NULL },
+   { JUST_COPY,                "snmpd.config",         TRUE, NULL },
+   { JUST_COPY,                "spwd.db",              TRUE, NULL },
+   { JUST_COPY,                "src.conf",             TRUE, NULL },
+   { JUST_COPY,                "ssh",                  TRUE, NULL },
+   { JUST_COPY,                "sysctl.conf",          TRUE, NULL },
+   { JUST_COPY,                "syslog.conf",          TRUE, NULL },
+   { JUST_COPY,                "ttys",                 TRUE, NULL },
+   { 0,                        NULL,                   FALSE, NULL },
+};
+
+static void
+traverseHitlist(HitList *h)
+{
+    system("rm -rf /etc/upgrade");
+    Mkdir("/etc/upgrade");
+    while (h->name) {
+       if (!file_readable(h->name)) {
+           if (!h->optional)
+               msgConfirm("Unable to find an old /etc/%s file!  That is 
decidedly non-standard and\n"
+                          "your upgraded system may function a little 
strangely as a result.", h->name);
+       }
+       else {
+           if (h->action == JUST_COPY) {
+               /* Move the just-loaded copy aside */
+               vsystem("mv /etc/%s /etc/upgrade/%s", h->name, h->name);
+
+               /* Copy the old one into its place */
+               msgNotify("Resurrecting %s..", h->name);
+               /* Do this with tar so that symlinks and such are preserved */
+               if (vsystem("tar cf - %s | tar xpf - -C /etc", h->name))
+                   msgConfirm("Unable to resurrect your old /etc/%s!  Hmmmm.", 
h->name);
+           }
+           else /* call handler */
+               h->handler(h);
+       }
+       ++h;
+    }
+}
+
+int
+installUpgrade(dialogMenuItem *self)
+{
+    char saved_etc[FILENAME_MAX];
+    Boolean extractingBin = TRUE;
+
+    if (variable_get(VAR_NONINTERACTIVE))
+       return installUpgradeNonInteractive(self);
+
+    variable_set2(SYSTEM_STATE, "upgrade", 0);
+    dialog_clear();
+
+    if (msgYesNo("Before beginning a binary upgrade, please review the upgrade 
instructions,\n"
+                "which are located in the \"Install\" document under the main 
documentation\n"
+                "menu.  Given that you have read these instructions and 
understand the risks\n"
+                "and precautions involved, are you sure that you want to 
proceed with\n"
+                "this upgrade?") != 0)
+       return DITEM_FAILURE;
+
+    if (!Dists) {
+       msgConfirm("First, you must select some distribution components.  The 
upgrade procedure\n"
+                  "will only upgrade the distributions you select in the next 
set of menus.");
+       if (!dmenuOpenSimple(&MenuDistributions, FALSE) || !Dists)
+           return DITEM_FAILURE;
+    }
+    else if (!(Dists & DIST_BASE)) {       /* No base selected?  Not much of 
an upgrade.. */
+       if (msgYesNo("You didn't select the base distribution as one of the 
distributons to load.\n"
+                    "This one is pretty vital to a successful upgrade.  Are 
you SURE you don't\n"
+                    "want to select the base distribution?  Chose No to bring 
up the Distributions\n"
+                    "menu again.") != 0) {
+           if (!dmenuOpenSimple(&MenuDistributions, FALSE))
+               return DITEM_FAILURE;
+       }
+    }
+
+    /* Still?!  OK!  They must know what they're doing.. */
+    if (!(Dists & DIST_BASE))
+       extractingBin = FALSE;
+
+    if (RunningAsInit) {
+       Device **devs;
+       int i, cnt;
+       char *cp;
+
+       cp = variable_get(VAR_DISK);
+       devs = deviceFind(cp, DEVICE_TYPE_DISK);
+       cnt = deviceCount(devs);
+       if (!cnt) {
+           msgConfirm("No disks found!  Please verify that your disk 
controller is being\n"
+                      "properly probed at boot time.  See the Hardware Guide 
on the\n"
+                      "Documentation menu for clues on diagnosing this type of 
problem.");
+           return DITEM_FAILURE | DITEM_RESTORE;
+       }
+       else {
+           /* Enable all the drives before we start */
+           for (i = 0; i < cnt; i++)
+               devs[i]->enabled = TRUE;
+       }
+
+       msgConfirm("OK.  First, we're going to go to the disk label editor.  In 
this editor\n"
+                  "you will be expected to Mount any partitions you're 
interested in\n"
+                  "upgrading.  DO NOT set the Newfs flag to Y on anything in 
the label editor\n"
+                  "unless you're absolutely sure you know what you're doing!  
In this\n"
+                  "instance, you'll be using the label editor as little more 
than a fancy\n"
+                  "screen-oriented partition mounting tool.\n\n"
+                  "Once you're done in the label editor, press Q to return 
here for the next\n"
+                  "step.");
+
+       if (DITEM_STATUS(diskLabelEditor(self)) == DITEM_FAILURE) {
+           msgConfirm("The disk label editor returned an error status.  
Upgrade operation\n"
+                      "aborted.");
+           return DITEM_FAILURE | DITEM_RESTORE;
+       }
+
+       /* Don't write out MBR info */
+       variable_set2(DISK_PARTITIONED, "written", 0);
+       if (DITEM_STATUS(diskLabelCommit(self)) == DITEM_FAILURE) {
+           msgConfirm("Not all file systems were properly mounted.  Upgrade 
operation\n"
+                      "aborted.");
+           variable_unset(DISK_PARTITIONED);
+           return DITEM_FAILURE | DITEM_RESTORE;
+       }
+
+       msgNotify("Updating /stand on root filesystem");
+       (void)vsystem("find -x /stand | cpio %s -pdum /mnt", cpioVerbosity());
+
+       if (DITEM_STATUS(chroot("/mnt")) == DITEM_FAILURE) {
+           msgConfirm("Unable to chroot to /mnt - something is wrong with 
the\n"
+                      "root partition or the way it's mounted if this doesn't 
work.");
+           variable_unset(DISK_PARTITIONED);
+           return DITEM_FAILURE | DITEM_RESTORE;
+       }
+       chdir("/");
+       installEnvironment();
+       systemCreateHoloshell();
+    }
+
+    saved_etc[0] = '\0';
+
+    /* Don't allow sources to be upgraded if we have src already */
+    if (directory_exists("/usr/src/") && (Dists & DIST_SRC)) {
+       Dists &= ~DIST_SRC;
+       SrcDists = 0;
+       msgConfirm("Warning: /usr/src exists and sources were selected as 
upgrade\n"
+                  "targets.  Unfortunately, this is not the way to upgrade 
your\n"
+                  "sources - please use CTM or CVSup or some other method 
which\n"
+                  "handles ``deletion events'', unlike this particular 
feature.\n\n"
+                  "Your existing /usr/src will not be affected by this 
upgrade.\n");
+    }
+
+    if (extractingBin) {
+       while (!*saved_etc) {
+           char *cp = msgGetInput("/var/tmp/etc", "Under which directory do 
you wish to save your current /etc?");
+
+           if (!cp || !*cp || Mkdir(cp)) {
+               if (msgYesNo("Directory was not specified, was invalid or user 
selected Cancel.\n\n"
+                            "Doing an upgrade without first backing up your 
/etc directory is a very\n"
+                            "bad idea!  Do you want to go back and specify the 
save directory again?") != 0)
+                   break;
+           }
+           else {
+               SAFE_STRCPY(saved_etc, cp);
+           }
+       }
+
+       if (saved_etc[0]) {
+           msgNotify("Preserving /etc directory..");
+           if (vsystem("tar -cBpf - -C /etc . | tar --unlink -xBpf - -C %s", 
saved_etc))
+               if (msgYesNo("Unable to backup your /etc into %s.\n"
+                            "Do you want to continue anyway?", saved_etc) != 0)
+                   return DITEM_FAILURE;
+           msgNotify("Preserving /root directory..");
+           vsystem("tar -cBpf - -C / root | tar --unlink -xBpf - -C %s", 
saved_etc);
+       }
+
+       msgNotify("chflags'ing old binaries - please wait.");
+       (void)vsystem("chflags -R noschg /bin /sbin /lib /libexec /usr/bin 
/usr/sbin /usr/lib /usr/libexec /var/empty /boot/kernel*");
+
+       if (directory_exists("/boot/kernel")) {
+           if (directory_exists("/boot/kernel.prev")) {
+               msgNotify("Removing /boot/kernel.prev");
+               if (system("rm -fr /boot/kernel.prev")) {
+                   msgConfirm("NOTICE: I'm trying to back up /boot/kernel to\n"
+                              "/boot/kernel.prev, but /boot/kernel.prev exists 
and I\n"
+                              "can't remove it.  This means that the backup 
will, in\n"
+                              "all probability, fail.");
+               }
+           }
+           msgNotify("Moving old kernel to /boot/kernel.prev");
+           if (system("mv /boot/kernel /boot/kernel.prev")) {
+               if (!msgYesNo("Hmmm!  I couldn't move the old kernel over!  Do 
you want to\n"
+                             "treat this as a big problem and abort the 
upgrade?  Due to the\n"
+                             "way that this upgrade process works, you will 
have to reboot\n"
+                             "and start over from the beginning.  Select Yes 
to reboot now"))
+                   systemShutdown(1);
+           }
+           else 
+               msgConfirm("NOTICE: Your old kernel is in /boot/kernel.prev 
should this\n"
+                          "upgrade fail for any reason and you need to boot 
your old\n"
+                          "kernel.");
+       }
+    }
+
+media:
+    /* We do this very late, but we unfortunately need to back up /etc first */
+    if (!mediaVerify())
+       return DITEM_FAILURE;
+
+    if (!DEVICE_INIT(mediaDevice)) {
+       if (!msgYesNo("Couldn't initialize the media.  Would you like\n"
+                  "to adjust your media selection and try again?")) {
+           mediaDevice = NULL;
+           goto media;
+       }
+       else
+           return DITEM_FAILURE | DITEM_REDRAW | DITEM_RESTORE;
+    }
+    
+    msgNotify("Beginning extraction of distributions.");
+    if (DITEM_STATUS(distExtractAll(self)) == DITEM_FAILURE) {
+       msgConfirm("Hmmmm.  We couldn't even extract the base distribution.  
This upgrade\n"
+                  "should be considered a failure and started from the 
beginning, sorry!\n"
+                  "The system will reboot now.");
+       dialog_clear();
+       systemShutdown(1);
+    }
+    else if (Dists) {
+       if (!extractingBin || !(Dists & DIST_BASE)) {
+           msgNotify("The extraction process seems to have had some problems, 
but we got most\n"
+                      "of the essentials.  We'll treat this as a warning since 
it may have been\n"
+                      "only non-essential distributions which failed to 
load.");
+       }
+       else {
+           msgConfirm("Hmmmm.  We couldn't even extract the base distribution. 
 This upgrade\n"
+                      "should be considered a failure and started from the 
beginning, sorry!\n"
+                      "The system will reboot now.");
+           dialog_clear();
+           systemShutdown(1);
+       }
+    }
+
+    if (extractingBin)
+       vsystem("disklabel -B `awk '$2~/\\/$/ {print substr($1, 6, 5)}' 
/etc/fstab`");
+    msgNotify("First stage of upgrade completed successfully!\n\n"
+              "Next comes stage 2, where we attempt to resurrect your /etc\n"
+              "directory!");
+
+    if (chdir(saved_etc)) {
+       msgConfirm("Unable to go to your saved /etc directory in %s?!  Argh!\n"
+                  "Something went seriously wrong!  It's quite possible that\n"
+                  "your former /etc is toast.  I hope you didn't have any\n"
+                  "important customizations you wanted to keep in there.. :(", 
saved_etc);
+    }
+    else {
+       /* Now try to resurrect the /etc files */
+       traverseHitlist(etc_files);
+       /* Resurrect the root dotfiles */
+       vsystem("tar -cBpf - root | tar -xBpf - -C / && rm -rf root");
+    }
+
+    msgConfirm("Upgrade completed!  All of your old /etc files have been 
restored.\n"
+              "For your reference, the new /etc files are in /etc/upgrade/ in 
case\n"
+              "you wish to upgrade these files by hand (though that should not 
be\n"
+              "strictly necessary).  If your root partition is specified in 
/etc/fstab\n"
+              "using the old \"compatibility\" slice, you may also wish to 
update it to\n"
+              "use a fully qualified slice name in order to avoid warnings on 
startup.\n\n"
+              "When you're ready to reboot into the new system, simply exit 
the installation.");
+    return DITEM_SUCCESS | DITEM_REDRAW | DITEM_RESTORE;
+}
+
+static int
+installUpgradeNonInteractive(dialogMenuItem *self)
+{
+    char *saved_etc;
+    Boolean extractingBin = TRUE;
+
+    variable_set2(SYSTEM_STATE, "upgrade", 0);
+
+    /* Make sure at least BIN is selected */
+    Dists |= DIST_BASE;
+
+    if (RunningAsInit) {
+       Device **devs;
+       int i, cnt;
+       char *cp;
+
+       cp = variable_get(VAR_DISK);
+       devs = deviceFind(cp, DEVICE_TYPE_DISK);
+       cnt = deviceCount(devs);
+       if (!cnt) {
+           msgConfirm("No disks found!  Please verify that your disk 
controller is being\n"
+                      "properly probed at boot time.  See the Hardware Guide 
on the\n"
+                      "Documentation menu for clues on diagnosing this type of 
problem.");
+           return DITEM_FAILURE;
+       }
+       else {
+           /* Enable all the drives before we start */
+           for (i = 0; i < cnt; i++)
+               devs[i]->enabled = TRUE;
+       }
+
+       msgConfirm("OK.  First, we're going to go to the disk label editor.  In 
this editor\n"
+                  "you will be expected to Mount any partitions you're 
interested in\n"
+                  "upgrading.  DO NOT set the Newfs flag to Y on anything in 
the label editor\n"
+                  "unless you're absolutely sure you know what you're doing!  
In this\n"
+                  "instance, you'll be using the label editor as little more 
than a fancy\n"
+                  "screen-oriented partition mounting tool.\n\n"
+                  "Once you're done in the label editor, press Q to return 
here for the next\n"
+                  "step.");
+
+       if (DITEM_STATUS(diskLabelEditor(self)) == DITEM_FAILURE) {
+           msgConfirm("The disk label editor returned an error status.  
Upgrade operation\n"
+                      "aborted.");
+           return DITEM_FAILURE;
+       }
+
+       /* Don't write out MBR info */
+       variable_set2(DISK_PARTITIONED, "written", 0);
+       if (DITEM_STATUS(diskLabelCommit(self)) == DITEM_FAILURE) {
+           msgConfirm("Not all file systems were properly mounted.  Upgrade 
operation\n"
+                      "aborted.");
+           variable_unset(DISK_PARTITIONED);
+           return DITEM_FAILURE;
+       }
+
+       if (extractingBin) {
+           msgNotify("chflags'ing old binaries - please wait.");
+           (void)vsystem("chflags -R noschg /mnt/");
+       }
+       msgNotify("Updating /stand on root filesystem");
+       (void)vsystem("find -x /stand | cpio %s -pdum /mnt", cpioVerbosity());
+
+       if (DITEM_STATUS(chroot("/mnt")) == DITEM_FAILURE) {
+           msgConfirm("Unable to chroot to /mnt - something is wrong with 
the\n"
+                      "root partition or the way it's mounted if this doesn't 
work.");
+           variable_unset(DISK_PARTITIONED);
+           return DITEM_FAILURE;
+       }
+       chdir("/");
+       systemCreateHoloshell();
+    }
+
+    if (!mediaVerify() || !DEVICE_INIT(mediaDevice)) {
+       msgNotify("Upgrade: Couldn't initialize media.");
+       return DITEM_FAILURE;
+    }
+
+    saved_etc = "/var/tmp/etc";
+    Mkdir(saved_etc);
+    msgNotify("Preserving /etc directory..");
+    if (vsystem("tar -cpBf - -C /etc . | tar -xpBf - -C %s", saved_etc)) {
+       msgNotify("Unable to backup your /etc into %s.", saved_etc);
+       return DITEM_FAILURE;
+    }
+
+    /*
+     * Back up the old kernel, leaving it in place in case we
+     *  crash and reboot.
+     */
+    if (directory_exists("/boot/kernel")) {
+       if (directory_exists("/boot/kernel.prev")) {
+           msgNotify("Removing /boot/kernel.prev");
+           if (system("rm -fr /boot/kernel.prev")) {
+               msgConfirm("NOTICE: I'm trying to back up /boot/kernel to\n"
+                   "/boot/kernel.prev, but /boot/kernel.prev exists and I\n"
+                   "can't remove it.  This means that the backup will, in\n"
+                   "all probability, fail.");
+           }
+       }
+       msgNotify("Copying old kernel to /boot/kernel.prev");
+       vsystem("cp -Rp /boot/kernel /boot/kernel.prev");
+    }   
+
+    msgNotify("Beginning extraction of distributions.");
+    if (DITEM_STATUS(distExtractAll(self)) == DITEM_FAILURE) {
+       msgConfirm("Hmmmm.  We couldn't even extract the base distribution.  
This upgrade\n"
+                  "should be considered a failure and started from the 
beginning, sorry!\n"
+                  "The system will reboot now.");
+       dialog_clear();
+       systemShutdown(1);
+    }
+    else if (Dists) {
+       if (!(Dists & DIST_BASE)) {
+           msgNotify("The extraction process seems to have had some problems, 
but we got most\n"
+                      "of the essentials.  We'll treat this as a warning since 
it may have been\n"
+                      "only non-essential distributions which failed to 
upgrade.");
+       }
+       else {
+           msgConfirm("Hmmmm.  We couldn't even extract the base distribution. 
 This upgrade\n"
+                      "should be considered a failure and started from the 
beginning, sorry!\n"
+                      "The system will reboot now.");
+           dialog_clear();
+           systemShutdown(1);
+       }
+    }
+
+    msgNotify("First stage of upgrade completed successfully.");
+    if (vsystem("tar -cpBf - -C %s . | tar --unlink -xpBf - -C /etc", 
saved_etc)) {
+       msgNotify("Unable to resurrect your old /etc!");
+       return DITEM_FAILURE;
+    }
+    return DITEM_SUCCESS | DITEM_REDRAW;
+}

Modified: head/usr.sbin/sysinstall/menus.c
==============================================================================
--- head/usr.sbin/sysinstall/menus.c    Thu Jul  8 21:02:31 2010        
(r209831)
+++ head/usr.sbin/sysinstall/menus.c    Thu Jul  8 21:26:26 2010        
(r209832)
@@ -243,6 +243,7 @@ DMenu MenuIndex = {
 #endif /* WITH_SYSCONS */
       { " Time Zone",          "Set the system's time zone.",          NULL, 
dmenuSystemCommand, NULL, "tzsetup" },
       { " TTYs",               "Configure system ttys.",               NULL, 
configEtcTtys, NULL, "ttys" },
+      { " Upgrade",            "Upgrade an existing system.",          NULL, 
installUpgrade },
       { " Usage",              "Quick start - How to use this menu system.",   
NULL, dmenuDisplayFile, NULL, "usage" },
       { " User Management",    "Add user and group information.",      NULL, 
dmenuSubmenu, NULL, &MenuUsermgmt },
       { NULL } },
@@ -274,6 +275,7 @@ DMenu MenuInitial = {
 #endif
       { "Options",     "View/Set various installation options",        NULL, 
optionsEditor },
       { "Fixit",       "Repair mode with CDROM/DVD/floppy or start shell",     
NULL, dmenuSubmenu, NULL, &MenuFixit },
+      { "Upgrade",     "Upgrade an existing system",                   NULL, 
installUpgrade },
       { "Load Config..","Load default install configuration",          NULL, 
dispatch_load_menu },
       { "Index",       "Glossary of functions",                        NULL, 
dmenuSubmenu, NULL, &MenuIndex },
       { NULL } },

Modified: head/usr.sbin/sysinstall/sysinstall.8
==============================================================================
--- head/usr.sbin/sysinstall/sysinstall.8       Thu Jul  8 21:02:31 2010        
(r209831)
+++ head/usr.sbin/sysinstall/sysinstall.8       Thu Jul  8 21:26:26 2010        
(r209832)
@@ -553,6 +553,11 @@ installation type available.
 .Pp
 .Sy Variables :
 None
+.It installUpgrade
+Start an upgrade installation.
+.Pp
+.Sy Variables :
+None
 .It installFixitHoloShell
 Start up the "emergency holographic shell" over on VTY4
 if running as init.

Modified: head/usr.sbin/sysinstall/sysinstall.h
==============================================================================
--- head/usr.sbin/sysinstall/sysinstall.h       Thu Jul  8 21:02:31 2010        
(r209831)
+++ head/usr.sbin/sysinstall/sysinstall.h       Thu Jul  8 21:26:26 2010        
(r209832)
@@ -679,6 +679,7 @@ extern int  installFixitUSB(dialogMenuIte
 extern int     installFixitFloppy(dialogMenuItem *self);
 extern int     installFixupBase(dialogMenuItem *self);
 extern int     installFixupKernel(dialogMenuItem *self, int dists);
+extern int     installUpgrade(dialogMenuItem *self);
 extern int     installFilesystems(dialogMenuItem *self);
 extern int     installVarDefaults(dialogMenuItem *self);
 extern void    installEnvironment(void);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to