- fix memory corruption on rpmdb size estimation (#766260)

- fix couple of memleaks in python bindings (#782147)
- fix regression in verify output formatting (#797964)
- dont process spec include in false branch of if (#782970)
- only warn on missing excluded files on build (#745629)
- dont free up file info sets on test transactions
This commit is contained in:
Panu Matilainen 2012-03-07 12:01:39 +02:00
parent e8efccb3d4
commit d06308ca0b
7 changed files with 356 additions and 1 deletions

View File

@ -0,0 +1,57 @@
commit cce686b2129e4e8dc27f1a640f7c4746f9ffb032
Author: Panu Matilainen <pmatilai@redhat.com>
Date: Sun Oct 23 13:59:46 2011 +0300
Warn but don't fail the build on missing excluded files (RhBug:745629)
- If a file/directory is not to be packaged, there's not a whole lot
point making the build fail if its missing. In case exclude is
used to leave certain files to sub-packages, the sub-package file
lists will catch out missing files that are really missing as a
result of actual build failure or such (except perhaps for some
glob cases but missing files can go unnoticed in those cases anyway)
- backported from commit 084a00bf51a941ec85c094a436bda401fccf7d3a
diff --git a/build/files.c b/build/files.c
index e0747f8..a520410 100644
--- a/build/files.c
+++ b/build/files.c
@@ -1393,12 +1393,17 @@ static rpmRC addFile(FileList fl, const char * diskPath,
statp->st_mtime = now;
statp->st_ctime = now;
} else {
+ int rc = RPMRC_FAIL;
+ int lvl = RPMLOG_ERR;
const char *msg = fl->isDir ?
_("Directory not found: %s\n") :
_("File not found: %s\n");
- rpmlog(RPMLOG_ERR, msg, diskPath);
- fl->processingFailed = 1;
- return RPMRC_FAIL;
+ if (fl->currentFlags & RPMFILE_EXCLUDE) {
+ lvl = RPMLOG_WARNING;
+ rc = RPMRC_OK;
+ }
+ rpmlog(lvl, msg, diskPath);
+ return rc;
}
}
}
@@ -1702,11 +1707,15 @@ static rpmRC processBinaryFile(Package pkg, FileList fl, const char * fileName)
}
argvFree(argv);
} else {
+ int lvl = RPMLOG_WARNING;
const char *msg = (fl->isDir) ?
_("Directory not found by glob: %s\n") :
_("File not found by glob: %s\n");
- rpmlog(RPMLOG_ERR, msg, diskPath);
- rc = RPMRC_FAIL;
+ if (!(fl->currentFlags & RPMFILE_EXCLUDE)) {
+ lvl = RPMLOG_ERR;
+ rc = RPMRC_FAIL;
+ }
+ rpmlog(lvl, msg, diskPath);
goto exit;
}
} else {

View File

@ -0,0 +1,21 @@
commit bf92b843fabd6c9881b19efb0cae1578d16e4f7b
Author: Panu Matilainen <pmatilai@redhat.com>
Date: Tue Feb 28 12:18:10 2012 +0200
Don't process spec %include in false branch of %if clauses (RhBug:782970)
(backported from commit 9defc922e971d98203890f1557ab951ec94f2a3f)
diff --git a/build/parseSpec.c b/build/parseSpec.c
index 01620bd..01c3c08 100644
--- a/build/parseSpec.c
+++ b/build/parseSpec.c
@@ -374,7 +374,8 @@ int readLine(rpmSpec spec, int strip)
spec->readStack = spec->readStack->next;
free(rl);
spec->line[0] = '\0';
- } else if (rstreqn("%include", s, sizeof("%include")-1)) {
+ } else if (spec->readStack->reading &&
+ rstreqn("%include", s, sizeof("%include")-1)) {
char *fileName, *endFileName, *p;
s += 8;

View File

@ -0,0 +1,66 @@
commit 59807943af5c10c892b239f11b8fafb209254a4a
Author: David Malcolm <dmalcolm@redhat.com>
Date: Thu Dec 15 22:22:56 2011 -0500
fix memory leaks in invocations of PyObject_Call
- Various functions in the Python bindings have expressions of the form:
PyObject_Call(callable,
Py_BuildValue(fmtstring, ...), NULL);
This leaks memory for the case when Py_BuildValue succeeds (it returns a
new reference, which is never freed; PyObject_Call doesn't steal the
reference): the argument tuple and all of its components will not be
freed (until the process exits).
Signed-off-by: Ales Kozumplik <akozumpl@redhat.com>
diff --git a/python/header-py.c b/python/header-py.c
index 96cf200..cef457b 100644
--- a/python/header-py.c
+++ b/python/header-py.c
@@ -295,8 +295,7 @@ static PyObject * hdrWrite(hdrObject *s, PyObject *args, PyObject *kwds)
*/
static PyObject * hdr_fiFromHeader(PyObject * s, PyObject * args, PyObject * kwds)
{
- return PyObject_Call((PyObject *) &rpmfi_Type,
- Py_BuildValue("(O)", s), NULL);
+ return PyObject_CallFunctionObjArgs((PyObject *) &rpmfi_Type, s, NULL);
}
/* Backwards compatibility. Flags argument is just a dummy and discarded. */
@@ -309,14 +308,14 @@ static PyObject * hdr_dsFromHeader(PyObject * s, PyObject * args, PyObject * kwd
tagNumFromPyObject, &tag, &flags))
return NULL;
- return PyObject_Call((PyObject *) &rpmds_Type,
- Py_BuildValue("(Oi)", s, tag), NULL);
+ return PyObject_CallFunction((PyObject *) &rpmds_Type,
+ "(Oi)", s, tag);
}
static PyObject * hdr_dsOfHeader(PyObject * s)
{
- return PyObject_Call((PyObject *) &rpmds_Type,
- Py_BuildValue("(Oi)", s, RPMTAG_NEVR), NULL);
+ return PyObject_CallFunction((PyObject *) &rpmds_Type,
+ "(Oi)", s, RPMTAG_NEVR);
}
static long hdr_hash(PyObject * h)
diff --git a/python/rpmfd-py.c b/python/rpmfd-py.c
index 89a70cd..1150aa1 100644
--- a/python/rpmfd-py.c
+++ b/python/rpmfd-py.c
@@ -23,8 +23,8 @@ int rpmfdFromPyObject(PyObject *obj, rpmfdObject **fdop)
Py_INCREF(obj);
fdo = (rpmfdObject *) obj;
} else {
- fdo = (rpmfdObject *) PyObject_Call((PyObject *)&rpmfd_Type,
- Py_BuildValue("(O)", obj), NULL);
+ fdo = (rpmfdObject *) PyObject_CallFunctionObjArgs((PyObject *)&rpmfd_Type,
+ obj, NULL);
}
if (fdo == NULL) return 0;

98
rpm-4.9.x-rpmdb-dsi.patch Normal file
View File

@ -0,0 +1,98 @@
diff --git a/lib/transaction.c b/lib/transaction.c
index 7adf60b..5acc08e 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -227,46 +227,12 @@ static void rpmtsUpdateDSI(const rpmts ts, dev_t dev, const char *dirName,
if (dsi->ineeded < dsi->oineeded) dsi->oineeded = dsi->ineeded;
}
-/* return DSI of the device the rpmdb lives on */
-static rpmDiskSpaceInfo rpmtsDbDSI(const rpmts ts) {
- const char *dbhome = rpmdbHome(rpmtsGetRdb(ts));
- struct stat sb;
- int rc;
-
- rc = stat(dbhome, &sb);
- if (rc) {
- return NULL;
- }
- return rpmtsGetDSI(ts, sb.st_dev, dbhome);
-}
-
-/* Update DSI for changing size of the rpmdb */
-static void rpmtsUpdateDSIrpmDBSize(const rpmte p,
- rpmDiskSpaceInfo dsi) {
- rpm_loff_t headerSize;
- int64_t bneeded;
-
- /* XXX somehow we can end up here with bsize 0 (RhBug:671056) */
- if (dsi == NULL || dsi->bsize == 0) return;
-
- headerSize = rpmteHeaderSize(p);
- bneeded = BLOCK_ROUND(headerSize, dsi->bsize);
- /* REMOVE doesn't neccessarily shrink the database */
- if (rpmteType(p) == TR_ADDED) {
- /* guessing that db grows 4 times more than the header size */
- dsi->bneeded += (bneeded * 4);
- }
-}
-
-
static void rpmtsCheckDSIProblems(const rpmts ts, const rpmte te)
{
rpmDiskSpaceInfo dsi = ts->dsi;
if (dsi == NULL || !dsi->bsize)
return;
- if (rpmfiFC(rpmteFI(te)) <= 0)
- return;
for (; dsi->bsize; dsi++) {
@@ -1294,11 +1260,12 @@ static int rpmtsPrepare(rpmts ts)
rpmfi fi;
int rc = 0;
uint64_t fileCount = countFiles(ts);
+ const char *dbhome = NULL;
+ struct stat dbstat;
fingerPrintCache fpc = fpCacheCreate(fileCount/2 + 10001);
rpmFpHash ht = rpmFpHashCreate(fileCount/2+1, fpHashFunction, fpEqual,
NULL, NULL);
- rpmDiskSpaceInfo dsi;
rpmlog(RPMLOG_DEBUG, "computing %" PRIu64 " file fingerprints\n", fileCount);
@@ -1326,7 +1293,10 @@ static int rpmtsPrepare(rpmts ts)
/* check against files in the rpmdb */
checkInstalledFiles(ts, fileCount, ht, fpc);
- dsi = rpmtsDbDSI(ts);
+ dbhome = rpmdbHome(rpmtsGetRdb(ts));
+ /* If we can't stat, ignore db growth. Probably not right but... */
+ if (dbhome && stat(dbhome, &dbstat))
+ dbhome = NULL;
pi = rpmtsiInit(ts);
while ((p = rpmtsiNext(pi, 0)) != NULL) {
@@ -1338,10 +1308,18 @@ static int rpmtsPrepare(rpmts ts)
needs on each partition for this package. */
handleOverlappedFiles(ts, ht, p, fi);
- rpmtsUpdateDSIrpmDBSize(p, dsi);
-
/* Check added package has sufficient space on each partition used. */
if (rpmteType(p) == TR_ADDED) {
+ /*
+ * Try to estimate space needed for rpmdb growth: guess that the
+ * db grows 4 times the header size (indexes and all).
+ */
+ if (dbhome) {
+ int64_t hsize = rpmteHeaderSize(p) * 4;
+ rpmtsUpdateDSI(ts, dbstat.st_dev, dbhome,
+ hsize, 0, 0, FA_CREATE);
+ }
+
rpmtsCheckDSIProblems(ts, p);
}
(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);

View File

@ -0,0 +1,43 @@
commit 7d88d5e54a9c3fa2b7fb443921c8adb799051784
Author: Panu Matilainen <pmatilai@redhat.com>
Date: Wed Feb 1 17:48:20 2012 +0200
Don't free up file info sets on transaction test-runs
- We'd like to get rid of the potentially huge amounts of memory
eaten by file info sets as early as possible, but when there's a
chance that we'll get called again with either added transacation
elements or on-disk changes, such as %pretrans changing something
underneath us, we need to (be able to) recalculate everything
from scratch. Only free up the memory when we know we dont need
it anymore, ie on an actual transaction run.
- This doesn't change anything for rpm itself, for yum and others
which do a separate test-transaction first, it means %pretrans
directory<->symlink replacement hacks and the like have a chance
of working again. I'm sure there's a bug filed on this somewhere but...
(cherry picked from commit cef18c94807af0935b7796c462aab8ed39f0f376)
diff --git a/lib/transaction.c b/lib/transaction.c
index 56ebc17..8d29ab9 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -1355,12 +1355,14 @@ static int rpmtsPrepare(rpmts ts)
if (rpmChrootOut())
rc = -1;
- /* File info sets, fp caches etc not needed beyond here, free 'em up. */
- pi = rpmtsiInit(ts);
- while ((p = rpmtsiNext(pi, 0)) != NULL) {
- rpmteSetFI(p, NULL);
+ /* On actual transaction, file info sets are not needed after this */
+ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))) {
+ pi = rpmtsiInit(ts);
+ while ((p = rpmtsiNext(pi, 0)) != NULL) {
+ rpmteSetFI(p, NULL);
+ }
+ rpmtsiFree(pi);
}
- pi = rpmtsiFree(pi);
exit:
ht = rpmFpHashFree(ht);

View File

@ -0,0 +1,50 @@
commit 4e207bfdfce434a6484babc14fe86aeadeec5329
Author: Panu Matilainen <pmatilai@redhat.com>
Date: Tue Feb 28 10:31:28 2012 +0200
Unbreak rpm -V output (RhBug:797964)
- Commit ac0ab016a5ec31e65eb0c0910a5a6f1199aae3e7 unintentionally
changed the order of the problems shown in verify strings due to
a dumb oversight (greetings to self, duh). In other words, this
fixes a verify output regression in rpm >= 4.9.x by restoring
the long-standing (and documented) order of the verify output chars.
- Also fix the testcase which unfortunately was only added after
the output-changing commit so it didn't catch the breakage either :-/
diff --git a/lib/verify.c b/lib/verify.c
index 35612fe..1edb27f 100644
--- a/lib/verify.c
+++ b/lib/verify.c
@@ -292,14 +292,14 @@ char * rpmVerifyString(uint32_t verifyResult, const char *pad)
{
char *fmt = NULL;
rasprintf(&fmt, "%s%s%s%s%s%s%s%s%s",
- _verifyfile(RPMVERIFY_FILEDIGEST, "5", pad),
_verify(RPMVERIFY_FILESIZE, "S", pad),
- _verifylink(RPMVERIFY_LINKTO, "L", pad),
- _verify(RPMVERIFY_MTIME, "T", pad),
+ _verify(RPMVERIFY_MODE, "M", pad),
+ _verifyfile(RPMVERIFY_FILEDIGEST, "5", pad),
_verify(RPMVERIFY_RDEV, "D", pad),
+ _verifylink(RPMVERIFY_LINKTO, "L", pad),
_verify(RPMVERIFY_USER, "U", pad),
_verify(RPMVERIFY_GROUP, "G", pad),
- _verify(RPMVERIFY_MODE, "M", pad),
+ _verify(RPMVERIFY_MTIME, "T", pad),
_verify(RPMVERIFY_CAPS, "P", pad));
return fmt;
diff --git a/tests/rpmverify.at b/tests/rpmverify.at
index dd23a4a..77d6bfe 100644
--- a/tests/rpmverify.at
+++ b/tests/rpmverify.at
@@ -79,7 +79,7 @@ dd if=/dev/zero of="${RPMTEST}"/usr/local/bin/hello \
runroot rpm -Va --nodeps --nouser --nogroup
],
[1],
-[5..T...M. /usr/local/bin/hello
+[.M5....T. /usr/local/bin/hello
missing d /usr/share/doc/hello-1.0/FAQ
],
[])

View File

@ -21,7 +21,7 @@
Summary: The RPM package management system
Name: rpm
Version: %{rpmver}
Release: %{?snapver:0.%{snapver}.}12%{?dist}
Release: %{?snapver:0.%{snapver}.}13%{?dist}
Group: System Environment/Base
Url: http://www.rpm.org/
Source0: http://rpm.org/releases/rpm-4.9.x/%{name}-%{srcver}.tar.bz2
@ -47,6 +47,12 @@ Patch100: rpm-4.9.x-fontattr.patch
Patch101: rpm-4.9.x-elfattr.patch
Patch102: rpm-4.9.1.2-perl-python-attr.patch
Patch103: rpm-4.9.x-mpsize.patch
Patch104: rpm-4.9.x-rpmdb-dsi.patch
Patch105: rpm-4.9.x-python-memleaks.patch
Patch106: rpm-4.9.x-verify-output.patch
Patch107: rpm-4.9.x-include-cond.patch
Patch108: rpm-4.9.x-exclude-warn.patch
Patch109: rpm-4.9.x-tstest-fileinfo.patch
# These are not yet upstream
Patch301: rpm-4.6.0-niagara.patch
@ -228,6 +234,12 @@ packages on a system.
%patch101 -p1 -b .elfattr
%patch102 -p1 -b .perl-python-attr
%patch103 -p1 -b .mpsize
%patch104 -p1 -b .rpmdb-dsi
%patch105 -p1 -b .python-memleaks
%patch106 -p1 -b .verify-output
%patch107 -p1 -b .include-cond
%patch108 -p1 -b .exclude-warn
%patch109 -p1 -b .tstest-fileinfo
%patch301 -p1 -b .niagara
%patch302 -p1 -b .geode
@ -457,6 +469,14 @@ exit 0
%doc COPYING doc/librpm/html/*
%changelog
* Wed Mar 07 2012 Panu Matilainen <pmatilai@redhat.com> - 4.9.1.2-13
- fix memory corruption on rpmdb size estimation (#766260)
- fix couple of memleaks in python bindings (#782147)
- fix regression in verify output formatting (#797964)
- dont process spec include in false branch of if (#782970)
- only warn on missing excluded files on build (#745629)
- dont free up file info sets on test transactions
* Thu Feb 09 2012 Panu Matilainen <pmatilai@redhat.com> - 4.9.1.2-12
- switch back to smaller BDB cache default (#752897)