Skip to content

Commit

Permalink
Minimally convert transaction diskspace info to STL
Browse files Browse the repository at this point in the history
Use an unordered map keyed by the device number for the storage, might
be an overkill when there typically are just a handful of filesystems
but shrug, that's how we access it.

"Minimally" is in the subject because this leaves all these
non-idiomatic pointer accesses around, but I think it makes the change
clearer because there are a lot of dsi->foo references in the code and
changing them to dsi.foo would just be a lot of churn. Changing mntPoint
into a string is necessary though, otherwise we'd need manual copy-control
and all that.

This also ditches the silly rpmDiskSpaceInfo typedef and the trailing _s
from diskspaceInfo, it's long enough to type as it is and the typedef
breaks const correctness.
  • Loading branch information
pmatilai committed Jun 26, 2024
1 parent 09d90d4 commit 3d2cc9f
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 59 deletions.
3 changes: 0 additions & 3 deletions lib/rpmts.c
Original file line number Diff line number Diff line change
Expand Up @@ -890,8 +890,6 @@ rpmts rpmtsFree(rpmts ts)

delete ts->members;

ts->dsi = _free(ts->dsi);

if (ts->scriptFd != NULL) {
ts->scriptFd = fdFree(ts->scriptFd);
ts->scriptFd = NULL;
Expand Down Expand Up @@ -1248,7 +1246,6 @@ rpmts rpmtsCreate(void)

memset(&ts->ops, 0, sizeof(ts->ops));
(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_TOTAL), -1);
ts->dsi = NULL;

ts->solve = NULL;
ts->solveData = NULL;
Expand Down
11 changes: 6 additions & 5 deletions lib/rpmts_internal.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef _RPMTS_INTERNAL_H
#define _RPMTS_INTERNAL_H

#include <string>
#include <unordered_map>
#include <vector>

#include <rpm/rpmts.h>
Expand All @@ -13,8 +15,8 @@
#include "rpmscript.h"
#include "rpmtriggers.h"

struct diskspaceInfo_s {
char * mntPoint; /*!< File system mount point */
struct diskspaceInfo {
std::string 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. */
Expand All @@ -29,8 +31,6 @@ struct diskspaceInfo_s {
int rotational; /*!< Rotational media? */
};

typedef struct diskspaceInfo_s * rpmDiskSpaceInfo;

/* Transaction set elements information */
typedef struct tsMembers_s {
rpmstrPool pool; /*!< Global string pool */
Expand Down Expand Up @@ -62,7 +62,8 @@ struct rpmts_s {
rpmprobFilterFlags ignoreSet;
/*!< Bits to filter current problems. */

rpmDiskSpaceInfo dsi; /*!< Per filesystem disk/inode usage. */
std::unordered_map<dev_t,diskspaceInfo> dsi;
/*!< Per filesystem disk/inode usage. */

rpmdb rdb; /*!< Install database handle. */
int dbmode; /*!< Install database open mode. */
Expand Down
89 changes: 38 additions & 51 deletions lib/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,19 @@

#include "debug.h"

using std::string;
using std::vector;

/* Adjust for root only reserved space. On linux e2fs, this is 5%. */
#define adj_fs_blocks(_nb) (((_nb) * 21) / 20)
#define BLOCK_ROUND(size, block) (((size) + (block) - 1) / (block))

static char *getMntPoint(const char *dirName, dev_t dev)
static string getMntPoint(const char *dirName, dev_t dev)
{
char *mntPoint = realpath(dirName, NULL);
char *end = NULL;
struct stat sb;
char *res = NULL;
string res;

if (!mntPoint)
mntPoint = xstrdup(dirName);
Expand All @@ -69,29 +70,29 @@ static char *getMntPoint(const char *dirName, dev_t dev)
if (end == mntPoint) { /* reached "/" */
stat("/", &sb);
if (dev != sb.st_dev) {
res = xstrdup(mntPoint);
res = mntPoint;
} else {
res = xstrdup("/");
res = "/";
}
break;
} else if (end) {
*end = '\0';
} else { /* dirName doesn't start with / - should not happen */
res = xstrdup(dirName);
res = dirName;
break;
}
stat(mntPoint, &sb);
if (dev != sb.st_dev) {
*end = '/';
res = xstrdup(mntPoint);
res = mntPoint;
break;
}
}
free(mntPoint);
return res;
}

static int getRotational(const char *dirName, dev_t dev)
static int getRotational(const string dirName, dev_t dev)
{
int rotational = 1; /* Be a good pessimist, assume the worst */
#if defined(__linux__)
Expand All @@ -114,15 +115,13 @@ static int getRotational(const char *dirName, dev_t dev)

static int rpmtsInitDSI(const rpmts ts)
{
ts->dsi = _free(ts->dsi);
ts->dsi = (rpmDiskSpaceInfo)xcalloc(1, sizeof(*ts->dsi));
ts->dsi.clear();
return 0;
}

static rpmDiskSpaceInfo rpmtsCreateDSI(const rpmts ts, dev_t dev,
const char * dirName, int count)
static diskspaceInfo *rpmtsCreateDSI(const rpmts ts, dev_t dev,
const char * dirName)
{
rpmDiskSpaceInfo dsi;
struct stat sb;
int rc;
struct statvfs sfb;
Expand All @@ -138,9 +137,9 @@ static rpmDiskSpaceInfo rpmtsCreateDSI(const rpmts ts, dev_t dev,
if (sb.st_dev != dev)
return NULL;

ts->dsi = xrealloc(ts->dsi, (count + 2) * sizeof(*ts->dsi));
dsi = ts->dsi + count;
memset(dsi, 0, 2 * sizeof(*dsi));
auto entry = ts->dsi.insert({ dev, {}}).first;
diskspaceInfo *dsi = &entry->second;


dsi->dev = sb.st_dev;
dsi->bsize = sfb.f_bsize;
Expand All @@ -166,7 +165,7 @@ static rpmDiskSpaceInfo rpmtsCreateDSI(const rpmts ts, dev_t dev,
uint64_t old_size = dsi->bavail * dsi->bsize;
rpmlog(RPMLOG_DEBUG,
"dubious blocksize % " PRId64 " on %s, normalizing to 4096\n",
dsi->bsize, dsi->mntPoint);
dsi->bsize, dsi->mntPoint.c_str());
dsi->bsize = 4096; /* Assume 4k block size */
dsi->bavail = old_size / dsi->bsize;
}
Expand All @@ -175,37 +174,35 @@ static rpmDiskSpaceInfo rpmtsCreateDSI(const rpmts ts, dev_t dev,
"0x%08x %8" PRId64 " %12" PRId64 " %12" PRId64" rotational:%d %s\n",
(unsigned) dsi->dev, dsi->bsize,
dsi->bavail, dsi->iavail, dsi->rotational,
dsi->mntPoint);
dsi->mntPoint.c_str());
return dsi;
}

static rpmDiskSpaceInfo rpmtsGetDSI(const rpmts ts, dev_t dev,
static diskspaceInfo *rpmtsGetDSI(const rpmts ts, dev_t dev,
const char *dirName) {
rpmDiskSpaceInfo dsi;
dsi = ts->dsi;
if (dsi) {
while (dsi->bsize && dsi->dev != dev)
dsi++;
if (dsi->bsize == 0) {
/* create new entry */
dsi = rpmtsCreateDSI(ts, dev, dirName, dsi - ts->dsi);
}
diskspaceInfo *dsi = NULL;
auto ret = ts->dsi.find(dev);

if (ret != ts->dsi.end()) {
dsi = &ret->second;
} else {
dsi = rpmtsCreateDSI(ts, dev, dirName);
}

return dsi;
}

static int rpmtsGetDSIRotational(rpmts ts)
{
int rc = 1;
int nrot = 0;
rpmDiskSpaceInfo dsi = ts->dsi;
while (dsi && dsi->bsize != 0) {
for (auto & entry : ts->dsi) {
diskspaceInfo *dsi = &entry.second;
if (dsi->rotational < 0)
dsi->rotational = getRotational(dsi->mntPoint, dsi->dev);
nrot += dsi->rotational;
dsi++;
}
if (dsi != ts->dsi && nrot == 0)
if (ts->dsi.empty() == false && nrot == 0)
rc = 0;
return rc;
}
Expand All @@ -215,7 +212,7 @@ static void rpmtsUpdateDSI(const rpmts ts, dev_t dev, const char *dirName,
rpmFileAction action)
{
int64_t bneeded;
rpmDiskSpaceInfo dsi = rpmtsGetDSI(ts, dev, dirName);
diskspaceInfo *dsi = rpmtsGetDSI(ts, dev, dirName);
if (dsi == NULL)
return;

Expand Down Expand Up @@ -259,24 +256,20 @@ static void rpmtsUpdateDSI(const rpmts ts, dev_t dev, const char *dirName,

static void rpmtsCheckDSIProblems(const rpmts ts, const rpmte te)
{
rpmDiskSpaceInfo dsi = ts->dsi;

if (dsi == NULL || !dsi->bsize)
return;

for (; dsi->bsize; dsi++) {
for (auto & entry : ts->dsi) {
diskspaceInfo *dsi = &entry.second;

if (dsi->bavail >= 0 && adj_fs_blocks(dsi->bneeded) > dsi->bavail) {
if (dsi->bneeded > dsi->obneeded) {
rpmteAddProblem(te, RPMPROB_DISKSPACE, NULL, dsi->mntPoint,
rpmteAddProblem(te, RPMPROB_DISKSPACE, NULL, dsi->mntPoint.c_str(),
(adj_fs_blocks(dsi->bneeded) - dsi->bavail) * dsi->bsize);
dsi->obneeded = dsi->bneeded;
}
}

if (dsi->iavail >= 0 && adj_fs_blocks(dsi->ineeded) > dsi->iavail) {
if (dsi->ineeded > dsi->oineeded) {
rpmteAddProblem(te, RPMPROB_DISKNODES, NULL, dsi->mntPoint,
rpmteAddProblem(te, RPMPROB_DISKNODES, NULL, dsi->mntPoint.c_str(),
(adj_fs_blocks(dsi->ineeded) - dsi->iavail));
dsi->oineeded = dsi->ineeded;
}
Expand All @@ -292,16 +285,9 @@ static void rpmtsCheckDSIProblems(const rpmts ts, const rpmte te)

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);
ts->dsi.clear();
}


Expand Down Expand Up @@ -1710,10 +1696,11 @@ static void rpmtsSync(rpmts ts)
return;

#ifdef HAVE_SYNCFS
for (rpmDiskSpaceInfo dsi = ts->dsi; dsi->bsize; dsi++) {
int fd = open(dsi->mntPoint, O_RDONLY);
for (auto & entry : ts->dsi) {
const diskspaceInfo *dsi = &entry.second;
int fd = open(dsi->mntPoint.c_str(), O_RDONLY);
if (fd != -1) {
rpmlog(RPMLOG_DEBUG, "syncing fs %s\n", dsi->mntPoint);
rpmlog(RPMLOG_DEBUG, "syncing fs %s\n", dsi->mntPoint.c_str());
syncfs(fd);
close(fd);
}
Expand Down

0 comments on commit 3d2cc9f

Please sign in to comment.