summaryrefslogtreecommitdiffstats
path: root/usr.sbin/sysinstall/dist.c
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2006-03-08 18:02:32 +0000
committersam <sam@FreeBSD.org>2006-03-08 18:02:32 +0000
commitfa1fbfedc2f06342ca8bbae5b057d8bd2c14cc59 (patch)
tree87198eeaccc5a4734146e5e9aa6881c4854232fe /usr.sbin/sysinstall/dist.c
parentb19c8d2fcc1540312b520fc757d445026667a6ac (diff)
downloadFreeBSD-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.c112
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;
OpenPOWER on IntegriCloud