summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorkensmith <kensmith@FreeBSD.org>2008-10-15 15:54:33 +0000
committerkensmith <kensmith@FreeBSD.org>2008-10-15 15:54:33 +0000
commiteac902752f91c88724dc3b620b50267b52224651 (patch)
tree2fb9c691624d6bed4d63f6de66158f4b4c8d9c80 /usr.sbin
parent10790fab265752c54b693cf1890e8c1a83c77a0b (diff)
downloadFreeBSD-src-eac902752f91c88724dc3b620b50267b52224651.zip
FreeBSD-src-eac902752f91c88724dc3b620b50267b52224651.tar.gz
Package installation is handled by starting off with the list of packages
the user selected and then recursively installing their dependencies, finally installing the ones the user selected after the recursion unwinds. Since users often select "high-level" packages that are on a higher numbered disc for the multi-volume release CDROMS this resulted in excessive disc swapping while installing things like kde, gnome, etc. Cut down on disc swapping by iterating through the disc volumes one at a time if we notice the package set is on multiple volumes. If a package is on a higher volume don't install it yet, but still "process it" so we get its dependencies installed. Because of the way the package sets for releases get assembled we're guaranteed dependencies will be on the same volume or lower. Reviewed by: jhb MFC after: 1 week
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/sysinstall/config.c11
-rw-r--r--usr.sbin/sysinstall/globals.c3
-rw-r--r--usr.sbin/sysinstall/index.c56
-rw-r--r--usr.sbin/sysinstall/package.c2
-rw-r--r--usr.sbin/sysinstall/sysinstall.h6
5 files changed, 69 insertions, 9 deletions
diff --git a/usr.sbin/sysinstall/config.c b/usr.sbin/sysinstall/config.c
index bb7ffbc..e550f05 100644
--- a/usr.sbin/sysinstall/config.c
+++ b/usr.sbin/sysinstall/config.c
@@ -737,6 +737,7 @@ configPackages(dialogMenuItem *self)
while (1) {
int ret, pos, scroll;
+ int current, low, high;
/* Bring up the packages menu */
pos = scroll = 0;
@@ -751,8 +752,14 @@ configPackages(dialogMenuItem *self)
else if (DITEM_STATUS(ret) != DITEM_FAILURE) {
dialog_clear();
restoreflag = 1;
- for (tmp = Plist.kids; tmp && tmp->name; tmp = tmp->next)
- (void)index_extract(mediaDevice, &Top, tmp, FALSE);
+ if (have_volumes) {
+ low = low_volume;
+ high = high_volume;
+ } else
+ low = high = 0;
+ for (current = low; current <= high; current++)
+ for (tmp = Plist.kids; tmp && tmp->name; tmp = tmp->next)
+ (void)index_extract(mediaDevice, &Top, tmp, FALSE, current);
break;
}
}
diff --git a/usr.sbin/sysinstall/globals.c b/usr.sbin/sysinstall/globals.c
index 892d852..9119c15 100644
--- a/usr.sbin/sysinstall/globals.c
+++ b/usr.sbin/sysinstall/globals.c
@@ -48,10 +48,13 @@ Boolean DialogActive; /* Is libdialog initialized? */
Boolean ColorDisplay; /* Are we on a color display? */
Boolean OnVTY; /* Are we on a VTY? */
Boolean Restarting; /* Are we restarting sysinstall? */
+Boolean have_volumes; /* Media has more than one volume. */
Variable *VarHead; /* The head of the variable chain */
Device *mediaDevice; /* Where we're installing from */
int BootMgr; /* Which boot manager we're using */
int StatusLine; /* Where to stick our status messages */
+int low_volume; /* Lowest volume number */
+int high_volume; /* Highest volume number */
jmp_buf BailOut; /* Beam me up, scotty! The natives are pissed! */
Chunk *HomeChunk;
diff --git a/usr.sbin/sysinstall/index.c b/usr.sbin/sysinstall/index.c
index a55b541..60e8160 100644
--- a/usr.sbin/sysinstall/index.c
+++ b/usr.sbin/sysinstall/index.c
@@ -225,7 +225,17 @@ new_index(char *name, char *pathto, char *prefix, char *comment, char *descr, ch
tmp->deps = _strdup(deps);
tmp->depc = 0;
tmp->installed = package_installed(name);
+ tmp->vol_checked = 0;
tmp->volume = volume;
+ if (volume != 0) {
+ have_volumes = TRUE;
+ if (low_volume == 0)
+ low_volume = volume;
+ else if (low_volume > volume)
+ low_volume = volume;
+ if (high_volume < volume)
+ high_volume = volume;
+ }
return tmp;
}
@@ -682,9 +692,11 @@ recycle:
}
int
-index_extract(Device *dev, PkgNodePtr top, PkgNodePtr who, Boolean depended)
+index_extract(Device *dev, PkgNodePtr top, PkgNodePtr who, Boolean depended,
+ int current_volume)
{
int status = DITEM_SUCCESS;
+ Boolean notyet = FALSE;
PkgNodePtr tmp2;
IndexEntryPtr id = who->data;
WINDOW *w;
@@ -699,7 +711,7 @@ index_extract(Device *dev, PkgNodePtr top, PkgNodePtr who, Boolean depended)
* a certain faulty INDEX file.
*/
- if (id->installed == 1)
+ if (id->installed == 1 || (have_volumes && id->vol_checked == current_volume))
return DITEM_SUCCESS;
w = savescr();
@@ -712,9 +724,13 @@ index_extract(Device *dev, PkgNodePtr top, PkgNodePtr who, Boolean depended)
if ((cp2 = index(cp, ' ')) != NULL)
*cp2 = '\0';
if ((tmp2 = index_search(top, cp, NULL)) != NULL) {
- status = index_extract(dev, top, tmp2, TRUE);
+ status = index_extract(dev, top, tmp2, TRUE, current_volume);
if (DITEM_STATUS(status) != DITEM_SUCCESS) {
- if (variable_get(VAR_NO_CONFIRM))
+ /* package probably on a future disc volume */
+ if (status & DITEM_CONTINUE) {
+ status = DITEM_SUCCESS;
+ notyet = TRUE;
+ } else if (variable_get(VAR_NO_CONFIRM))
msgNotify("Loading of dependent package %s failed", cp);
else
msgConfirm("Loading of dependent package %s failed", cp);
@@ -732,10 +748,38 @@ index_extract(Device *dev, PkgNodePtr top, PkgNodePtr who, Boolean depended)
cp = NULL;
}
}
- /* Done with the deps? Load the real m'coy */
+
+ /*
+ * If iterating through disc volumes one at a time indicate failure if
+ * dependency install failed due to package being on a higher volume
+ * numbered disc, but that we should continue anyway. Note that this
+ * package has already been processed for this disc volume so we don't
+ * need to do it again.
+ */
+
+ if (notyet) {
+ restorescr(w);
+ id->vol_checked = current_volume;
+ return DITEM_FAILURE | DITEM_CONTINUE;
+ }
+
+ /*
+ * Done with the deps? Try to load the real m'coy. If iterating
+ * through a multi-volume disc set fail the install if the package
+ * is on a higher numbered volume to cut down on disc switches the
+ * user needs to do, but indicate caller should continue processing
+ * despite error return. Note this package was processed for the
+ * current disc being checked.
+ */
+
if (DITEM_STATUS(status) == DITEM_SUCCESS) {
/* Prompt user if the package is not available on the current volume. */
if(mediaDevice->type == DEVICE_TYPE_CDROM) {
+ if (current_volume != 0 && id->volume > current_volume) {
+ restorescr(w);
+ id->vol_checked = current_volume;
+ return DITEM_FAILURE | DITEM_CONTINUE;
+ }
while (id->volume != dev->volume) {
if (!msgYesNo("This is disc #%d. Package %s is on disc #%d\n"
"Would you like to switch discs now?\n", dev->volume,
@@ -801,6 +845,8 @@ index_initialize(char *path)
if (!index_initted) {
w = savescr();
dialog_clear_norefresh();
+ have_volumes = FALSE;
+ low_volume = high_volume = 0;
/* Got any media? */
if (!mediaVerify()) {
diff --git a/usr.sbin/sysinstall/package.c b/usr.sbin/sysinstall/package.c
index bcbf29c..2f416a2 100644
--- a/usr.sbin/sysinstall/package.c
+++ b/usr.sbin/sysinstall/package.c
@@ -69,7 +69,7 @@ package_add(char *name)
tmp = index_search(&Top, name, &tmp);
if (tmp)
- return index_extract(mediaDevice, &Top, tmp, FALSE);
+ return index_extract(mediaDevice, &Top, tmp, FALSE, 0);
else {
msgConfirm("Sorry, package %s was not found in the INDEX.", name);
return DITEM_FAILURE;
diff --git a/usr.sbin/sysinstall/sysinstall.h b/usr.sbin/sysinstall/sysinstall.h
index f0966f4..2bc366d 100644
--- a/usr.sbin/sysinstall/sysinstall.h
+++ b/usr.sbin/sysinstall/sysinstall.h
@@ -384,6 +384,7 @@ typedef struct _indexEntry { /* A single entry in an INDEX file */
char *deps; /* packages this depends on */
int depc; /* how many depend on me */
int installed; /* indicates if it is installed */
+ int vol_checked; /* disc volume last checked for */
char *maintainer; /* maintainer */
unsigned int volume; /* Volume of package */
} IndexEntry;
@@ -416,6 +417,7 @@ extern Boolean RunningAsInit; /* Are we running stand-alone? */
extern Boolean DialogActive; /* Is the dialog() stuff up? */
extern Boolean ColorDisplay; /* Are we on a color display? */
extern Boolean OnVTY; /* On a syscons VTY? */
+extern Boolean have_volumes; /* Media has multiple volumes */
extern Variable *VarHead; /* The head of the variable chain */
extern Device *mediaDevice; /* Where we're getting our distribution from */
extern unsigned int Dists; /* Which distributions we want */
@@ -479,6 +481,8 @@ extern int FixItMode; /* FixItMode starts shell on cur
extern const char * StartName; /* Which name we were started as */
extern const char * ProgName; /* Program's proper name */
extern int NCpus; /* # cpus on machine */
+extern int low_volume; /* Lowest volume number */
+extern int high_volume; /* Highest volume number */
/* Important chunks. */
extern Chunk *HomeChunk;
@@ -670,7 +674,7 @@ void index_init(PkgNodePtr top, PkgNodePtr plist);
void index_node_free(PkgNodePtr top, PkgNodePtr plist);
void index_sort(PkgNodePtr top);
void index_print(PkgNodePtr top, int level);
-int index_extract(Device *dev, PkgNodePtr top, PkgNodePtr who, Boolean depended);
+int index_extract(Device *dev, PkgNodePtr top, PkgNodePtr who, Boolean depended, int current_volume);
int index_initialize(char *path);
PkgNodePtr index_search(PkgNodePtr top, char *str, PkgNodePtr *tp);
OpenPOWER on IntegriCloud