rpm/lazystatfs.diff

275 lines
8.3 KiB
Diff
Raw Normal View History

--- ./configure.ac.orig 2010-03-25 15:16:21.000000000 +0000
+++ ./configure.ac 2010-03-25 15:27:47.000000000 +0000
@@ -510,25 +510,25 @@ dnl
found_struct_statfs=no
if test X$found_struct_statfs = Xno ; then
-dnl Solaris 2.6+ wants to use statvfs
+dnl first try including sys/vfs.h
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
-#include <sys/statvfs.h> ]], [[struct statvfs sfs;]])],[AC_MSG_RESULT(in sys/statvfs.h)
- AC_DEFINE(STATFS_IN_SYS_STATVFS, 1,
- [statfs in <sys/statvfs.h> (for solaris 2.6+ systems)])
+#include <sys/vfs.h> ]], [[struct statfs sfs;]])],[AC_MSG_RESULT(in sys/vfs.h)
+ AC_DEFINE(STATFS_IN_SYS_VFS, 1, [statfs in <sys/vfs.h> (for linux systems)])
found_struct_statfs=yes],[])
fi
if test X$found_struct_statfs = Xno ; then
-dnl first try including sys/vfs.h
+dnl Solaris 2.6+ wants to use statvfs
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
-#include <sys/vfs.h> ]], [[struct statfs sfs;]])],[AC_MSG_RESULT(in sys/vfs.h)
- AC_DEFINE(STATFS_IN_SYS_VFS, 1, [statfs in <sys/vfs.h> (for linux systems)])
+#include <sys/statvfs.h> ]], [[struct statvfs sfs;]])],[AC_MSG_RESULT(in sys/statvfs.h)
+ AC_DEFINE(STATFS_IN_SYS_STATVFS, 1,
+ [statfs in <sys/statvfs.h> (for solaris 2.6+ systems)])
found_struct_statfs=yes],[])
fi
--- ./lib/transaction.c.orig 2010-03-25 15:14:38.000000000 +0000
+++ ./lib/transaction.c 2010-03-25 15:44:25.000000000 +0000
@@ -45,6 +45,7 @@
#include "debug.h"
struct diskspaceInfo_s {
+ const 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,78 @@ 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->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;
+ 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(ts->filesystems[i], &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;
+ if (rc)
+ return NULL;
- rc = stat(ts->filesystems[i], &sb);
- if (rc)
- break;
- dsi->dev = sb.st_dev;
+ rc = stat(dirName, &sb);
+ if (rc)
+ return NULL;
+ if (sb.st_dev != dev)
+ return NULL;
- dsi->bsize = sfb.f_bsize;
- dsi->bneeded = 0;
- dsi->ineeded = 0;
+ 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;
+# ifdef ST_RDONLY
+ dsi->bavail = (sfb.f_flag & ST_RDONLY) ? 0 : sfb.f_bavail;
+# else
+ dsi->bavail = sfb.f_bavail;
+# endif
#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]);
- }
- return rc;
+ /* 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;
+ 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 +140,10 @@ static void rpmtsUpdateDSI(const rpmts t
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;
@@ -187,31 +181,58 @@ static void rpmtsUpdateDSI(const rpmts t
dsi->bneeded -= BLOCK_ROUND(fixupSize, dsi->bsize);
}
+static void rpmtsFindDSIMount(const rpmts ts, rpmDiskSpaceInfo dsi)
+{
+ int i;
+ struct stat sb;
+
+ /* must leave chroot for this */
+ if (rpmtsChrootDone(ts)) {
+ chroot(".");
+ }
+ if (!ts->filesystemCount)
+ rpmGetFilesystemList(&ts->filesystems, &ts->filesystemCount);
+ for (i = 0; i < ts->filesystemCount; i++) {
+ if (stat(ts->filesystems[i], &sb))
+ continue;
+ if (sb.st_dev == dsi->dev) {
+ dsi->mntPoint = ts->filesystems[i];
+ break;
+ }
+ }
+ if (i == ts->filesystemCount) {
+ /* file system not found, create something to display */
+ dsi->mntPoint = xmalloc(20);
+ sprintf((char *)dsi->mntPoint, "dev 0x%08x", (unsigned)dsi->dev);
+ }
+ if (rpmtsChrootDone(ts)) {
+ chroot(ts->rootDir);
+ }
+}
+
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) {
+ if (!dsi->mntPoint)
+ rpmtsFindDSIMount(ts, dsi);
rpmpsAppend(ps, RPMPROB_DISKSPACE,
rpmteNEVRA(te), rpmteKey(te),
- ts->filesystems[i], NULL, NULL,
+ dsi->mntPoint, NULL, NULL,
(adj_fs_blocks(dsi->bneeded)) * dsi->bsize);
dsi->obneeded = dsi->bneeded;
}
@@ -219,9 +240,11 @@ static void rpmtsCheckDSIProblems(const
if (dsi->iavail >= 0 && adj_fs_blocks(dsi->ineeded) > dsi->iavail) {
if (dsi->ineeded != dsi->oineeded) {
+ if (!dsi->mntPoint)
+ rpmtsFindDSIMount(ts, dsi);
rpmpsAppend(ps, RPMPROB_DISKNODES,
rpmteNEVRA(te), rpmteKey(te),
- ts->filesystems[i], NULL, NULL,
+ dsi->mntPoint, NULL, NULL,
(adj_fs_blocks(dsi->ineeded)));
dsi->oineeded = dsi->ineeded;
}
@@ -543,7 +566,7 @@ assert(otherFi != NULL);
}
/* Update disk space info for a file. */
- rpmtsUpdateDSI(ts, fiFps->entry->dev, rpmfiFSize(fi),
+ rpmtsUpdateDSI(ts, fiFps->entry->dev, fiFps->entry->dirName, rpmfiFSize(fi),
rpmfiFReplacedSize(fi), fixupSize, rpmfsGetAction(fs, i));
}