- fix: for busted db1, attempt chain reconnection to following record.

CVS patchset: 4819
CVS date: 2001/05/30 22:42:43
This commit is contained in:
jbj 2001-05-30 22:42:43 +00:00
parent 2a4452a1f9
commit cc54f00167
7 changed files with 183 additions and 51 deletions

View File

@ -70,6 +70,7 @@
- popt: return POPT_ERROR_ERRNO on config open/read/close failure.
- fix: popt exec doesn't add '--', --target et al no longer need '='.
- fix: popt consume-next-arg "!#:+" w/o side effect (#41956).
- fix: for busted db1, attempt chain reconnection to following record.
4.0 -> 4.0.[12]
- add doxygen and lclint annotations most everywhere.

View File

@ -979,7 +979,7 @@ static void defaultMachine(/*@out@*/ const char ** arch, /*@out@*/ const char **
if (!gotDefaults) {
rc = uname(&un);
if (rc) return;
if (rc < 0) return;
#if !defined(__linux__)
#ifdef SNI

View File

@ -31,8 +31,6 @@ BuildRequires: db3-devel
# XXX linked binaries like /bin/rpm.
%ifnarch ia64
Requires: glibc >= 2.1.92
# XXX needed to avoid libdb.so.2 satisfied by compat/libc5 provides.
Requires: db1 = 1.85
%endif
%endif
@ -119,9 +117,9 @@ capabilities.
%build
%ifos linux
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{__prefix} --sysconfdir=/etc --localstatedir=/var --infodir='${prefix}%{__share}/info' --mandir='${prefix}%{__share}/man' # --enable-db1
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{__prefix} --sysconfdir=/etc --localstatedir=/var --infodir='${prefix}%{__share}/info' --mandir='${prefix}%{__share}/man'
%else
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{__prefix} # --enable-db1
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{__prefix}
%endif
make
@ -141,9 +139,17 @@ mkdir -p ${RPM_BUILD_ROOT}/etc/logrotate.d
install -m 755 scripts/rpm.log ${RPM_BUILD_ROOT}/etc/logrotate.d/rpm
mkdir -p $RPM_BUILD_ROOT/etc/rpm
#cat << E_O_F > $RPM_BUILD_ROOT/etc/rpm/macros.db1
#%%_dbapi 1
#E_O_F
cat << E_O_F > $RPM_BUILD_ROOT/etc/rpm/macros.db1
%%_dbapi 1
E_O_F
mkdir -p $RPM_BUILD_ROOT/var/lib/rpm
for dbi in \
Basenames Conflictname Dirnames Group Installtid Name Providename \
Provideversion Removetid Requirename Requireversion Triggername
do
touch $RPM_BUILD_ROOT/var/lib/rpm/dbi
done
%endif
@ -163,27 +169,36 @@ rm -rf $RPM_BUILD_ROOT
%pre
%ifos linux
if [ -f /var/lib/rpm/packages.rpm ]; then
if [ -f /var/lib/rpm/Packages -a -f /var/lib/rpm/packages.rpm ]; then
echo "
This version of rpm does not have db1 support, install rpm-4.0.2 and
do rpm --rebuilddb to convert your database from db1 to db3 format.
You have both
/var/lib/rpm/packages.rpm db1 format installed package headers
/var/lib/rpm/Packages db3 format installed package headers
Please remove (or at least rename) one of those files, and re-install.
"
exit 1
fi
/usr/sbin/groupadd -g 37 rpm
/usr/sbin/useradd -d /var/lib/rpm -u 37 -g 37 rpm
/usr/sbin/groupadd -g 37 @RPMGROUP@ > /dev/null 2>&1
/usr/sbin/useradd -d /var/lib/rpm -u 37 -g 37 @RPMUSER@ > /dev/null 2>&1
%endif
exit 0
%post
%ifos linux
/sbin/ldconfig
if [ -f /var/lib/rpm/packages.rpm ]; then
: # do nothing
elif [ -f /var/lib/rpm/Packages ]; then
# undo db1 configuration
rm -f /etc/rpm/macros.db1
else
# initialize db3 database
rm -f /etc/rpm/macros.db1
/bin/rpm --initdb
fi
/bin/chown @RPMUSER@.@RPMGROUP@ /var/lib/rpm/[A-Z]* /var/lib/rpm/*.rpm
%endif
# initialize db3 database
/bin/rpm --initdb
/bin/chown @RPMUSER@.@RPMGROUP@ /var/lib/rpm/[A-Z]*
exit 0
%ifos linux
%postun
@ -215,7 +230,22 @@ fi
%config(missingok) /etc/cron.daily/rpm
%config(missingok) /etc/logrotate.d/rpm
%dir /etc/rpm
#%config(missingok) /etc/rpm/macros.db1
%config(missingok) /etc/rpm/macros.db1
%attr(0755, @RPMUSER@, @RPMGROUP@) %dir /var/lib/rpm
%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Basenames
%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Conflictname
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/__db.001
%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Dirnames
%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Group
%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Installtid
%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Name
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Packages
%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Providename
%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Provideversion
%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Removetid
%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Requirename
%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Requireversion
%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Triggername
%endif
%attr(0755, @RPMUSER@, @RPMGROUP@) %{__prefix}/bin/rpm2cpio
@ -241,22 +271,6 @@ fi
%attr(0644, @RPMUSER@, @RPMGROUP@) %{__prefix}/lib/rpm/rpmpopt*
%attr(0644, @RPMUSER@, @RPMGROUP@) %{__prefix}/lib/rpm/rpmrc
%attr(0755, @RPMUSER@, @RPMGROUP@) %dir /var/lib/rpm
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Basenames
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Conflictname
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/__db.001
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Dirnames
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Group
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Installtid
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Name
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Packages
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Providename
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Provideversion
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Removetid
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Requirename
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Requireversion
#%attr(0755, @RPMUSER@, @RPMGROUP@) %ghost /var/lib/rpm/Triggername
%ifarch i386 i486 i586 i686 athlon
%attr(-, @RPMUSER@, @RPMGROUP@) %{__prefix}/lib/rpm/i[3456]86*
%endif

View File

@ -30,7 +30,7 @@ lib_LTLIBRARIES = librpmdb.la
librpmdb_la_SOURCES = $(DBLIBSRCS) dbconfig.c fprint.c rpmhash.c rpmdb.c
librpmdb_la_LDFLAGS = @libdb3@
librpmdb_la_LIBADD = $(DBLIBOBJS) $(DB3LOBJS)
librpmdb_la_DEPENDENCIES = $(DBLIBOBJS) createlinks
librpmdb_la_DEPENDENCIES = $(DBLIBOBJS) .created
# XXX Add internal libtool dependence
install-data-local:
@ -41,11 +41,11 @@ install-data-local:
falloc.lo: falloc.c $(top_srcdir)/system.h $(top_srcdir)/rpmio/rpmio.h falloc.h
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.PHONY: createlinks
createlinks:
.created:
for lo in $(DB3LOBJS); do \
[ -f $$lo ] || $(LN_S) $(top_builddir)/$(WITH_DB_SUBDIR)/$$lo $$lo ; \
done
touch $@
clean-local:
rm -f $(DB3LOBJS)
@ -57,3 +57,6 @@ sources:
.PHONY: lclint
lclint:
lclint $(DEFS) $(INCLUDES) $(librpmdb_la_SOURCES)
tfalloc: librpmdb.la tfalloc.o
$(LINK) -all-static $@.o $< $(mylibpaths) $(mylibs) $(LIBS)

View File

@ -128,14 +128,17 @@ static int db1sync(dbiIndex dbi, /*@unused@*/ unsigned int flags) {
return rc;
}
/*@null@*/ static void * doGetRecord(FD_t pkgs, unsigned int offset)
/*@null@*/ static void * doGetRecord(dbiIndex dbi, unsigned int offset)
{
FD_t pkgs = dbi->dbi_db;
void * uh = NULL;
Header h = NULL;
const char ** fileNames;
int fileCount = 0;
int lasto = 0;
int i;
retry:
if (offset >= fadGetFileSize(pkgs))
goto exit;
@ -144,7 +147,8 @@ static int db1sync(dbiIndex dbi, /*@unused@*/ unsigned int flags) {
h = headerRead(pkgs, HEADER_MAGIC_NO);
/* let's sanity check this record a bit, otherwise just skip it */
if (!( headerIsEntry(h, RPMTAG_NAME) &&
if (h != NULL &&
!( headerIsEntry(h, RPMTAG_NAME) &&
headerIsEntry(h, RPMTAG_VERSION) &&
headerIsEntry(h, RPMTAG_RELEASE) &&
headerIsEntry(h, RPMTAG_BUILDTIME)))
@ -152,8 +156,26 @@ static int db1sync(dbiIndex dbi, /*@unused@*/ unsigned int flags) {
h = headerFree(h);
}
if (h == NULL)
if (h == NULL) {
/* XXX HACK: try to reconnect broken chain. */
if (lasto == 0) {
rpmMessage(RPMMESS_WARNING,
_("Broken package chain at offset %d(0x%08x), attempting to reconnect ...\n"),
(int) offset, offset);
lasto = (offset ? offset : -1);
offset = fadNextOffset(pkgs, offset);
if (offset > 0)
goto retry;
}
goto exit;
}
if (lasto) {
rpmMessage(RPMMESS_WARNING,
_("Reconnecting broken chain at offset %d(0x%08x).\n"),
(int) offset, offset);
dbi->dbi_lastoffset = offset;
}
/* Retrofit "Provide: name = EVR" for binary packages. */
providePackageNVR(h);
@ -169,7 +191,8 @@ static int db1sync(dbiIndex dbi, /*@unused@*/ unsigned int flags) {
* list.
*/
if (!headerGetEntryMinMemory(h, RPMTAG_OLDFILENAMES, NULL,
(const void **) &fileNames, &fileCount)) goto exit;
(const void **) &fileNames, &fileCount))
goto exit;
for (i = 0; i < fileCount; i++)
if (*fileNames[i] != '/') break;
@ -274,13 +297,8 @@ static int db1cget(dbiIndex dbi, /*@unused@*/ DBC * dbcursor, void ** keyp,
memcpy(data.data, &offset, sizeof(offset));
data.size = sizeof(offset);
} else { /* XXX simulated retrieval */
data.data = doGetRecord(pkgs, offset);
data.data = doGetRecord(dbi, offset);
data.size = 0; /* XXX WRONG */
if (data.data == NULL) {
if (keyp) *keyp = key.data;
if (keylen) *keylen = key.size;
rc = EFAULT;
}
}
}
#ifdef DYING

View File

@ -13,6 +13,7 @@
#include "system.h"
#include <rpmio_internal.h>
#include <rpmmessages.h>
#include <rpmerr.h>
#include "falloc.h"
#include "debug.h"
@ -379,6 +380,42 @@ void fadFree(FD_t fd, unsigned int offset)
}
}
static int insane = 0;
static int fadSanity(FD_t fd, int offset, struct faHeader * fh)
{
int rc = 0;
if (fh->size <= 0 || fh->size > 0x00200000 || (fh->size & 0x3f) != 0)
rc |= 0x1;
if (fh->freeNext &&
!( fh->freeNext > sizeof(struct faFileHeader) &&
fh->freeNext < fadGetFileSize(fd) &&
(fh->freeNext & 0x3f) == sizeof(struct faFileHeader)) )
rc |= 0x2;
if (fh->freePrev &&
!( fh->freePrev > sizeof(struct faFileHeader) &&
fh->freePrev < fadGetFileSize(fd) &&
(fh->freePrev & 0x3f) == sizeof(struct faFileHeader)) )
rc |= 0x4;
if (fh->isFree & ~1)
rc |= 0x8;
if (!insane && rc) {
rpmMessage(RPMMESS_DEBUG,
"offset %d(0x%08x) rc %d: size 0x%08x next %d(0x%08x) prev %d(0x%08x) isFree 0x%08x\n",
offset, (unsigned) offset, rc,
(unsigned) fh->size,
(int) fh->freeNext, fh->freeNext,
(int) fh->freePrev, fh->freePrev,
(unsigned) fh->isFree);
}
return rc;
}
int fadFirstOffset(FD_t fd)
{
return fadNextOffset(fd, 0);
@ -388,6 +425,7 @@ int fadNextOffset(FD_t fd, unsigned int lastOffset)
{
struct faHeader header;
int offset;
int rc;
offset = (lastOffset)
? (lastOffset - sizeof(header))
@ -400,17 +438,45 @@ int fadNextOffset(FD_t fd, unsigned int lastOffset)
if (Pread(fd, &header, sizeof(header), offset) != sizeof(header))
return 0;
if (!lastOffset && !header.isFree)
if (!lastOffset && header.isFree == 0)
return (offset + sizeof(header));
/*
* XXX Try to reconnect at next record found. This isn't perfect
* XXX but handles many common db1 corruption problems.
*/
rc = fadSanity(fd, offset, &header);
if (rc) {
struct faHeader myheader;
int o = offset + sizeof(header);
memset(&myheader, 0, sizeof(myheader));
insane = 1;
for ( o = offset + 0x40;
o < fadGetFileSize(fd);
o += 0x40)
{
rc = Pread(fd, &myheader, sizeof(myheader), o);
if (rc != sizeof(header))
return 0;
rc = fadSanity(fd, o, &myheader);
if (rc == 0)
break;
}
insane = 0;
if (o >= fadGetFileSize(fd))
return 0;
return (o + sizeof(header));
}
do {
offset += header.size;
if (Pread(fd, &header, sizeof(header), offset) != sizeof(header))
return 0;
if (!header.isFree) break;
} while (offset < fadGetFileSize(fd) && header.isFree);
if (header.isFree == 0) break;
} while (offset < fadGetFileSize(fd) && header.isFree == 1);
if (offset < fadGetFileSize(fd)) {
/* Sanity check this to make sure we're not going in loops */

30
rpmdb/tfalloc.c Normal file
View File

@ -0,0 +1,30 @@
#include "system.h"
#include <rpmlib.h>
#include "rpmio_internal.h"
#include "falloc.h"
#include "debug.h"
#define RPMDBFN "/var/lib/rpm/packages.rpm"
static const char * rpmdbfn = RPMDBFN;
int main(int argc, const char ** argv)
{
int lasto = 0;
FD_t fd;
fd = fadOpen(rpmdbfn, O_RDONLY, 0644);
if (fd == NULL) {
fprintf(stderr, "fadOpen(%s) failed\n", rpmdbfn);
exit(1);
}
fprintf(stderr, "%s: size %d(0x%08x)\n", rpmdbfn, fadGetFileSize(fd), (unsigned) fadGetFileSize(fd));
while ((lasto = fadNextOffset(fd, lasto)) > 0) {
fprintf(stderr, "%10d\n", lasto);
}
(void) Fclose(fd);
return 0;
}