diff options
author | sam <sam@FreeBSD.org> | 2006-03-08 18:02:32 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2006-03-08 18:02:32 +0000 |
commit | fa1fbfedc2f06342ca8bbae5b057d8bd2c14cc59 (patch) | |
tree | 87198eeaccc5a4734146e5e9aa6881c4854232fe /usr.sbin/sysinstall/dist.c | |
parent | b19c8d2fcc1540312b520fc757d445026667a6ac (diff) | |
download | FreeBSD-src-fa1fbfedc2f06342ca8bbae5b057d8bd2c14cc59.zip FreeBSD-src-fa1fbfedc2f06342ca8bbae5b057d8bd2c14cc59.tar.gz |
Revamp base system packaging of kernels to enable up/smp selection
at runtime and to support distributing additional kernels:
o remove kernel from the base tarball
o add new kernel tarballs
o build + package both SMP and GENERIC kernels when an <arch>/conf/SMP
config file is present
o add sysinstall support for multiple kernels
o update sysinstall to probe for the number of cpus on a system
and auto-select smp/up kernel accordingly
o add a post-kernels install hook to fixup /boot/kernel
o add -ldevinfo to boot crunch for sysinstall's cpu probing logic
Notes:
1. On HEAD this code is not currently used because GENERIC kernels
include SMP. This work is mainly intended for RELENG_6 where the
GENERIC kernel is UP. If HEAD changes to match then just enable
WITH_SMP in sysinstall/Makefile.
2. The cpu probing support is done with acpi and MPTable; this means
some systems will require work for auto-detection to work.
3. The handling of /boot/kernel may need to be revisited; for now
we rename one kernel at the last moment (SMP if installed, otherwise
GENERIC). There are other, possibly better, approaches.
Lots of help from ru, emaste, scottl, and jhb.
Diffstat (limited to 'usr.sbin/sysinstall/dist.c')
-rw-r--r-- | usr.sbin/sysinstall/dist.c | 112 |
1 files changed, 102 insertions, 10 deletions
diff --git a/usr.sbin/sysinstall/dist.c b/usr.sbin/sysinstall/dist.c index ab3914c..be74bd3 100644 --- a/usr.sbin/sysinstall/dist.c +++ b/usr.sbin/sysinstall/dist.c @@ -45,6 +45,7 @@ unsigned int Dists; unsigned int SrcDists; unsigned int XOrgDists; +unsigned int KernelDists; enum _disttype { DT_TARBALL, DT_SUBDIST, DT_PACKAGE }; @@ -59,6 +60,7 @@ typedef struct _dist { } my_data; } Distribution; +static Distribution KernelDistTable[]; static Distribution SrcDistTable[]; static Distribution XOrgDistTable[]; @@ -75,6 +77,7 @@ static Distribution XOrgDistTable[]; /* The top-level distribution categories */ static Distribution DistTable[] = { DTE_TARBALL("base", &Dists, BASE, "/"), + DTE_SUBDIST("kernels", &Dists, KERNEL, KernelDistTable), DTE_TARBALL("doc", &Dists, DOC, "/"), DTE_TARBALL("games", &Dists, GAMES, "/"), DTE_TARBALL("manpages", &Dists, MANPAGES, "/"), @@ -92,6 +95,15 @@ static Distribution DistTable[] = { DTE_END, }; +/* The kernel distributions */ +static Distribution KernelDistTable[] = { + DTE_TARBALL("GENERIC", &KernelDists, KERNEL_GENERIC, "/boot"), +#ifdef WITH_SMP + DTE_TARBALL("SMP", &KernelDists, KERNEL_SMP, "/boot"), +#endif + DTE_END, +}; + /* The /usr/src distribution */ static Distribution SrcDistTable[] = { DTE_TARBALL("sbase", &SrcDists, SRC_BASE, "/usr/src"), @@ -149,9 +161,11 @@ distVerifyFlags(void) Dists |= DIST_SRC; if (XOrgDists) Dists |= DIST_XORG; + if (KernelDists) + Dists |= DIST_KERNEL; if (isDebug()) { - msgDebug("Dist Masks: Dists: %0x, Srcs: %0x\n", Dists, - SrcDists); + msgDebug("Dist Masks: Dists: %0x, Srcs: %0x Kernels: %0x\n", Dists, + SrcDists, KernelDists); msgDebug("XServer: %0x\n", XOrgDists); } } @@ -162,6 +176,7 @@ distReset(dialogMenuItem *self) Dists = 0; SrcDists = 0; XOrgDists = 0; + KernelDists = 0; return DITEM_SUCCESS | DITEM_REDRAW; } @@ -181,6 +196,9 @@ distConfig(dialogMenuItem *self) if ((cp = variable_get(VAR_DIST_X11)) != NULL) XOrgDists = atoi(cp); + if ((cp = variable_get(VAR_DIST_KERNEL)) != NULL) + KernelDists = atoi(cp); + distVerifyFlags(); return DITEM_SUCCESS | DITEM_REDRAW; } @@ -193,6 +211,17 @@ distSetX(void) return distSetXOrg(NULL); } +static int +selectKernel(void) +{ +#ifdef WITH_SMP + /* select default kernel based on deduced cpu count */ + return NCpus > 1 ? DIST_KERNEL_SMP : DIST_KERNEL_GENERIC; +#else + return DIST_KERNEL_GENERIC; +#endif +} + int distSetDeveloper(dialogMenuItem *self) { @@ -201,6 +230,7 @@ distSetDeveloper(dialogMenuItem *self) distReset(NULL); Dists = _DIST_DEVELOPER; SrcDists = DIST_SRC_ALL; + KernelDists = selectKernel(); i = distMaybeSetPorts(self); distVerifyFlags(); return i; @@ -225,6 +255,7 @@ distSetKernDeveloper(dialogMenuItem *self) distReset(NULL); Dists = _DIST_DEVELOPER; SrcDists = DIST_SRC_SYS; + KernelDists = selectKernel(); i = distMaybeSetPorts(self); distVerifyFlags(); return i; @@ -248,6 +279,7 @@ distSetUser(dialogMenuItem *self) distReset(NULL); Dists = _DIST_USER; + KernelDists = selectKernel(); i = distMaybeSetPorts(self); distVerifyFlags(); return i; @@ -268,7 +300,8 @@ int distSetMinimum(dialogMenuItem *self) { distReset(NULL); - Dists = DIST_BASE; + Dists = DIST_BASE | DIST_KERNEL; + KernelDists = selectKernel(); distVerifyFlags(); return DITEM_SUCCESS | DITEM_REDRAW; } @@ -281,6 +314,7 @@ distSetEverything(dialogMenuItem *self) Dists = DIST_ALL; SrcDists = DIST_SRC_ALL; XOrgDists = DIST_XORG_ALL; + KernelDists = DIST_KERNEL_ALL; i = distMaybeSetPorts(self); distVerifyFlags(); return i | DITEM_REDRAW; @@ -434,6 +468,20 @@ distSetXOrg(dialogMenuItem *self) return i | DITEM_RESTORE; } +int +distSetKernel(dialogMenuItem *self) +{ + int i; + + dialog_clear_norefresh(); + if (!dmenuOpenSimple(&MenuKernelDistributions, FALSE)) + i = DITEM_FAILURE; + else + i = DITEM_SUCCESS; + distVerifyFlags(); + return i | DITEM_RESTORE; +} + static Boolean got_intr = FALSE; /* timeout handler */ @@ -455,13 +503,31 @@ check_for_interrupt(void) } /* + * translate distribution filename to lower case + * as doTARBALL does in release/Makefile + */ +static void +translateDist(char trdist[PATH_MAX], const char *dist) +{ + int j; + + /* + * translate distribution filename to lower case + * as doTARBALL does in release/Makefile + */ + for (j = 0; j < PATH_MAX-1 && dist[j] != '\0'; j++) + trdist[j] = tolower(dist[j]); + trdist[j] = '\0'; +} + +/* * Try to get distribution as multiple pieces, locating and parsing an * info file which tells us how many we need for this distribution. */ static Boolean distExtractTarball(char *path, char *dist, char *my_dir, int is_base) { - char *buf = NULL, fname[PATH_MAX]; + char *buf = NULL, trdist[PATH_MAX], fname[PATH_MAX]; struct timeval start, stop; int j, status, total, intr; int cpid, zpid, fd2, chunk, numchunks; @@ -469,14 +535,23 @@ distExtractTarball(char *path, char *dist, char *my_dir, int is_base) const char *tmp; FILE *fp; + translateDist(trdist, dist); + if (isDebug()) + msgDebug("%s: path \"%s\" dist \"%s\" trdist \"%s\" " + "my_dir \"%s\" %sis_base\n", + __func__, path, dist, trdist, my_dir, is_base ? "" : "!"); + status = TRUE; numchunks = 0; - snprintf(fname, sizeof (fname), "%s/%s.inf", path, dist); + snprintf(fname, sizeof (fname), "%s/%s.inf", path, trdist); getinfo: fp = DEVICE_GET(mediaDevice, fname, TRUE); intr = check_for_interrupt(); if (fp == (FILE *)IO_ERROR || intr || !mediaDevice) { + if (isDebug()) + msgDebug("%s: fname %s fp: %p, intr: %d mediaDevice: %p\n", + __func__, fname, fp, intr, mediaDevice); /* Hard error, can't continue */ if (!msgYesNo("Unable to open %s: %s.\nReinitialize media?", fname, !intr ? "I/O error." : "User interrupt.")) { @@ -488,8 +563,10 @@ getinfo: return (FALSE); } else if (fp == NULL) { /* No attributes file, so try as a single file. */ - snprintf(fname, sizeof(fname), "%s/%s.%s", path, dist, + snprintf(fname, sizeof(fname), "%s/%s.%s", path, trdist, USE_GZIP ? "tgz" : "tbz"); + if (isDebug()) + msgDebug("%s: fp is NULL (1) fname: %s\n", __func__, fname); /* * Passing TRUE as 3rd parm to get routine makes this a "probing" * get, for which errors are not considered too significant. @@ -498,6 +575,9 @@ getinfo: fp = DEVICE_GET(mediaDevice, fname, TRUE); intr = check_for_interrupt(); if (fp == (FILE *)IO_ERROR || intr || !mediaDevice) { + if (isDebug()) + msgDebug("%s: fname %s fp: %p, intr: %d mediaDevice: %p\n", + __func__, fname, fp, intr, mediaDevice); /* Hard error, can't continue */ msgConfirm("Unable to open %s: %s", fname, !intr ? "I/O error" : "User interrupt"); @@ -513,8 +593,11 @@ getinfo: status = mediaExtractDist(dir, dist, fp); fclose(fp); return (status); - } else + } else { + if (isDebug()) + msgDebug("%s: fp is NULL (2) fname %s\n", __func__, fname); return (FALSE); + } } if (isDebug()) @@ -523,6 +606,8 @@ getinfo: dist_attr = properties_read(fileno(fp)); intr = check_for_interrupt(); if (intr || !dist_attr) { + if (isDebug()) + msgDebug("%s: intr %d dist_attr %p\n", __func__, intr, dist_attr); msgConfirm("Cannot parse information file for the %s distribution: %s\n" "Please verify that your media is valid and try again.", dist, !intr ? "I/O error" : "User interrupt"); @@ -532,8 +617,11 @@ getinfo: numchunks = strtol(tmp, 0, 0); } fclose(fp); - if (!numchunks) + if (!numchunks) { + if (isDebug()) + msgDebug("%s: numchunks is zero\n", __func__); return (TRUE); + } if (isDebug()) msgDebug("Attempting to extract distribution from %u chunks.\n", @@ -562,7 +650,7 @@ getinfo: tmp = index(tmp, ' '); chunksize = strtol(tmp, 0, 0); } - snprintf(fname, sizeof(fname), "%s/%s.%c%c", path, dist, (chunk / 26) + 'a', + snprintf(fname, sizeof(fname), "%s/%s.%c%c", path, trdist, (chunk / 26) + 'a', (chunk % 26) + 'a'); if (isDebug()) msgDebug("trying for piece %d of %d: %s\n", chunk + 1, numchunks, @@ -767,7 +855,7 @@ printSelected(char *buf, int selected, Distribution *me, int *col) int distExtractAll(dialogMenuItem *self) { - int old_dists, retries = 0, status = DITEM_SUCCESS; + int old_dists, old_kernel, retries = 0, status = DITEM_SUCCESS; char buf[512]; WINDOW *w; @@ -781,6 +869,7 @@ distExtractAll(dialogMenuItem *self) return DITEM_FAILURE; old_dists = Dists; + old_kernel = KernelDists; distVerifyFlags(); dialog_clear_norefresh(); @@ -795,6 +884,9 @@ distExtractAll(dialogMenuItem *self) /* Only do base fixup if base dist was successfully extracted */ if ((old_dists & DIST_BASE) && !(Dists & DIST_BASE)) status |= installFixupBase(self); + /* Only do base fixup if base dist was successfully extracted */ + if ((old_dists & DIST_KERNEL) && !(Dists & DIST_KERNEL)) + status |= installFixupKernel(self, old_kernel); /* Clear any local dist flags now */ Dists &= ~DIST_LOCAL; |