summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Katz <katzj@redhat.com>2004-12-03 22:20:49 +0000
committerJeremy Katz <katzj@redhat.com>2004-12-03 22:20:49 +0000
commit9d9316a234208c12637f930fe2e8d0b81f4550c0 (patch)
treefb360e5be78c247c4664820376ca4be71735327d
parent1b9abddfac3b95d7c4c8d02f67e4060315984fe2 (diff)
downloadanaconda-9d9316a234208c12637f930fe2e8d0b81f4550c0.tar.gz
anaconda-9d9316a234208c12637f930fe2e8d0b81f4550c0.tar.xz
anaconda-9d9316a234208c12637f930fe2e8d0b81f4550c0.zip
2004-12-03 Jeremy Katz <katzj@redhat.com>
* loader2/mediacheck.c: Disable read-ahead for the last meg or so of the CD to try to avoid mediacheck problems (#131051 and others) * loader2/mediacheck.h (mediaCheckFile): Add new arg. * loader2/cdinstall.c (mediaCheckCdrom): Likewise. * loader2/method.c (queryISOMediaCheck): Likewise.
-rw-r--r--ChangeLog6
-rw-r--r--loader2/cdinstall.c2
-rw-r--r--loader2/mediacheck.c58
-rw-r--r--loader2/mediacheck.h2
-rw-r--r--loader2/method.c2
5 files changed, 61 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 30729f037..44ceaee92 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,12 @@
2004-12-03 Jeremy Katz <katzj@redhat.com>
* anaconda.spec: Bump version.
+
+ * loader2/mediacheck.c: Disable read-ahead for the last meg or so
+ of the CD to try to avoid mediacheck problems (#131051 and others)
+ * loader2/mediacheck.h (mediaCheckFile): Add new arg.
+ * loader2/cdinstall.c (mediaCheckCdrom): Likewise.
+ * loader2/method.c (queryISOMediaCheck): Likewise.
* constants.py (BETANAG): turn off beta nag.
diff --git a/loader2/cdinstall.c b/loader2/cdinstall.c
index eac9f6c96..af842229c 100644
--- a/loader2/cdinstall.c
+++ b/loader2/cdinstall.c
@@ -98,7 +98,7 @@ static char * mediaCheckCdrom(char *cddriver) {
if (!ejectcd) {
/* XXX MSFFIXME: should check return code for error */
readStampFileFromIso("/tmp/cdrom", &tstamp, &descr);
- mediaCheckFile("/tmp/cdrom", descr);
+ mediaCheckFile("/tmp/cdrom", descr, 1);
if (descr)
free(descr);
diff --git a/loader2/mediacheck.c b/loader2/mediacheck.c
index e507050e1..6f387e7f3 100644
--- a/loader2/mediacheck.c
+++ b/loader2/mediacheck.c
@@ -9,8 +9,13 @@
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
+#include <errno.h>
#include <newt.h>
+/* FIXME: for turning off read-ahead */
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+
#include "md5.h"
#include "log.h"
@@ -145,7 +150,7 @@ int parsepvd(int isofd, char *mediasum, int *skipsectors, long long *isosize, in
/* mediasum is the sum encoded in media, computedsum is one we compute */
/* both strings must be pre-allocated at least 33 chars in length */
int checkmd5sum(int isofd, char *mediasum, char *computedsum,
- checkCallback cb, void *cbdata) {
+ checkCallback cb, void *cbdata, int isCD) {
int nread;
int i;
int appdata_start_offset, appdata_end_offset;
@@ -157,8 +162,22 @@ int checkmd5sum(int isofd, char *mediasum, char *computedsum,
unsigned int len;
unsigned char *buf;
long long isosize, offset, pvd_offset, apoff;
+ int cfd, readahead_hack = 1, readahead_disabled = 0;
MD5_CTX md5ctx;
+ /* FIXME: the kernel doesn't properly handle EOF on ide-cds.
+ * turning off read-ahead for the last meg or so should help, per alan.
+ * let people opt out of this with "nocdhack" on the boot command line */
+ if ((cfd = open("/proc/cmdline", O_RDONLY)) >= 0) {
+ char buf[1024];
+ int len;
+
+ len = read(cfd, buf, sizeof(buf) - 1);
+ close(cfd);
+ if (strstr(buf, "nocdhack") == NULL)
+ readahead_hack = 0;
+ }
+
isostatus = 0;
if ((pvd_offset = parsepvd(isofd, mediasum, &skipsectors, &isosize, &isostatus)) < 0)
return -1;
@@ -173,6 +192,21 @@ int checkmd5sum(int isofd, char *mediasum, char *computedsum,
buf = malloc(bufsize * sizeof(unsigned char));
while (offset < isosize - skipsectors*2048) {
+ /* turn off read-ahead for the last meg of the CD. see above
+ * for the gory details */
+ if ((isCD == 1) && (offset > (isosize - 1024 * 1024 * 1024))) {
+ if ((readahead_disabled == 0) && (readahead_hack == 1)) {
+ if (ioctl(isofd, BLKRASET, (unsigned long) 0) == -1) {
+ logMessage("failed to disable readahead: %s",
+ strerror(errno));
+ readahead_disabled = -1;
+ } else {
+ logMessage("disabled readahead");
+ readahead_disabled = 1;
+ }
+ }
+ }
+
nattempt = MIN(isosize - skipsectors*2048 - offset, bufsize);
nread = read(isofd, buf, nattempt);
@@ -220,6 +254,18 @@ int checkmd5sum(int isofd, char *mediasum, char *computedsum,
strcat(computedsum, tmpstr);
}
+ /* if we disabled readahead, then we should probably turn it back on.
+ * otherwise, people are going to hate life as their installs take a
+ * week */
+ if (readahead_disabled == 1) {
+ if (ioctl(isofd, BLKRASET, (unsigned long) 256) == -1) {
+ logMessage("failed to re-enable readahead: %s",
+ strerror(errno));
+ } else {
+ logMessage("re-enabled readahead");
+ }
+ }
+
if (strcmp(mediasum, computedsum))
return 0;
else
@@ -242,7 +288,7 @@ static void readCB(void *co, long long pos) {
newtRefresh();
}
-int doMediaCheck(int isofd, char *descr, char *mediasum, char *computedsum, long long *isosize, int *isostatus) {
+int doMediaCheck(int isofd, char *descr, char *mediasum, char *computedsum, long long *isosize, int *isostatus, int isCD) {
struct progressCBdata data;
newtComponent t, f, scale, label;
int rc;
@@ -287,7 +333,7 @@ int doMediaCheck(int isofd, char *descr, char *mediasum, char *computedsum, long
data.scale = scale;
data.label = label;
- rc = checkmd5sum(isofd, mediasum, computedsum, readCB, &data);
+ rc = checkmd5sum(isofd, mediasum, computedsum, readCB, &data, isCD);
newtFormDestroy(f);
newtPopWindow();
@@ -295,7 +341,7 @@ int doMediaCheck(int isofd, char *descr, char *mediasum, char *computedsum, long
return rc;
}
-int mediaCheckFile(char *file, char *descr) {
+int mediaCheckFile(char *file, char *descr, int isCD) {
int isofd;
int rc;
int isostatus;
@@ -315,7 +361,7 @@ int mediaCheckFile(char *file, char *descr) {
}
isostatus = 0;
- rc = doMediaCheck(isofd, descr, mediasum, computedsum, &isosize, &isostatus);
+ rc = doMediaCheck(isofd, descr, mediasum, computedsum, &isosize, &isostatus, isCD);
close(isofd);
if (rc == 0) {
@@ -371,7 +417,7 @@ int main(int argc, char **argv) {
newtInit();
newtCls();
- rc = mediaCheckFile(argv[1], "TESTING");
+ rc = mediaCheckFile(argv[1], "TESTING", 0);
newtFinished();
exit (0);
}
diff --git a/loader2/mediacheck.h b/loader2/mediacheck.h
index 26f7bfbf9..5cfb963ea 100644
--- a/loader2/mediacheck.h
+++ b/loader2/mediacheck.h
@@ -5,7 +5,7 @@
/* Copyright 2001 Red Hat, Inc. */
/* Michael Fulbright msf@redhat.com */
-int mediaCheckFile(char *file, char *descr);
+int mediaCheckFile(char *file, char *descr, int isCD);
int parsepvd(int isofd, char *mediasum, int *skipsectors, long long *isosize, int *isostatus);
#endif
diff --git a/loader2/method.c b/loader2/method.c
index ca31da481..04d9beb2e 100644
--- a/loader2/method.c
+++ b/loader2/method.c
@@ -417,7 +417,7 @@ void queryIsoMediaCheck(char *isoFile, int flags) {
free(tdescr);
continue;
} else {
- mediaCheckFile(isoImage, tdescr);
+ mediaCheckFile(isoImage, tdescr, 0);
if (tdescr)
free(tdescr);