After sysintall has initialized, sliced the disks and asked for mount points of the partitions, pressing Ctrl-C brings up the option to restart sysinstall. After restarting sysinstall, the target installation path changes from /mnt (the newly created "/" mount pount) to the actuall "/" which is amemory disk device, causing the setup to give errors of unsufficient disk space as the system tries to install the distributions on the memory disk. How-To-Repeat: boot from setup media, chose standard setup, slice and partiton disks, mount, press Ctrl-C , choose restart setup program, repeat slicing and aprtitoning again, choses distributions and proceed to copying.
Responsible Changed From-To: freebsd-bugs->qa Assign to qa group
Responsible Changed From-To: freebsd-bugs->brucec Take.
Author: brucec Date: Tue Aug 17 09:39:06 2010 New Revision: 211417 URL: http://svn.freebsd.org/changeset/base/211417 Log: To restart, sysinstall calls execl. Since it will create a new process, we can't check to see if sysinstall is running as init just by checking if the PID is 0. Introduce a new option that sets the RunningAsInit flag, and update the code to check RunningAsInit intstead of getpid(). PR: bin/38854 Submitted by: Peter Sedeffow <peter at trumanbrewery.com> Approved by: rrs (mentor) MFC after: 1 month Modified: head/usr.sbin/sysinstall/globals.c head/usr.sbin/sysinstall/install.c head/usr.sbin/sysinstall/main.c head/usr.sbin/sysinstall/msg.c head/usr.sbin/sysinstall/system.c head/usr.sbin/sysinstall/termcap.c Modified: head/usr.sbin/sysinstall/globals.c ============================================================================== --- head/usr.sbin/sysinstall/globals.c Tue Aug 17 09:13:26 2010 (r211416) +++ head/usr.sbin/sysinstall/globals.c Tue Aug 17 09:39:06 2010 (r211417) @@ -76,13 +76,10 @@ globalsInit(void) { DebugFD = -1; ColorDisplay = FALSE; - Fake = FALSE; - Restarting = FALSE; OnVTY = FALSE; DialogActive = FALSE; VarHead = NULL; mediaDevice = NULL; - RunningAsInit = FALSE; HomeChunk = NULL; RootChunk = NULL; Modified: head/usr.sbin/sysinstall/install.c ============================================================================== --- head/usr.sbin/sysinstall/install.c Tue Aug 17 09:13:26 2010 (r211416) +++ head/usr.sbin/sysinstall/install.c Tue Aug 17 09:39:06 2010 (r211417) @@ -1274,7 +1274,7 @@ installVarDefaults(dialogMenuItem *self) variable_set2(VAR_FIXIT_TTY, "serial", 0); variable_set2(VAR_PKG_TMPDIR, "/var/tmp", 0); variable_set2(VAR_MEDIA_TIMEOUT, itoa(MEDIA_TIMEOUT), 0); - if (getpid() != 1) + if (!RunningAsInit) variable_set2(SYSTEM_STATE, "update", 0); else variable_set2(SYSTEM_STATE, "init", 0); Modified: head/usr.sbin/sysinstall/main.c ============================================================================== --- head/usr.sbin/sysinstall/main.c Tue Aug 17 09:13:26 2010 (r211416) +++ head/usr.sbin/sysinstall/main.c Tue Aug 17 09:39:06 2010 (r211417) @@ -56,12 +56,42 @@ main(int argc, char **argv) int choice, scroll, curr, max, status; char titlestr[80], *arch, *osrel, *ostype; struct rlimit rlim; - + char *arg; + int i; + int optionArgs = 0; + /* Record name to be able to restart */ StartName = argv[0]; + Restarting = FALSE; + RunningAsInit = FALSE; + Fake = FALSE; + + for (i = 1; i < argc; i++) { + arg = argv[i]; + + if (arg[0] != '-') + break; + + optionArgs++; + + if (!strcmp(arg, "-fake")) { + variable_set2(VAR_DEBUG, "YES", 0); + Fake = TRUE; + } else if (!strcmp(arg, "-restart")) { + Restarting = TRUE; + } else if (!strcmp(arg, "-fakeInit")) { + RunningAsInit = TRUE; + } + + arg = argv[optionArgs+1]; + } + + if (getpid() == 1) + RunningAsInit = TRUE; + /* Catch fatal signals and complain about them if running as init */ - if (getpid() == 1) { + if (RunningAsInit) { signal(SIGBUS, screech); signal(SIGSEGV, screech); } @@ -105,13 +135,8 @@ main(int argc, char **argv) if (!RunningAsInit) installEnvironment(); - if (argc > 1 && !strcmp(argv[1], "-fake")) { - variable_set2(VAR_DEBUG, "YES", 0); - Fake = TRUE; + if (Fake) msgConfirm("I'll be just faking it from here on out, OK?"); - } - if (argc > 1 && !strcmp(argv[1], "-restart")) - Restarting = TRUE; /* Try to preserve our scroll-back buffer */ if (OnVTY) { @@ -140,19 +165,14 @@ main(int argc, char **argv) /* First, see if we have any arguments to process (and argv[0] counts if it's not "sysinstall") */ if (!RunningAsInit) { - int i, start_arg; - - if (!strstr(argv[0], "sysinstall")) - start_arg = 0; - else if (Fake || Restarting) - start_arg = 2; - else - start_arg = 1; - for (i = start_arg; i < argc; i++) { + for (i = optionArgs+1; i < argc; i++) { if (DITEM_STATUS(dispatchCommand(argv[i])) != DITEM_SUCCESS) systemShutdown(1); } - if (argc > start_arg) + + /* If we were given commands to process on the command line, just exit + * now */ + if (argc > optionArgs+1) systemShutdown(0); } else @@ -187,7 +207,7 @@ main(int argc, char **argv) while (1) { choice = scroll = curr = max = 0; dmenuOpen(&MenuInitial, &choice, &scroll, &curr, &max, TRUE); - if (getpid() != 1 + if (!RunningAsInit #if defined(__sparc64__) || !msgNoYes("Are you sure you wish to exit? The system will halt.") #else Modified: head/usr.sbin/sysinstall/msg.c ============================================================================== --- head/usr.sbin/sysinstall/msg.c Tue Aug 17 09:13:26 2010 (r211416) +++ head/usr.sbin/sysinstall/msg.c Tue Aug 17 09:39:06 2010 (r211417) @@ -233,7 +233,7 @@ msgFatal(char *fmt, ...) mvaddstr(StatusLine, 0, errstr); addstr(" - "); addstr("PRESS ANY KEY TO "); - if (getpid() == 1) + if (RunningAsInit) addstr("REBOOT"); else addstr("QUIT"); Modified: head/usr.sbin/sysinstall/system.c ============================================================================== --- head/usr.sbin/sysinstall/system.c Tue Aug 17 09:13:26 2010 (r211416) +++ head/usr.sbin/sysinstall/system.c Tue Aug 17 09:39:06 2010 (r211417) @@ -59,13 +59,20 @@ static int intr_restart(dialogMenuItem *self) { int ret, fd, fdmax; + char *arg; mediaClose(); free_variables(); fdmax = getdtablesize(); for (fd = 3; fd < fdmax; fd++) close(fd); - ret = execl(StartName, StartName, "-restart", (char *)NULL); + + if (RunningAsInit) + arg = "-restart -fakeInit"; + else + arg = "-restart"; + + ret = execl(StartName, StartName, arg, NULL); msgDebug("execl failed (%s)\n", strerror(errno)); /* NOTREACHED */ return -1; @@ -148,11 +155,10 @@ systemInitialize(int argc, char **argv) variable_set2(VAR_DEBUG, "YES", 0); /* Are we running as init? */ - if (getpid() == 1) { + if (RunningAsInit) { struct ufs_args ufs_args; int fd; - RunningAsInit = 1; setsid(); close(0); fd = open("/dev/ttyv0", O_RDWR); Modified: head/usr.sbin/sysinstall/termcap.c ============================================================================== --- head/usr.sbin/sysinstall/termcap.c Tue Aug 17 09:13:26 2010 (r211416) +++ head/usr.sbin/sysinstall/termcap.c Tue Aug 17 09:39:06 2010 (r211417) @@ -105,7 +105,7 @@ set_termcap(void) else { int i, on; - if (getpid() == 1) { + if (RunningAsInit) { DebugFD = open("/dev/ttyv1", O_WRONLY); if (DebugFD != -1) { on = 1; _______________________________________________ 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-unsubscribe@freebsd.org"
State Changed From-To: open->patched Fixed in r211417.
State Changed From-To: patched->open The patch I committed was a no-op because execl doesn't change the PID.
Hi, I prototyped up a solution for this issue by banking on the fact that the *fork(2) system calls actually do a copy on write of several process variables, including the current working directory, etc. Example: $ ./test_forking_and_chdiring [0] getwd = /tmp [1] getwd = /usr/home/gcooper [2] getwd = /tmp [3] getwd = /usr/home/gcooper So at least now sysinstall is starting from a sane state consistently, instead of just reexecuting itself via system(3) with -fakeInit and -restart (ugh). I was concerned about sysinstall closing file descriptors on exec, etc, but this appears to be mostly baseless. Cleaning up these dead options should be done in later commits. I executed sysinstall from the command line in multiuser given the following 4 scenarios: 1. Exit (exit code was 0). 2. ^C: a. Continue (process continued as usual). b. Restart (process `restarted' by continuing on in the loop again -- it was rather amusing when I discovered that it reexecutes itself and can essentially overload the stack eventually if it gets into an infinite loop :/). c. Abort (process exited with 1 as I designed it to). There might be some corner cases with usage, but this focuses on the primary areas. I was hoping to use vfork(2) (because it would have made the logic a bit simpler, but unfortunately vfork isn't isolated enough to do proper signal handling with SIGINT (I think that the parent process and the child process share the same signal vectors, but I could be wrong... I should look). Ideally sysinstall should be run from a custom /etc/rc script that sets up all of these variables and ensures that the sysinstall process is playing by the rules, but that's something else that needs to be resolved down the line for this particular issue. This is just a quick and dirty stopgap fix. Credit goes to Gavin for pointing me to this annoying problem :). Thanks, -Garrett #include <sys/types.h> #include <sys/wait.h> #include <err.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(void) { int status; switch (fork()) { case -1: err(1, "fork"); case 0: if (chdir("/tmp") == -1) err(1, "chroot"); printf("[0] getwd = %s\n", getwd(NULL)); exit(0); default: if (wait(&status) == -1) err(1, "wait"); else if (status) errx(1, "exit status != 0"); } printf("[1] getwd = %s\n", getwd(NULL)); switch (vfork()) { case -1: err(1, "vfork"); case 0: if (chdir("/tmp") == -1) err(1, "chroot"); printf("[2] getwd = %s\n", getwd(NULL)); exit(0); default: if (wait(&status) == -1) err(1, "wait"); else if (status) errx(1, "exit status != 0"); } printf("[3] getwd = %s\n", getwd(NULL)); exit(0); }
Responsible Changed From-To: brucec->freebsd-sysinstall Back to the pool.
sysinstall has been replaced by bsdinstall in FreeBSD 9.x. Closing.