- avoid accessing unrelated mount points in disk space checking (#547548)
This commit is contained in:
parent
6b08a4c01a
commit
459c2d0f81
271
rpm-4.8.0-lazy-statfs.patch
Normal file
271
rpm-4.8.0-lazy-statfs.patch
Normal file
@ -0,0 +1,271 @@
|
||||
diff --git a/lib/transaction.c b/lib/transaction.c
|
||||
index 1860dfb..d913258 100644
|
||||
--- a/lib/transaction.c
|
||||
+++ b/lib/transaction.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "debug.h"
|
||||
|
||||
struct diskspaceInfo_s {
|
||||
+ char * mntPoint; /*!< File system mount point */
|
||||
dev_t dev; /*!< File system device number. */
|
||||
int64_t bneeded; /*!< No. of blocks needed. */
|
||||
int64_t ineeded; /*!< No. of inodes needed. */
|
||||
@@ -61,83 +62,114 @@ struct diskspaceInfo_s {
|
||||
|
||||
static int rpmtsInitDSI(const rpmts ts)
|
||||
{
|
||||
- rpmDiskSpaceInfo dsi;
|
||||
- struct stat sb;
|
||||
- int rc;
|
||||
- int i;
|
||||
-
|
||||
if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_DISKSPACE)
|
||||
return 0;
|
||||
-
|
||||
- rpmlog(RPMLOG_DEBUG, "mounted filesystems:\n");
|
||||
- rpmlog(RPMLOG_DEBUG,
|
||||
- " i dev bsize bavail iavail mount point\n");
|
||||
-
|
||||
- rc = rpmGetFilesystemList(&ts->filesystems, &ts->filesystemCount);
|
||||
- if (rc || ts->filesystems == NULL || ts->filesystemCount <= 0)
|
||||
- return rc;
|
||||
-
|
||||
- /* Get available space on mounted file systems. */
|
||||
-
|
||||
ts->dsi = _free(ts->dsi);
|
||||
- ts->dsi = xcalloc((ts->filesystemCount + 1), sizeof(*ts->dsi));
|
||||
+ ts->filesystemCount = 0;
|
||||
+ ts->dsi = xcalloc(1, sizeof(*ts->dsi));
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
- dsi = ts->dsi;
|
||||
+static rpmDiskSpaceInfo rpmtsCreateDSI(const rpmts ts, dev_t dev,
|
||||
+ const char * dirName, int count)
|
||||
+{
|
||||
+ rpmDiskSpaceInfo dsi;
|
||||
+ struct stat sb;
|
||||
+ char * resolved_path;
|
||||
+ char mntPoint[PATH_MAX];
|
||||
+ int rc;
|
||||
|
||||
- if (dsi != NULL)
|
||||
- for (i = 0; (i < ts->filesystemCount) && dsi; i++, dsi++) {
|
||||
#if STATFS_IN_SYS_STATVFS
|
||||
- struct statvfs sfb;
|
||||
- memset(&sfb, 0, sizeof(sfb));
|
||||
- rc = statvfs(ts->filesystems[i], &sfb);
|
||||
+ struct statvfs sfb;
|
||||
+ memset(&sfb, 0, sizeof(sfb));
|
||||
+ rc = statvfs(dirName, &sfb);
|
||||
#else
|
||||
- struct statfs sfb;
|
||||
- memset(&sfb, 0, sizeof(sfb));
|
||||
+ struct statfs sfb;
|
||||
+ memset(&sfb, 0, sizeof(sfb));
|
||||
# if STAT_STATFS4
|
||||
/* This platform has the 4-argument version of the statfs call. The last two
|
||||
* should be the size of struct statfs and 0, respectively. The 0 is the
|
||||
* filesystem type, and is always 0 when statfs is called on a mounted
|
||||
* filesystem, as we're doing.
|
||||
*/
|
||||
- rc = statfs(ts->filesystems[i], &sfb, sizeof(sfb), 0);
|
||||
+ rc = statfs(dirName, &sfb, sizeof(sfb), 0);
|
||||
# else
|
||||
- rc = statfs(ts->filesystems[i], &sfb);
|
||||
+ rc = statfs(dirName, &sfb);
|
||||
# endif
|
||||
#endif
|
||||
- if (rc)
|
||||
- break;
|
||||
-
|
||||
- rc = stat(ts->filesystems[i], &sb);
|
||||
- if (rc)
|
||||
- break;
|
||||
- dsi->dev = sb.st_dev;
|
||||
-
|
||||
- dsi->bsize = sfb.f_bsize;
|
||||
- dsi->bneeded = 0;
|
||||
- dsi->ineeded = 0;
|
||||
+ if (rc)
|
||||
+ return NULL;
|
||||
+
|
||||
+ rc = stat(dirName, &sb);
|
||||
+ if (rc)
|
||||
+ return NULL;
|
||||
+ if (sb.st_dev != dev) // XXX WHY?
|
||||
+ return NULL;
|
||||
+
|
||||
+ ts->dsi = xrealloc(ts->dsi, (count + 2) * sizeof(*ts->dsi));
|
||||
+ dsi = ts->dsi + count;
|
||||
+ memset(dsi, 0, 2 * sizeof(*dsi));
|
||||
+
|
||||
+ dsi->dev = sb.st_dev;
|
||||
+ dsi->bsize = sfb.f_bsize;
|
||||
+ if (!dsi->bsize)
|
||||
+ dsi->bsize = 512; /* we need a bsize */
|
||||
+ dsi->bneeded = 0;
|
||||
+ dsi->ineeded = 0;
|
||||
#ifdef STATFS_HAS_F_BAVAIL
|
||||
- dsi->bavail = (sfb.f_flag & ST_RDONLY) ? 0 : sfb.f_bavail;
|
||||
+ dsi->bavail = (sfb.f_flag & ST_RDONLY) ? 0 : sfb.f_bavail;
|
||||
#else
|
||||
/* FIXME: the statfs struct doesn't have a member to tell how many blocks are
|
||||
* available for non-superusers. f_blocks - f_bfree is probably too big, but
|
||||
* it's about all we can do.
|
||||
*/
|
||||
- dsi->bavail = sfb.f_blocks - sfb.f_bfree;
|
||||
+ dsi->bavail = sfb.f_blocks - sfb.f_bfree;
|
||||
#endif
|
||||
- /* XXX Avoid FAT and other file systems that have not inodes. */
|
||||
- /* XXX assigning negative value to unsigned type */
|
||||
- dsi->iavail = !(sfb.f_ffree == 0 && sfb.f_files == 0)
|
||||
- ? sfb.f_ffree : -1;
|
||||
- rpmlog(RPMLOG_DEBUG,
|
||||
- "%5d 0x%08x %8" PRId64 " %12" PRId64 " %12" PRId64" %s\n",
|
||||
- i, (unsigned) dsi->dev, dsi->bsize,
|
||||
- dsi->bavail, dsi->iavail,
|
||||
- ts->filesystems[i]);
|
||||
+ /* XXX Avoid FAT and other file systems that have not inodes. */
|
||||
+ /* XXX assigning negative value to unsigned type */
|
||||
+ dsi->iavail = !(sfb.f_ffree == 0 && sfb.f_files == 0)
|
||||
+ ? sfb.f_ffree : -1;
|
||||
+
|
||||
+ /* Find mount point belonging to this device number */
|
||||
+ resolved_path = realpath(dirName, mntPoint);
|
||||
+ if (!resolved_path) {
|
||||
+ strncpy(mntPoint, dirName, PATH_MAX);
|
||||
+ mntPoint[PATH_MAX-1] = '\0';
|
||||
}
|
||||
- return rc;
|
||||
+ char * end = NULL;
|
||||
+ while (end != mntPoint) {
|
||||
+ end = strrchr(mntPoint, '/');
|
||||
+ if (end == mntPoint) { // reached "/"
|
||||
+ stat("/", &sb);
|
||||
+ if (dsi->dev != sb.st_dev) {
|
||||
+ dsi->mntPoint = xstrdup(mntPoint);
|
||||
+ } else {
|
||||
+ dsi->mntPoint = xstrdup("/");
|
||||
+ }
|
||||
+ break;
|
||||
+ } else if (end) {
|
||||
+ *end = '\0';
|
||||
+ } else { // dirName doesn't start with / - should not happen
|
||||
+ dsi->mntPoint = xstrdup(dirName);
|
||||
+ break;
|
||||
+ }
|
||||
+ stat(mntPoint, &sb);
|
||||
+ if (dsi->dev != sb.st_dev) {
|
||||
+ *end = '/';
|
||||
+ dsi->mntPoint = xstrdup(mntPoint);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ rpmlog(RPMLOG_DEBUG,
|
||||
+ "0x%08x %8" PRId64 " %12" PRId64 " %12" PRId64" %s\n",
|
||||
+ (unsigned) dsi->dev, dsi->bsize,
|
||||
+ dsi->bavail, dsi->iavail,
|
||||
+ dsi->mntPoint);
|
||||
+ return dsi;
|
||||
}
|
||||
|
||||
-static void rpmtsUpdateDSI(const rpmts ts, dev_t dev,
|
||||
+static void rpmtsUpdateDSI(const rpmts ts, dev_t dev, const char *dirName,
|
||||
rpm_loff_t fileSize, rpm_loff_t prevSize, rpm_loff_t fixupSize,
|
||||
rpmFileAction action)
|
||||
{
|
||||
@@ -148,8 +180,10 @@ static void rpmtsUpdateDSI(const rpmts ts, dev_t dev,
|
||||
if (dsi) {
|
||||
while (dsi->bsize && dsi->dev != dev)
|
||||
dsi++;
|
||||
- if (dsi->bsize == 0)
|
||||
- dsi = NULL;
|
||||
+ if (dsi->bsize == 0) {
|
||||
+ /* create new entry */
|
||||
+ dsi = rpmtsCreateDSI(ts, dev, dirName, dsi - ts->dsi);
|
||||
+ }
|
||||
}
|
||||
if (dsi == NULL)
|
||||
return;
|
||||
@@ -192,26 +226,22 @@ static void rpmtsCheckDSIProblems(const rpmts ts, const rpmte te)
|
||||
rpmDiskSpaceInfo dsi;
|
||||
rpmps ps;
|
||||
int fc;
|
||||
- int i;
|
||||
-
|
||||
- if (ts->filesystems == NULL || ts->filesystemCount <= 0)
|
||||
- return;
|
||||
|
||||
dsi = ts->dsi;
|
||||
- if (dsi == NULL)
|
||||
+ if (dsi == NULL || !dsi->bsize)
|
||||
return;
|
||||
fc = rpmfiFC(rpmteFI(te));
|
||||
if (fc <= 0)
|
||||
return;
|
||||
|
||||
ps = rpmtsProblems(ts);
|
||||
- for (i = 0; i < ts->filesystemCount; i++, dsi++) {
|
||||
+ for (; dsi->bsize; dsi++) {
|
||||
|
||||
if (dsi->bavail >= 0 && adj_fs_blocks(dsi->bneeded) > dsi->bavail) {
|
||||
if (dsi->bneeded != dsi->obneeded) {
|
||||
rpmpsAppend(ps, RPMPROB_DISKSPACE,
|
||||
rpmteNEVRA(te), rpmteKey(te),
|
||||
- ts->filesystems[i], NULL, NULL,
|
||||
+ dsi->mntPoint, NULL, NULL,
|
||||
(adj_fs_blocks(dsi->bneeded) - dsi->bavail) * dsi->bsize);
|
||||
dsi->obneeded = dsi->bneeded;
|
||||
}
|
||||
@@ -221,7 +251,7 @@ static void rpmtsCheckDSIProblems(const rpmts ts, const rpmte te)
|
||||
if (dsi->ineeded != dsi->oineeded) {
|
||||
rpmpsAppend(ps, RPMPROB_DISKNODES,
|
||||
rpmteNEVRA(te), rpmteKey(te),
|
||||
- ts->filesystems[i], NULL, NULL,
|
||||
+ dsi->mntPoint, NULL, NULL,
|
||||
(adj_fs_blocks(dsi->ineeded) - dsi->iavail));
|
||||
dsi->oineeded = dsi->ineeded;
|
||||
}
|
||||
@@ -230,6 +260,20 @@ static void rpmtsCheckDSIProblems(const rpmts ts, const rpmte te)
|
||||
ps = rpmpsFree(ps);
|
||||
}
|
||||
|
||||
+static void rpmtsFreeDSI(rpmts ts){
|
||||
+ rpmDiskSpaceInfo dsi;
|
||||
+ if (ts == NULL)
|
||||
+ return;
|
||||
+ dsi = ts->dsi;
|
||||
+ while (dsi && dsi->bsize != 0) {
|
||||
+ dsi->mntPoint = _free(dsi->mntPoint);
|
||||
+ dsi++;
|
||||
+ }
|
||||
+
|
||||
+ ts->dsi = _free(ts->dsi);
|
||||
+}
|
||||
+
|
||||
+
|
||||
/**
|
||||
*/
|
||||
static int archOkay(const char * pkgArch)
|
||||
@@ -543,8 +587,9 @@ assert(otherFi != NULL);
|
||||
}
|
||||
|
||||
/* Update disk space info for a file. */
|
||||
- rpmtsUpdateDSI(ts, fiFps->entry->dev, rpmfiFSize(fi),
|
||||
- rpmfiFReplacedSize(fi), fixupSize, rpmfsGetAction(fs, i));
|
||||
+ rpmtsUpdateDSI(ts, fiFps->entry->dev, fiFps->entry->dirName,
|
||||
+ rpmfiFSize(fi), rpmfiFReplacedSize(fi),
|
||||
+ fixupSize, rpmfsGetAction(fs, i));
|
||||
|
||||
}
|
||||
ps = rpmpsFree(ps);
|
||||
@@ -1338,6 +1383,7 @@ static int rpmtsPrepare(rpmts ts)
|
||||
exit:
|
||||
ht = rpmFpHashFree(ht);
|
||||
fpc = fpCacheFree(fpc);
|
||||
+ rpmtsFreeDSI(ts);
|
||||
return rc;
|
||||
}
|
||||
|
3
rpm.spec
3
rpm.spec
@ -46,6 +46,7 @@ Patch200: rpm-4.8.0-url-segfault.patch
|
||||
Patch201: rpm-4.8.0-verify-exitcode.patch
|
||||
Patch202: rpm-4.8.0-pythondeps-parallel.patch
|
||||
Patch203: rpm-4.8.0-python-bytecompile.patch
|
||||
Patch204: rpm-4.8.0-lazy-statfs.patch
|
||||
|
||||
# These are not yet upstream
|
||||
Patch301: rpm-4.6.0-niagara.patch
|
||||
@ -197,6 +198,7 @@ packages on a system.
|
||||
%patch201 -p1 -b .verify-exitcode
|
||||
%patch202 -p1 -b .pythondeps-parallel
|
||||
%patch203 -p1 -b .python-bytecompile
|
||||
%patch204 -p1 -b .lazy-statfs
|
||||
|
||||
%patch301 -p1 -b .niagara
|
||||
%patch302 -p1 -b .geode
|
||||
@ -415,6 +417,7 @@ exit 0
|
||||
%changelog
|
||||
* Fri Feb 05 2010 Panu Matilainen <pmatilai@redhat.com> - 4.8.0-8
|
||||
- more fixes to postscript provides extractor (#562228)
|
||||
- avoid accessing unrelated mount points in disk space checking (#547548)
|
||||
|
||||
* Fri Feb 05 2010 Panu Matilainen <pmatilai@redhat.com> - 4.8.0-7
|
||||
- couple of fixes to the postscript provides extractor (#538101)
|
||||
|
Loading…
Reference in New Issue
Block a user