|
|
23dfb9 |
From 22d18785b2c41f1a8937b712920b4342f7596a7e Mon Sep 17 00:00:00 2001
|
|
|
23dfb9 |
From: Panu Matilainen <pmatilai@redhat.com>
|
|
|
23dfb9 |
Date: Mon, 8 Feb 2021 10:45:59 +0200
|
|
|
23dfb9 |
Subject: [PATCH 1/9] Clean up file unpack iteration logic a bit
|
|
|
23dfb9 |
|
|
|
23dfb9 |
Handle rpmfiNext() in the while-condition directly to make it more like
|
|
|
23dfb9 |
similar other constructs elsewhere, adjust for the end of iteration
|
|
|
23dfb9 |
code after the loop. Also take the file index from rpmfiNext() so
|
|
|
23dfb9 |
we don't need multiple calls to rpmfiFX() later.
|
|
|
23dfb9 |
---
|
|
|
23dfb9 |
lib/fsm.c | 19 +++++++------------
|
|
|
23dfb9 |
1 file changed, 7 insertions(+), 12 deletions(-)
|
|
|
23dfb9 |
|
|
|
23dfb9 |
diff --git a/lib/fsm.c b/lib/fsm.c
|
|
|
23dfb9 |
index 35dcda081c..7c291adb02 100644
|
|
|
23dfb9 |
--- a/lib/fsm.c
|
|
|
23dfb9 |
+++ b/lib/fsm.c
|
|
|
23dfb9 |
@@ -841,6 +841,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
struct stat sb;
|
|
|
23dfb9 |
int saveerrno = errno;
|
|
|
23dfb9 |
int rc = 0;
|
|
|
23dfb9 |
+ int fx = -1;
|
|
|
23dfb9 |
int nodigest = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOFILEDIGEST) ? 1 : 0;
|
|
|
23dfb9 |
int nofcaps = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCAPS) ? 1 : 0;
|
|
|
23dfb9 |
int firsthardlink = -1;
|
|
|
23dfb9 |
@@ -862,17 +863,8 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
/* Detect and create directories not explicitly in package. */
|
|
|
23dfb9 |
rc = fsmMkdirs(files, fs, plugins);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- while (!rc) {
|
|
|
23dfb9 |
- /* Read next payload header. */
|
|
|
23dfb9 |
- rc = rpmfiNext(fi);
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
- if (rc < 0) {
|
|
|
23dfb9 |
- if (rc == RPMERR_ITER_END)
|
|
|
23dfb9 |
- rc = 0;
|
|
|
23dfb9 |
- break;
|
|
|
23dfb9 |
- }
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
- action = rpmfsGetAction(fs, rpmfiFX(fi));
|
|
|
23dfb9 |
+ while (!rc && (fx = rpmfiNext(fi)) >= 0) {
|
|
|
23dfb9 |
+ action = rpmfsGetAction(fs, fx);
|
|
|
23dfb9 |
skip = XFA_SKIPPING(action);
|
|
|
23dfb9 |
if (action != FA_TOUCH) {
|
|
|
23dfb9 |
suffix = S_ISDIR(rpmfiFMode(fi)) ? NULL : tid;
|
|
|
23dfb9 |
@@ -896,7 +888,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
if (rc) {
|
|
|
23dfb9 |
skip = 1;
|
|
|
23dfb9 |
} else {
|
|
|
23dfb9 |
- setFileState(fs, rpmfiFX(fi));
|
|
|
23dfb9 |
+ setFileState(fs, fx);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (!skip) {
|
|
|
23dfb9 |
@@ -1005,6 +997,9 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
fpath = _free(fpath);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
+ if (!rc && fx != RPMERR_ITER_END)
|
|
|
23dfb9 |
+ rc = fx;
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
rpmswAdd(rpmtsOp(ts, RPMTS_OP_UNCOMPRESS), fdOp(payload, FDSTAT_READ));
|
|
|
23dfb9 |
rpmswAdd(rpmtsOp(ts, RPMTS_OP_DIGEST), fdOp(payload, FDSTAT_DIGEST));
|
|
|
23dfb9 |
|
|
|
23dfb9 |
|
|
|
23dfb9 |
From c0dc57b820791dd76ce8baafac59b9a58ab0f0d3 Mon Sep 17 00:00:00 2001
|
|
|
23dfb9 |
From: Panu Matilainen <pmatilai@redhat.com>
|
|
|
23dfb9 |
Date: Wed, 10 Feb 2021 08:25:28 +0200
|
|
|
23dfb9 |
Subject: [PATCH 2/9] Drop unused filename variable
|
|
|
23dfb9 |
|
|
|
23dfb9 |
---
|
|
|
23dfb9 |
lib/fsm.c | 2 --
|
|
|
23dfb9 |
1 file changed, 2 deletions(-)
|
|
|
23dfb9 |
|
|
|
23dfb9 |
diff --git a/lib/fsm.c b/lib/fsm.c
|
|
|
23dfb9 |
index 7c291adb02..41b6267ddc 100644
|
|
|
23dfb9 |
--- a/lib/fsm.c
|
|
|
23dfb9 |
+++ b/lib/fsm.c
|
|
|
23dfb9 |
@@ -959,11 +959,9 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
/* On FA_TOUCH no hardlinks are created thus this is skipped. */
|
|
|
23dfb9 |
/* we skip the hard linked file containing the content */
|
|
|
23dfb9 |
/* write the content to the first used instead */
|
|
|
23dfb9 |
- char *fn = rpmfilesFN(files, firsthardlink);
|
|
|
23dfb9 |
rc = rpmfiArchiveReadToFilePsm(fi, firstlinkfile, nodigest, psm);
|
|
|
23dfb9 |
wfd_close(&firstlinkfile);
|
|
|
23dfb9 |
firsthardlink = -1;
|
|
|
23dfb9 |
- free(fn);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (rc) {
|
|
|
23dfb9 |
|
|
|
23dfb9 |
From dcb5791066afd5caa1003a5d35903a7f5dc79cc2 Mon Sep 17 00:00:00 2001
|
|
|
23dfb9 |
From: Panu Matilainen <pmatilai@redhat.com>
|
|
|
23dfb9 |
Date: Wed, 10 Feb 2021 09:57:17 +0200
|
|
|
23dfb9 |
Subject: [PATCH 3/9] Don't update path info if rename failed on file commit
|
|
|
23dfb9 |
|
|
|
23dfb9 |
---
|
|
|
23dfb9 |
lib/fsm.c | 16 +++++++++-------
|
|
|
23dfb9 |
1 file changed, 9 insertions(+), 7 deletions(-)
|
|
|
23dfb9 |
|
|
|
23dfb9 |
diff --git a/lib/fsm.c b/lib/fsm.c
|
|
|
23dfb9 |
index 41b6267ddc..c581a918a5 100644
|
|
|
23dfb9 |
--- a/lib/fsm.c
|
|
|
23dfb9 |
+++ b/lib/fsm.c
|
|
|
23dfb9 |
@@ -773,14 +773,16 @@ static int fsmCommit(char **path, rpmfi fi, rpmFileAction action, const char *su
|
|
|
23dfb9 |
/* Rename temporary to final file name if needed. */
|
|
|
23dfb9 |
if (dest != *path) {
|
|
|
23dfb9 |
rc = fsmRename(*path, dest);
|
|
|
23dfb9 |
- if (!rc && nsuffix) {
|
|
|
23dfb9 |
- char * opath = fsmFsPath(fi, NULL);
|
|
|
23dfb9 |
- rpmlog(RPMLOG_WARNING, _("%s created as %s\n"),
|
|
|
23dfb9 |
- opath, dest);
|
|
|
23dfb9 |
- free(opath);
|
|
|
23dfb9 |
+ if (!rc) {
|
|
|
23dfb9 |
+ if (nsuffix) {
|
|
|
23dfb9 |
+ char * opath = fsmFsPath(fi, NULL);
|
|
|
23dfb9 |
+ rpmlog(RPMLOG_WARNING, _("%s created as %s\n"),
|
|
|
23dfb9 |
+ opath, dest);
|
|
|
23dfb9 |
+ free(opath);
|
|
|
23dfb9 |
+ }
|
|
|
23dfb9 |
+ free(*path);
|
|
|
23dfb9 |
+ *path = dest;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
- free(*path);
|
|
|
23dfb9 |
- *path = dest;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
|
|
|
23dfb9 |
From 7fdf248e7d29a244b97c46b19be0df64992fdfae Mon Sep 17 00:00:00 2001
|
|
|
23dfb9 |
From: Panu Matilainen <pmatilai@redhat.com>
|
|
|
23dfb9 |
Date: Wed, 10 Feb 2021 09:47:19 +0200
|
|
|
23dfb9 |
Subject: [PATCH 4/9] Refactor file install and remove around a common struct
|
|
|
23dfb9 |
|
|
|
23dfb9 |
Collect the common state info into a struct shared by both file install
|
|
|
23dfb9 |
and remove, update code accordingly. The change looks much more drastic
|
|
|
23dfb9 |
than it is - it's just adding fp-> prefix to a lot of places.
|
|
|
23dfb9 |
While we're at it, remember the state data throughout the operation.
|
|
|
23dfb9 |
|
|
|
23dfb9 |
No functional changes here, just paving way for the next steps which
|
|
|
23dfb9 |
will look clearer with these pre-requisites in place.
|
|
|
23dfb9 |
---
|
|
|
23dfb9 |
lib/fsm.c | 158 +++++++++++++++++++++++++++++-------------------------
|
|
|
23dfb9 |
1 file changed, 85 insertions(+), 73 deletions(-)
|
|
|
23dfb9 |
|
|
|
23dfb9 |
diff --git a/lib/fsm.c b/lib/fsm.c
|
|
|
23dfb9 |
index c581a918a5..9dba30560f 100644
|
|
|
23dfb9 |
--- a/lib/fsm.c
|
|
|
23dfb9 |
+++ b/lib/fsm.c
|
|
|
23dfb9 |
@@ -38,6 +38,14 @@ static int strict_erasures = 0;
|
|
|
23dfb9 |
#define _dirPerms 0755
|
|
|
23dfb9 |
#define _filePerms 0644
|
|
|
23dfb9 |
|
|
|
23dfb9 |
+struct filedata_s {
|
|
|
23dfb9 |
+ int skip;
|
|
|
23dfb9 |
+ rpmFileAction action;
|
|
|
23dfb9 |
+ const char *suffix;
|
|
|
23dfb9 |
+ char *fpath;
|
|
|
23dfb9 |
+ struct stat sb;
|
|
|
23dfb9 |
+};
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
/*
|
|
|
23dfb9 |
* XXX Forward declarations for previously exported functions to avoid moving
|
|
|
23dfb9 |
* things around needlessly
|
|
|
23dfb9 |
@@ -840,19 +848,16 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
rpmfi fi = rpmfiNewArchiveReader(payload, files, RPMFI_ITER_READ_ARCHIVE);
|
|
|
23dfb9 |
rpmfs fs = rpmteGetFileStates(te);
|
|
|
23dfb9 |
rpmPlugins plugins = rpmtsPlugins(ts);
|
|
|
23dfb9 |
- struct stat sb;
|
|
|
23dfb9 |
int saveerrno = errno;
|
|
|
23dfb9 |
int rc = 0;
|
|
|
23dfb9 |
int fx = -1;
|
|
|
23dfb9 |
+ int fc = rpmfilesFC(files);
|
|
|
23dfb9 |
int nodigest = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOFILEDIGEST) ? 1 : 0;
|
|
|
23dfb9 |
int nofcaps = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCAPS) ? 1 : 0;
|
|
|
23dfb9 |
int firsthardlink = -1;
|
|
|
23dfb9 |
FD_t firstlinkfile = NULL;
|
|
|
23dfb9 |
- int skip;
|
|
|
23dfb9 |
- rpmFileAction action;
|
|
|
23dfb9 |
char *tid = NULL;
|
|
|
23dfb9 |
- const char *suffix;
|
|
|
23dfb9 |
- char *fpath = NULL;
|
|
|
23dfb9 |
+ struct filedata_s *fdata = xcalloc(fc, sizeof(*fdata));
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (fi == NULL) {
|
|
|
23dfb9 |
rc = RPMERR_BAD_MAGIC;
|
|
|
23dfb9 |
@@ -866,96 +871,99 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
rc = fsmMkdirs(files, fs, plugins);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
while (!rc && (fx = rpmfiNext(fi)) >= 0) {
|
|
|
23dfb9 |
- action = rpmfsGetAction(fs, fx);
|
|
|
23dfb9 |
- skip = XFA_SKIPPING(action);
|
|
|
23dfb9 |
- if (action != FA_TOUCH) {
|
|
|
23dfb9 |
- suffix = S_ISDIR(rpmfiFMode(fi)) ? NULL : tid;
|
|
|
23dfb9 |
+ struct filedata_s *fp = &fdata[fx];
|
|
|
23dfb9 |
+ fp->action = rpmfsGetAction(fs, fx);
|
|
|
23dfb9 |
+ fp->skip = XFA_SKIPPING(fp->action);
|
|
|
23dfb9 |
+ if (fp->action != FA_TOUCH) {
|
|
|
23dfb9 |
+ fp->suffix = S_ISDIR(rpmfiFMode(fi)) ? NULL : tid;
|
|
|
23dfb9 |
} else {
|
|
|
23dfb9 |
- suffix = NULL;
|
|
|
23dfb9 |
+ fp->suffix = NULL;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
- fpath = fsmFsPath(fi, suffix);
|
|
|
23dfb9 |
+ fp->fpath = fsmFsPath(fi, fp->suffix);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* Remap file perms, owner, and group. */
|
|
|
23dfb9 |
- rc = rpmfiStat(fi, 1, &sb);
|
|
|
23dfb9 |
+ rc = rpmfiStat(fi, 1, &fp->sb);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- fsmDebug(fpath, action, &sb);
|
|
|
23dfb9 |
+ fsmDebug(fp->fpath, fp->action, &fp->sb);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* Exit on error. */
|
|
|
23dfb9 |
if (rc)
|
|
|
23dfb9 |
break;
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* Run fsm file pre hook for all plugins */
|
|
|
23dfb9 |
- rc = rpmpluginsCallFsmFilePre(plugins, fi, fpath,
|
|
|
23dfb9 |
- sb.st_mode, action);
|
|
|
23dfb9 |
+ rc = rpmpluginsCallFsmFilePre(plugins, fi, fp->fpath,
|
|
|
23dfb9 |
+ fp->sb.st_mode, fp->action);
|
|
|
23dfb9 |
if (rc) {
|
|
|
23dfb9 |
- skip = 1;
|
|
|
23dfb9 |
+ fp->skip = 1;
|
|
|
23dfb9 |
} else {
|
|
|
23dfb9 |
setFileState(fs, fx);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- if (!skip) {
|
|
|
23dfb9 |
+ if (!fp->skip) {
|
|
|
23dfb9 |
int setmeta = 1;
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* Directories replacing something need early backup */
|
|
|
23dfb9 |
- if (!suffix) {
|
|
|
23dfb9 |
- rc = fsmBackup(fi, action);
|
|
|
23dfb9 |
+ if (!fp->suffix) {
|
|
|
23dfb9 |
+ rc = fsmBackup(fi, fp->action);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
/* Assume file does't exist when tmp suffix is in use */
|
|
|
23dfb9 |
- if (!suffix) {
|
|
|
23dfb9 |
- rc = fsmVerify(fpath, fi);
|
|
|
23dfb9 |
+ if (!fp->suffix) {
|
|
|
23dfb9 |
+ rc = fsmVerify(fp->fpath, fi);
|
|
|
23dfb9 |
} else {
|
|
|
23dfb9 |
rc = RPMERR_ENOENT;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* See if the file was removed while our attention was elsewhere */
|
|
|
23dfb9 |
- if (rc == RPMERR_ENOENT && action == FA_TOUCH) {
|
|
|
23dfb9 |
- rpmlog(RPMLOG_DEBUG, "file %s vanished unexpectedly\n", fpath);
|
|
|
23dfb9 |
- action = FA_CREATE;
|
|
|
23dfb9 |
- fsmDebug(fpath, action, &sb);
|
|
|
23dfb9 |
+ if (rc == RPMERR_ENOENT && fp->action == FA_TOUCH) {
|
|
|
23dfb9 |
+ rpmlog(RPMLOG_DEBUG, "file %s vanished unexpectedly\n",
|
|
|
23dfb9 |
+ fp->fpath);
|
|
|
23dfb9 |
+ fp->action = FA_CREATE;
|
|
|
23dfb9 |
+ fsmDebug(fp->fpath, fp->action, &fp->sb);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* When touching we don't need any of this... */
|
|
|
23dfb9 |
- if (action == FA_TOUCH)
|
|
|
23dfb9 |
+ if (fp->action == FA_TOUCH)
|
|
|
23dfb9 |
goto touch;
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- if (S_ISREG(sb.st_mode)) {
|
|
|
23dfb9 |
+ if (S_ISREG(fp->sb.st_mode)) {
|
|
|
23dfb9 |
if (rc == RPMERR_ENOENT) {
|
|
|
23dfb9 |
- rc = fsmMkfile(fi, fpath, files, psm, nodigest,
|
|
|
23dfb9 |
+ rc = fsmMkfile(fi, fp->fpath, files, psm, nodigest,
|
|
|
23dfb9 |
&setmeta, &firsthardlink, &firstlinkfile);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
- } else if (S_ISDIR(sb.st_mode)) {
|
|
|
23dfb9 |
+ } else if (S_ISDIR(fp->sb.st_mode)) {
|
|
|
23dfb9 |
if (rc == RPMERR_ENOENT) {
|
|
|
23dfb9 |
- mode_t mode = sb.st_mode;
|
|
|
23dfb9 |
+ mode_t mode = fp->sb.st_mode;
|
|
|
23dfb9 |
mode &= ~07777;
|
|
|
23dfb9 |
mode |= 00700;
|
|
|
23dfb9 |
- rc = fsmMkdir(fpath, mode);
|
|
|
23dfb9 |
+ rc = fsmMkdir(fp->fpath, mode);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
- } else if (S_ISLNK(sb.st_mode)) {
|
|
|
23dfb9 |
+ } else if (S_ISLNK(fp->sb.st_mode)) {
|
|
|
23dfb9 |
if (rc == RPMERR_ENOENT) {
|
|
|
23dfb9 |
- rc = fsmSymlink(rpmfiFLink(fi), fpath);
|
|
|
23dfb9 |
+ rc = fsmSymlink(rpmfiFLink(fi), fp->fpath);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
- } else if (S_ISFIFO(sb.st_mode)) {
|
|
|
23dfb9 |
+ } else if (S_ISFIFO(fp->sb.st_mode)) {
|
|
|
23dfb9 |
/* This mimics cpio S_ISSOCK() behavior but probably isn't right */
|
|
|
23dfb9 |
if (rc == RPMERR_ENOENT) {
|
|
|
23dfb9 |
- rc = fsmMkfifo(fpath, 0000);
|
|
|
23dfb9 |
+ rc = fsmMkfifo(fp->fpath, 0000);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
- } else if (S_ISCHR(sb.st_mode) ||
|
|
|
23dfb9 |
- S_ISBLK(sb.st_mode) ||
|
|
|
23dfb9 |
- S_ISSOCK(sb.st_mode))
|
|
|
23dfb9 |
+ } else if (S_ISCHR(fp->sb.st_mode) ||
|
|
|
23dfb9 |
+ S_ISBLK(fp->sb.st_mode) ||
|
|
|
23dfb9 |
+ S_ISSOCK(fp->sb.st_mode))
|
|
|
23dfb9 |
{
|
|
|
23dfb9 |
if (rc == RPMERR_ENOENT) {
|
|
|
23dfb9 |
- rc = fsmMknod(fpath, sb.st_mode, sb.st_rdev);
|
|
|
23dfb9 |
+ rc = fsmMknod(fp->fpath, fp->sb.st_mode, fp->sb.st_rdev);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
} else {
|
|
|
23dfb9 |
/* XXX Special case /dev/log, which shouldn't be packaged anyways */
|
|
|
23dfb9 |
- if (!IS_DEV_LOG(fpath))
|
|
|
23dfb9 |
+ if (!IS_DEV_LOG(fp->fpath))
|
|
|
23dfb9 |
rc = RPMERR_UNKNOWN_FILETYPE;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
touch:
|
|
|
23dfb9 |
/* Set permissions, timestamps etc for non-hardlink entries */
|
|
|
23dfb9 |
if (!rc && setmeta) {
|
|
|
23dfb9 |
- rc = fsmSetmeta(fpath, fi, plugins, action, &sb, nofcaps);
|
|
|
23dfb9 |
+ rc = fsmSetmeta(fp->fpath, fi, plugins, fp->action,
|
|
|
23dfb9 |
+ &fp->sb, nofcaps);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
} else if (firsthardlink >= 0 && rpmfiArchiveHasContent(fi)) {
|
|
|
23dfb9 |
/* On FA_TOUCH no hardlinks are created thus this is skipped. */
|
|
|
23dfb9 |
@@ -967,10 +975,10 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (rc) {
|
|
|
23dfb9 |
- if (!skip) {
|
|
|
23dfb9 |
+ if (!fp->skip) {
|
|
|
23dfb9 |
/* XXX only erase if temp fn w suffix is in use */
|
|
|
23dfb9 |
- if (suffix) {
|
|
|
23dfb9 |
- (void) fsmRemove(fpath, sb.st_mode);
|
|
|
23dfb9 |
+ if (fp->suffix) {
|
|
|
23dfb9 |
+ (void) fsmRemove(fp->fpath, fp->sb.st_mode);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
errno = saveerrno;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
@@ -978,23 +986,22 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
/* Notify on success. */
|
|
|
23dfb9 |
rpmpsmNotify(psm, RPMCALLBACK_INST_PROGRESS, rpmfiArchiveTell(fi));
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- if (!skip) {
|
|
|
23dfb9 |
+ if (!fp->skip) {
|
|
|
23dfb9 |
/* Backup file if needed. Directories are handled earlier */
|
|
|
23dfb9 |
- if (suffix)
|
|
|
23dfb9 |
- rc = fsmBackup(fi, action);
|
|
|
23dfb9 |
+ if (fp->suffix)
|
|
|
23dfb9 |
+ rc = fsmBackup(fi, fp->action);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (!rc)
|
|
|
23dfb9 |
- rc = fsmCommit(&fpath, fi, action, suffix);
|
|
|
23dfb9 |
+ rc = fsmCommit(&fp->fpath, fi, fp->action, fp->suffix);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (rc)
|
|
|
23dfb9 |
- *failedFile = xstrdup(fpath);
|
|
|
23dfb9 |
+ *failedFile = xstrdup(fp->fpath);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* Run fsm file post hook for all plugins */
|
|
|
23dfb9 |
- rpmpluginsCallFsmFilePost(plugins, fi, fpath,
|
|
|
23dfb9 |
- sb.st_mode, action, rc);
|
|
|
23dfb9 |
- fpath = _free(fpath);
|
|
|
23dfb9 |
+ rpmpluginsCallFsmFilePost(plugins, fi, fp->fpath,
|
|
|
23dfb9 |
+ fp->sb.st_mode, fp->action, rc);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (!rc && fx != RPMERR_ITER_END)
|
|
|
23dfb9 |
@@ -1010,7 +1017,9 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
rpmfiFree(fi);
|
|
|
23dfb9 |
Fclose(payload);
|
|
|
23dfb9 |
free(tid);
|
|
|
23dfb9 |
- free(fpath);
|
|
|
23dfb9 |
+ for (int i = 0; i < fc; i++)
|
|
|
23dfb9 |
+ free(fdata[i].fpath);
|
|
|
23dfb9 |
+ free(fdata);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
return rc;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
@@ -1022,29 +1031,31 @@ int rpmPackageFilesRemove(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
rpmfi fi = rpmfilesIter(files, RPMFI_ITER_BACK);
|
|
|
23dfb9 |
rpmfs fs = rpmteGetFileStates(te);
|
|
|
23dfb9 |
rpmPlugins plugins = rpmtsPlugins(ts);
|
|
|
23dfb9 |
- struct stat sb;
|
|
|
23dfb9 |
+ int fc = rpmfilesFC(files);
|
|
|
23dfb9 |
+ int fx = -1;
|
|
|
23dfb9 |
+ struct filedata_s *fdata = xcalloc(fc, sizeof(*fdata));
|
|
|
23dfb9 |
int rc = 0;
|
|
|
23dfb9 |
- char *fpath = NULL;
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- while (!rc && rpmfiNext(fi) >= 0) {
|
|
|
23dfb9 |
- rpmFileAction action = rpmfsGetAction(fs, rpmfiFX(fi));
|
|
|
23dfb9 |
- fpath = fsmFsPath(fi, NULL);
|
|
|
23dfb9 |
- rc = fsmStat(fpath, 1, &sb);
|
|
|
23dfb9 |
+ while (!rc && (fx = rpmfiNext(fi)) >= 0) {
|
|
|
23dfb9 |
+ struct filedata_s *fp = &fdata[fx];
|
|
|
23dfb9 |
+ fp->action = rpmfsGetAction(fs, rpmfiFX(fi));
|
|
|
23dfb9 |
+ fp->fpath = fsmFsPath(fi, NULL);
|
|
|
23dfb9 |
+ rc = fsmStat(fp->fpath, 1, &fp->sb);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- fsmDebug(fpath, action, &sb);
|
|
|
23dfb9 |
+ fsmDebug(fp->fpath, fp->action, &fp->sb);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* Run fsm file pre hook for all plugins */
|
|
|
23dfb9 |
- rc = rpmpluginsCallFsmFilePre(plugins, fi, fpath,
|
|
|
23dfb9 |
- sb.st_mode, action);
|
|
|
23dfb9 |
+ rc = rpmpluginsCallFsmFilePre(plugins, fi, fp->fpath,
|
|
|
23dfb9 |
+ fp->sb.st_mode, fp->action);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- if (!XFA_SKIPPING(action))
|
|
|
23dfb9 |
- rc = fsmBackup(fi, action);
|
|
|
23dfb9 |
+ if (!XFA_SKIPPING(fp->action))
|
|
|
23dfb9 |
+ rc = fsmBackup(fi, fp->action);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* Remove erased files. */
|
|
|
23dfb9 |
- if (action == FA_ERASE) {
|
|
|
23dfb9 |
+ if (fp->action == FA_ERASE) {
|
|
|
23dfb9 |
int missingok = (rpmfiFFlags(fi) & (RPMFILE_MISSINGOK | RPMFILE_GHOST));
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- rc = fsmRemove(fpath, sb.st_mode);
|
|
|
23dfb9 |
+ rc = fsmRemove(fp->fpath, fp->sb.st_mode);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/*
|
|
|
23dfb9 |
* Missing %ghost or %missingok entries are not errors.
|
|
|
23dfb9 |
@@ -1069,20 +1080,20 @@ int rpmPackageFilesRemove(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
if (rc) {
|
|
|
23dfb9 |
int lvl = strict_erasures ? RPMLOG_ERR : RPMLOG_WARNING;
|
|
|
23dfb9 |
rpmlog(lvl, _("%s %s: remove failed: %s\n"),
|
|
|
23dfb9 |
- S_ISDIR(sb.st_mode) ? _("directory") : _("file"),
|
|
|
23dfb9 |
- fpath, strerror(errno));
|
|
|
23dfb9 |
+ S_ISDIR(fp->sb.st_mode) ? _("directory") : _("file"),
|
|
|
23dfb9 |
+ fp->fpath, strerror(errno));
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* Run fsm file post hook for all plugins */
|
|
|
23dfb9 |
- rpmpluginsCallFsmFilePost(plugins, fi, fpath,
|
|
|
23dfb9 |
- sb.st_mode, action, rc);
|
|
|
23dfb9 |
+ rpmpluginsCallFsmFilePost(plugins, fi, fp->fpath,
|
|
|
23dfb9 |
+ fp->sb.st_mode, fp->action, rc);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* XXX Failure to remove is not (yet) cause for failure. */
|
|
|
23dfb9 |
if (!strict_erasures) rc = 0;
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (rc)
|
|
|
23dfb9 |
- *failedFile = xstrdup(fpath);
|
|
|
23dfb9 |
+ *failedFile = xstrdup(fp->fpath);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (rc == 0) {
|
|
|
23dfb9 |
/* Notify on success. */
|
|
|
23dfb9 |
@@ -1090,10 +1101,11 @@ int rpmPackageFilesRemove(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
rpm_loff_t amount = rpmfiFC(fi) - rpmfiFX(fi);
|
|
|
23dfb9 |
rpmpsmNotify(psm, RPMCALLBACK_UNINST_PROGRESS, amount);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
- fpath = _free(fpath);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- free(fpath);
|
|
|
23dfb9 |
+ for (int i = 0; i < fc; i++)
|
|
|
23dfb9 |
+ free(fdata[i].fpath);
|
|
|
23dfb9 |
+ free(fdata);
|
|
|
23dfb9 |
rpmfiFree(fi);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
return rc;
|
|
|
23dfb9 |
|
|
|
23dfb9 |
From 202c9e9cd2e199b7e7c9655704a98ab2d4fad69c Mon Sep 17 00:00:00 2001
|
|
|
23dfb9 |
From: Panu Matilainen <pmatilai@redhat.com>
|
|
|
23dfb9 |
Date: Wed, 10 Feb 2021 10:08:27 +0200
|
|
|
23dfb9 |
Subject: [PATCH 5/9] Refactor fsmMkfile() to take advantage of the new state
|
|
|
23dfb9 |
struct
|
|
|
23dfb9 |
|
|
|
23dfb9 |
Move setmeta into the struct too (we'll want this later anyhow),
|
|
|
23dfb9 |
and now we only need to pass the struct to fsmMkfile(). One less
|
|
|
23dfb9 |
argument to pass around, it has way too many still.
|
|
|
23dfb9 |
|
|
|
23dfb9 |
No functional changes.
|
|
|
23dfb9 |
---
|
|
|
23dfb9 |
lib/fsm.c | 22 +++++++++++-----------
|
|
|
23dfb9 |
1 file changed, 11 insertions(+), 11 deletions(-)
|
|
|
23dfb9 |
|
|
|
23dfb9 |
diff --git a/lib/fsm.c b/lib/fsm.c
|
|
|
23dfb9 |
index 9dba30560f..80ca234b1e 100644
|
|
|
23dfb9 |
--- a/lib/fsm.c
|
|
|
23dfb9 |
+++ b/lib/fsm.c
|
|
|
23dfb9 |
@@ -39,6 +39,7 @@ static int strict_erasures = 0;
|
|
|
23dfb9 |
#define _filePerms 0644
|
|
|
23dfb9 |
|
|
|
23dfb9 |
struct filedata_s {
|
|
|
23dfb9 |
+ int setmeta;
|
|
|
23dfb9 |
int skip;
|
|
|
23dfb9 |
rpmFileAction action;
|
|
|
23dfb9 |
const char *suffix;
|
|
|
23dfb9 |
@@ -279,8 +280,8 @@ static int expandRegular(rpmfi fi, const char *dest, rpmpsm psm, int nodigest)
|
|
|
23dfb9 |
return rc;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
-static int fsmMkfile(rpmfi fi, const char *dest, rpmfiles files,
|
|
|
23dfb9 |
- rpmpsm psm, int nodigest, int *setmeta,
|
|
|
23dfb9 |
+static int fsmMkfile(rpmfi fi, struct filedata_s *fp, rpmfiles files,
|
|
|
23dfb9 |
+ rpmpsm psm, int nodigest,
|
|
|
23dfb9 |
int * firsthardlink, FD_t *firstlinkfile)
|
|
|
23dfb9 |
{
|
|
|
23dfb9 |
int rc = 0;
|
|
|
23dfb9 |
@@ -290,11 +291,11 @@ static int fsmMkfile(rpmfi fi, const char *dest, rpmfiles files,
|
|
|
23dfb9 |
/* Create first hardlinked file empty */
|
|
|
23dfb9 |
if (*firsthardlink < 0) {
|
|
|
23dfb9 |
*firsthardlink = rpmfiFX(fi);
|
|
|
23dfb9 |
- rc = wfd_open(firstlinkfile, dest);
|
|
|
23dfb9 |
+ rc = wfd_open(firstlinkfile, fp->fpath);
|
|
|
23dfb9 |
} else {
|
|
|
23dfb9 |
/* Create hard links for others */
|
|
|
23dfb9 |
char *fn = rpmfilesFN(files, *firsthardlink);
|
|
|
23dfb9 |
- rc = link(fn, dest);
|
|
|
23dfb9 |
+ rc = link(fn, fp->fpath);
|
|
|
23dfb9 |
if (rc < 0) {
|
|
|
23dfb9 |
rc = RPMERR_LINK_FAILED;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
@@ -305,14 +306,14 @@ static int fsmMkfile(rpmfi fi, const char *dest, rpmfiles files,
|
|
|
23dfb9 |
existing) file with content */
|
|
|
23dfb9 |
if (numHardlinks<=1) {
|
|
|
23dfb9 |
if (!rc)
|
|
|
23dfb9 |
- rc = expandRegular(fi, dest, psm, nodigest);
|
|
|
23dfb9 |
+ rc = expandRegular(fi, fp->fpath, psm, nodigest);
|
|
|
23dfb9 |
} else if (rpmfiArchiveHasContent(fi)) {
|
|
|
23dfb9 |
if (!rc)
|
|
|
23dfb9 |
rc = rpmfiArchiveReadToFilePsm(fi, *firstlinkfile, nodigest, psm);
|
|
|
23dfb9 |
wfd_close(firstlinkfile);
|
|
|
23dfb9 |
*firsthardlink = -1;
|
|
|
23dfb9 |
} else {
|
|
|
23dfb9 |
- *setmeta = 0;
|
|
|
23dfb9 |
+ fp->setmeta = 0;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
return rc;
|
|
|
23dfb9 |
@@ -874,6 +875,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
struct filedata_s *fp = &fdata[fx];
|
|
|
23dfb9 |
fp->action = rpmfsGetAction(fs, fx);
|
|
|
23dfb9 |
fp->skip = XFA_SKIPPING(fp->action);
|
|
|
23dfb9 |
+ fp->setmeta = 1;
|
|
|
23dfb9 |
if (fp->action != FA_TOUCH) {
|
|
|
23dfb9 |
fp->suffix = S_ISDIR(rpmfiFMode(fi)) ? NULL : tid;
|
|
|
23dfb9 |
} else {
|
|
|
23dfb9 |
@@ -900,8 +902,6 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (!fp->skip) {
|
|
|
23dfb9 |
- int setmeta = 1;
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
/* Directories replacing something need early backup */
|
|
|
23dfb9 |
if (!fp->suffix) {
|
|
|
23dfb9 |
rc = fsmBackup(fi, fp->action);
|
|
|
23dfb9 |
@@ -927,8 +927,8 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (S_ISREG(fp->sb.st_mode)) {
|
|
|
23dfb9 |
if (rc == RPMERR_ENOENT) {
|
|
|
23dfb9 |
- rc = fsmMkfile(fi, fp->fpath, files, psm, nodigest,
|
|
|
23dfb9 |
- &setmeta, &firsthardlink, &firstlinkfile);
|
|
|
23dfb9 |
+ rc = fsmMkfile(fi, fp, files, psm, nodigest,
|
|
|
23dfb9 |
+ &firsthardlink, &firstlinkfile);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
} else if (S_ISDIR(fp->sb.st_mode)) {
|
|
|
23dfb9 |
if (rc == RPMERR_ENOENT) {
|
|
|
23dfb9 |
@@ -961,7 +961,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
|
|
|
23dfb9 |
touch:
|
|
|
23dfb9 |
/* Set permissions, timestamps etc for non-hardlink entries */
|
|
|
23dfb9 |
- if (!rc && setmeta) {
|
|
|
23dfb9 |
+ if (!rc && fp->setmeta) {
|
|
|
23dfb9 |
rc = fsmSetmeta(fp->fpath, fi, plugins, fp->action,
|
|
|
23dfb9 |
&fp->sb, nofcaps);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
From f014fc46325efe92b79841145f8dc0cb40896c64 Mon Sep 17 00:00:00 2001
|
|
|
23dfb9 |
From: Panu Matilainen <pmatilai@redhat.com>
|
|
|
23dfb9 |
Date: Wed, 10 Feb 2021 10:24:22 +0200
|
|
|
23dfb9 |
Subject: [PATCH 6/9] Clarify file installation temporary suffix rule
|
|
|
23dfb9 |
|
|
|
23dfb9 |
We only use a temporary suffix for regular files that we are actually
|
|
|
23dfb9 |
creating, skipped and touched files should not have it. Add XFA_CREATING()
|
|
|
23dfb9 |
macro to accomppany XFA_SKIPPING() to easily check whether the file
|
|
|
23dfb9 |
is being created or something else.
|
|
|
23dfb9 |
|
|
|
23dfb9 |
No functional changes but makes the logic clearer.
|
|
|
23dfb9 |
---
|
|
|
23dfb9 |
lib/fsm.c | 5 +----
|
|
|
23dfb9 |
lib/rpmfiles.h | 3 +++
|
|
|
23dfb9 |
2 files changed, 4 insertions(+), 4 deletions(-)
|
|
|
23dfb9 |
|
|
|
23dfb9 |
diff --git a/lib/fsm.c b/lib/fsm.c
|
|
|
23dfb9 |
index 80ca234b1e..554ea712f5 100644
|
|
|
23dfb9 |
--- a/lib/fsm.c
|
|
|
23dfb9 |
+++ b/lib/fsm.c
|
|
|
23dfb9 |
@@ -876,11 +876,8 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
fp->action = rpmfsGetAction(fs, fx);
|
|
|
23dfb9 |
fp->skip = XFA_SKIPPING(fp->action);
|
|
|
23dfb9 |
fp->setmeta = 1;
|
|
|
23dfb9 |
- if (fp->action != FA_TOUCH) {
|
|
|
23dfb9 |
+ if (XFA_CREATING(fp->action))
|
|
|
23dfb9 |
fp->suffix = S_ISDIR(rpmfiFMode(fi)) ? NULL : tid;
|
|
|
23dfb9 |
- } else {
|
|
|
23dfb9 |
- fp->suffix = NULL;
|
|
|
23dfb9 |
- }
|
|
|
23dfb9 |
fp->fpath = fsmFsPath(fi, fp->suffix);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* Remap file perms, owner, and group. */
|
|
|
23dfb9 |
diff --git a/lib/rpmfiles.h b/lib/rpmfiles.h
|
|
|
23dfb9 |
index 7ce1712323..e0adbd8aff 100644
|
|
|
23dfb9 |
--- a/lib/rpmfiles.h
|
|
|
23dfb9 |
+++ b/lib/rpmfiles.h
|
|
|
23dfb9 |
@@ -121,6 +121,9 @@ typedef enum rpmFileAction_e {
|
|
|
23dfb9 |
#define XFA_SKIPPING(_a) \
|
|
|
23dfb9 |
((_a) == FA_SKIP || (_a) == FA_SKIPNSTATE || (_a) == FA_SKIPNETSHARED || (_a) == FA_SKIPCOLOR)
|
|
|
23dfb9 |
|
|
|
23dfb9 |
+#define XFA_CREATING(_a) \
|
|
|
23dfb9 |
+ ((_a) == FA_CREATE || (_a) == FA_BACKUP || (_a) == FA_SAVE || (_a) == FA_ALTNAME)
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
/**
|
|
|
23dfb9 |
* We pass these around as an array with a sentinel.
|
|
|
23dfb9 |
*/
|
|
|
23dfb9 |
|
|
|
23dfb9 |
From fc54439f8a10901cd72028cdbdb924e3e7501624 Mon Sep 17 00:00:00 2001
|
|
|
23dfb9 |
From: Panu Matilainen <pmatilai@redhat.com>
|
|
|
23dfb9 |
Date: Wed, 10 Feb 2021 10:24:22 +0200
|
|
|
23dfb9 |
Subject: [PATCH 7/9] Clarify file installation temporary suffix rule
|
|
|
23dfb9 |
|
|
|
23dfb9 |
We only use a temporary suffix for regular files that we are actually
|
|
|
23dfb9 |
creating, skipped and touched files should not have it. Add XFA_CREATING()
|
|
|
23dfb9 |
macro to accomppany XFA_SKIPPING() to easily check whether the file
|
|
|
23dfb9 |
is being created or something else.
|
|
|
23dfb9 |
|
|
|
23dfb9 |
No functional changes but makes the logic clearer.
|
|
|
23dfb9 |
---
|
|
|
23dfb9 |
lib/fsm.c | 4 ++--
|
|
|
23dfb9 |
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
23dfb9 |
|
|
|
23dfb9 |
diff --git a/lib/fsm.c b/lib/fsm.c
|
|
|
23dfb9 |
index 554ea712f5..094f5e2bb6 100644
|
|
|
23dfb9 |
--- a/lib/fsm.c
|
|
|
23dfb9 |
+++ b/lib/fsm.c
|
|
|
23dfb9 |
@@ -876,8 +876,8 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
fp->action = rpmfsGetAction(fs, fx);
|
|
|
23dfb9 |
fp->skip = XFA_SKIPPING(fp->action);
|
|
|
23dfb9 |
fp->setmeta = 1;
|
|
|
23dfb9 |
- if (XFA_CREATING(fp->action))
|
|
|
23dfb9 |
- fp->suffix = S_ISDIR(rpmfiFMode(fi)) ? NULL : tid;
|
|
|
23dfb9 |
+ if (XFA_CREATING(fp->action) && !S_ISDIR(rpmfiFMode(fi)))
|
|
|
23dfb9 |
+ fp->suffix = tid;
|
|
|
23dfb9 |
fp->fpath = fsmFsPath(fi, fp->suffix);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* Remap file perms, owner, and group. */
|
|
|
23dfb9 |
|
|
|
23dfb9 |
From 9294ffa898bc7f1f77ff80c0a3f4f0f70c4dfef2 Mon Sep 17 00:00:00 2001
|
|
|
23dfb9 |
From: Panu Matilainen <pmatilai@redhat.com>
|
|
|
23dfb9 |
Date: Wed, 10 Feb 2021 11:25:10 +0200
|
|
|
23dfb9 |
Subject: [PATCH 8/9] Handle hardlink tracking with a file state pointer
|
|
|
23dfb9 |
|
|
|
23dfb9 |
No functional changes, just makes it a little cleaner as firstlink now
|
|
|
23dfb9 |
points to the actual file data instead of a index number somewhere.
|
|
|
23dfb9 |
---
|
|
|
23dfb9 |
lib/fsm.c | 20 +++++++++-----------
|
|
|
23dfb9 |
1 file changed, 9 insertions(+), 11 deletions(-)
|
|
|
23dfb9 |
|
|
|
23dfb9 |
diff --git a/lib/fsm.c b/lib/fsm.c
|
|
|
23dfb9 |
index 094f5e2bb6..f86383a986 100644
|
|
|
23dfb9 |
--- a/lib/fsm.c
|
|
|
23dfb9 |
+++ b/lib/fsm.c
|
|
|
23dfb9 |
@@ -282,24 +282,22 @@ static int expandRegular(rpmfi fi, const char *dest, rpmpsm psm, int nodigest)
|
|
|
23dfb9 |
|
|
|
23dfb9 |
static int fsmMkfile(rpmfi fi, struct filedata_s *fp, rpmfiles files,
|
|
|
23dfb9 |
rpmpsm psm, int nodigest,
|
|
|
23dfb9 |
- int * firsthardlink, FD_t *firstlinkfile)
|
|
|
23dfb9 |
+ struct filedata_s ** firstlink, FD_t *firstlinkfile)
|
|
|
23dfb9 |
{
|
|
|
23dfb9 |
int rc = 0;
|
|
|
23dfb9 |
int numHardlinks = rpmfiFNlink(fi);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (numHardlinks > 1) {
|
|
|
23dfb9 |
/* Create first hardlinked file empty */
|
|
|
23dfb9 |
- if (*firsthardlink < 0) {
|
|
|
23dfb9 |
- *firsthardlink = rpmfiFX(fi);
|
|
|
23dfb9 |
+ if (*firstlink == NULL) {
|
|
|
23dfb9 |
+ *firstlink = fp;
|
|
|
23dfb9 |
rc = wfd_open(firstlinkfile, fp->fpath);
|
|
|
23dfb9 |
} else {
|
|
|
23dfb9 |
/* Create hard links for others */
|
|
|
23dfb9 |
- char *fn = rpmfilesFN(files, *firsthardlink);
|
|
|
23dfb9 |
- rc = link(fn, fp->fpath);
|
|
|
23dfb9 |
+ rc = link((*firstlink)->fpath, fp->fpath);
|
|
|
23dfb9 |
if (rc < 0) {
|
|
|
23dfb9 |
rc = RPMERR_LINK_FAILED;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
- free(fn);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
/* Write normal files or fill the last hardlinked (already
|
|
|
23dfb9 |
@@ -311,7 +309,7 @@ static int fsmMkfile(rpmfi fi, struct filedata_s *fp, rpmfiles files,
|
|
|
23dfb9 |
if (!rc)
|
|
|
23dfb9 |
rc = rpmfiArchiveReadToFilePsm(fi, *firstlinkfile, nodigest, psm);
|
|
|
23dfb9 |
wfd_close(firstlinkfile);
|
|
|
23dfb9 |
- *firsthardlink = -1;
|
|
|
23dfb9 |
+ *firstlink = NULL;
|
|
|
23dfb9 |
} else {
|
|
|
23dfb9 |
fp->setmeta = 0;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
@@ -855,10 +853,10 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
int fc = rpmfilesFC(files);
|
|
|
23dfb9 |
int nodigest = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOFILEDIGEST) ? 1 : 0;
|
|
|
23dfb9 |
int nofcaps = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCAPS) ? 1 : 0;
|
|
|
23dfb9 |
- int firsthardlink = -1;
|
|
|
23dfb9 |
FD_t firstlinkfile = NULL;
|
|
|
23dfb9 |
char *tid = NULL;
|
|
|
23dfb9 |
struct filedata_s *fdata = xcalloc(fc, sizeof(*fdata));
|
|
|
23dfb9 |
+ struct filedata_s *firstlink = NULL;
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (fi == NULL) {
|
|
|
23dfb9 |
rc = RPMERR_BAD_MAGIC;
|
|
|
23dfb9 |
@@ -925,7 +923,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
if (S_ISREG(fp->sb.st_mode)) {
|
|
|
23dfb9 |
if (rc == RPMERR_ENOENT) {
|
|
|
23dfb9 |
rc = fsmMkfile(fi, fp, files, psm, nodigest,
|
|
|
23dfb9 |
- &firsthardlink, &firstlinkfile);
|
|
|
23dfb9 |
+ &firstlink, &firstlinkfile);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
} else if (S_ISDIR(fp->sb.st_mode)) {
|
|
|
23dfb9 |
if (rc == RPMERR_ENOENT) {
|
|
|
23dfb9 |
@@ -962,13 +960,13 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
rc = fsmSetmeta(fp->fpath, fi, plugins, fp->action,
|
|
|
23dfb9 |
&fp->sb, nofcaps);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
- } else if (firsthardlink >= 0 && rpmfiArchiveHasContent(fi)) {
|
|
|
23dfb9 |
+ } else if (firstlink && rpmfiArchiveHasContent(fi)) {
|
|
|
23dfb9 |
/* On FA_TOUCH no hardlinks are created thus this is skipped. */
|
|
|
23dfb9 |
/* we skip the hard linked file containing the content */
|
|
|
23dfb9 |
/* write the content to the first used instead */
|
|
|
23dfb9 |
rc = rpmfiArchiveReadToFilePsm(fi, firstlinkfile, nodigest, psm);
|
|
|
23dfb9 |
wfd_close(&firstlinkfile);
|
|
|
23dfb9 |
- firsthardlink = -1;
|
|
|
23dfb9 |
+ firstlink = NULL;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (rc) {
|
|
|
23dfb9 |
|
|
|
23dfb9 |
From d6a9a00396a89d14858c6b6e2548eca2065c1d64 Mon Sep 17 00:00:00 2001
|
|
|
23dfb9 |
From: Panu Matilainen <pmatilai@redhat.com>
|
|
|
23dfb9 |
Date: Wed, 10 Feb 2021 14:15:33 +0200
|
|
|
23dfb9 |
Subject: [PATCH 9/9] Handle file install failures more gracefully
|
|
|
23dfb9 |
|
|
|
23dfb9 |
Run the file installation in multiple stages:
|
|
|
23dfb9 |
1) gather intel
|
|
|
23dfb9 |
2) unpack the archive to temporary files
|
|
|
23dfb9 |
3) set file metadatas
|
|
|
23dfb9 |
4) commit files to final location
|
|
|
23dfb9 |
5) mop up leftovers on failure
|
|
|
23dfb9 |
|
|
|
23dfb9 |
This means we no longer leave behind a trail of untracked, potentially
|
|
|
23dfb9 |
harmful junk on installation failure.
|
|
|
23dfb9 |
|
|
|
23dfb9 |
If commit step fails the package can still be left in an inconsistent stage,
|
|
|
23dfb9 |
this could be further improved by first backing up old files to temporary
|
|
|
23dfb9 |
location to allow undo on failure, but leaving that for some other day.
|
|
|
23dfb9 |
Also unowned directories will still be left behind.
|
|
|
23dfb9 |
|
|
|
23dfb9 |
And yes, this is a somewhat scary change as it's the biggest ever change
|
|
|
23dfb9 |
to how rpm lays down files on install. Adopt the hardlink test spec
|
|
|
23dfb9 |
over to install tests and add some more tests for the new behavior.
|
|
|
23dfb9 |
|
|
|
23dfb9 |
Fixes: #967 (+ multiple reports over the years)
|
|
|
23dfb9 |
---
|
|
|
23dfb9 |
lib/fsm.c | 147 ++++++++++++++++++++------------
|
|
|
23dfb9 |
tests/data/SPECS/hlinktest.spec | 4 +
|
|
|
23dfb9 |
tests/rpmbuild.at | 32 -------
|
|
|
23dfb9 |
tests/rpmi.at | 92 ++++++++++++++++++++
|
|
|
23dfb9 |
4 files changed, 189 insertions(+), 86 deletions(-)
|
|
|
23dfb9 |
|
|
|
23dfb9 |
diff --git a/lib/fsm.c b/lib/fsm.c
|
|
|
23dfb9 |
index f86383a986..6efd25bddd 100644
|
|
|
23dfb9 |
--- a/lib/fsm.c
|
|
|
23dfb9 |
+++ b/lib/fsm.c
|
|
|
23dfb9 |
@@ -38,7 +38,17 @@ static int strict_erasures = 0;
|
|
|
23dfb9 |
#define _dirPerms 0755
|
|
|
23dfb9 |
#define _filePerms 0644
|
|
|
23dfb9 |
|
|
|
23dfb9 |
+enum filestage_e {
|
|
|
23dfb9 |
+ FILE_COMMIT = -1,
|
|
|
23dfb9 |
+ FILE_NONE = 0,
|
|
|
23dfb9 |
+ FILE_PRE = 1,
|
|
|
23dfb9 |
+ FILE_UNPACK = 2,
|
|
|
23dfb9 |
+ FILE_PREP = 3,
|
|
|
23dfb9 |
+ FILE_POST = 4,
|
|
|
23dfb9 |
+};
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
struct filedata_s {
|
|
|
23dfb9 |
+ int stage;
|
|
|
23dfb9 |
int setmeta;
|
|
|
23dfb9 |
int skip;
|
|
|
23dfb9 |
rpmFileAction action;
|
|
|
23dfb9 |
@@ -844,10 +854,9 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
rpmpsm psm, char ** failedFile)
|
|
|
23dfb9 |
{
|
|
|
23dfb9 |
FD_t payload = rpmtePayload(te);
|
|
|
23dfb9 |
- rpmfi fi = rpmfiNewArchiveReader(payload, files, RPMFI_ITER_READ_ARCHIVE);
|
|
|
23dfb9 |
+ rpmfi fi = NULL;
|
|
|
23dfb9 |
rpmfs fs = rpmteGetFileStates(te);
|
|
|
23dfb9 |
rpmPlugins plugins = rpmtsPlugins(ts);
|
|
|
23dfb9 |
- int saveerrno = errno;
|
|
|
23dfb9 |
int rc = 0;
|
|
|
23dfb9 |
int fx = -1;
|
|
|
23dfb9 |
int fc = rpmfilesFC(files);
|
|
|
23dfb9 |
@@ -858,20 +867,17 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
struct filedata_s *fdata = xcalloc(fc, sizeof(*fdata));
|
|
|
23dfb9 |
struct filedata_s *firstlink = NULL;
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- if (fi == NULL) {
|
|
|
23dfb9 |
- rc = RPMERR_BAD_MAGIC;
|
|
|
23dfb9 |
- goto exit;
|
|
|
23dfb9 |
- }
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
/* transaction id used for temporary path suffix while installing */
|
|
|
23dfb9 |
rasprintf(&tid, ";%08x", (unsigned)rpmtsGetTid(ts));
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- /* Detect and create directories not explicitly in package. */
|
|
|
23dfb9 |
- rc = fsmMkdirs(files, fs, plugins);
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
+ /* Collect state data for the whole operation */
|
|
|
23dfb9 |
+ fi = rpmfilesIter(files, RPMFI_ITER_FWD);
|
|
|
23dfb9 |
while (!rc && (fx = rpmfiNext(fi)) >= 0) {
|
|
|
23dfb9 |
struct filedata_s *fp = &fdata[fx];
|
|
|
23dfb9 |
- fp->action = rpmfsGetAction(fs, fx);
|
|
|
23dfb9 |
+ if (rpmfiFFlags(fi) & RPMFILE_GHOST)
|
|
|
23dfb9 |
+ fp->action = FA_SKIP;
|
|
|
23dfb9 |
+ else
|
|
|
23dfb9 |
+ fp->action = rpmfsGetAction(fs, fx);
|
|
|
23dfb9 |
fp->skip = XFA_SKIPPING(fp->action);
|
|
|
23dfb9 |
fp->setmeta = 1;
|
|
|
23dfb9 |
if (XFA_CREATING(fp->action) && !S_ISDIR(rpmfiFMode(fi)))
|
|
|
23dfb9 |
@@ -881,20 +887,32 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
/* Remap file perms, owner, and group. */
|
|
|
23dfb9 |
rc = rpmfiStat(fi, 1, &fp->sb);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
+ setFileState(fs, fx);
|
|
|
23dfb9 |
fsmDebug(fp->fpath, fp->action, &fp->sb);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- /* Exit on error. */
|
|
|
23dfb9 |
- if (rc)
|
|
|
23dfb9 |
- break;
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
/* Run fsm file pre hook for all plugins */
|
|
|
23dfb9 |
rc = rpmpluginsCallFsmFilePre(plugins, fi, fp->fpath,
|
|
|
23dfb9 |
fp->sb.st_mode, fp->action);
|
|
|
23dfb9 |
- if (rc) {
|
|
|
23dfb9 |
- fp->skip = 1;
|
|
|
23dfb9 |
- } else {
|
|
|
23dfb9 |
- setFileState(fs, fx);
|
|
|
23dfb9 |
- }
|
|
|
23dfb9 |
+ fp->stage = FILE_PRE;
|
|
|
23dfb9 |
+ }
|
|
|
23dfb9 |
+ fi = rpmfiFree(fi);
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+ if (rc)
|
|
|
23dfb9 |
+ goto exit;
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+ fi = rpmfiNewArchiveReader(payload, files, RPMFI_ITER_READ_ARCHIVE);
|
|
|
23dfb9 |
+ if (fi == NULL) {
|
|
|
23dfb9 |
+ rc = RPMERR_BAD_MAGIC;
|
|
|
23dfb9 |
+ goto exit;
|
|
|
23dfb9 |
+ }
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+ /* Detect and create directories not explicitly in package. */
|
|
|
23dfb9 |
+ if (!rc)
|
|
|
23dfb9 |
+ rc = fsmMkdirs(files, fs, plugins);
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+ /* Process the payload */
|
|
|
23dfb9 |
+ while (!rc && (fx = rpmfiNext(fi)) >= 0) {
|
|
|
23dfb9 |
+ struct filedata_s *fp = &fdata[fx];
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (!fp->skip) {
|
|
|
23dfb9 |
/* Directories replacing something need early backup */
|
|
|
23dfb9 |
@@ -918,7 +936,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
|
|
|
23dfb9 |
/* When touching we don't need any of this... */
|
|
|
23dfb9 |
if (fp->action == FA_TOUCH)
|
|
|
23dfb9 |
- goto touch;
|
|
|
23dfb9 |
+ continue;
|
|
|
23dfb9 |
|
|
|
23dfb9 |
if (S_ISREG(fp->sb.st_mode)) {
|
|
|
23dfb9 |
if (rc == RPMERR_ENOENT) {
|
|
|
23dfb9 |
@@ -954,12 +972,6 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
rc = RPMERR_UNKNOWN_FILETYPE;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
-touch:
|
|
|
23dfb9 |
- /* Set permissions, timestamps etc for non-hardlink entries */
|
|
|
23dfb9 |
- if (!rc && fp->setmeta) {
|
|
|
23dfb9 |
- rc = fsmSetmeta(fp->fpath, fi, plugins, fp->action,
|
|
|
23dfb9 |
- &fp->sb, nofcaps);
|
|
|
23dfb9 |
- }
|
|
|
23dfb9 |
} else if (firstlink && rpmfiArchiveHasContent(fi)) {
|
|
|
23dfb9 |
/* On FA_TOUCH no hardlinks are created thus this is skipped. */
|
|
|
23dfb9 |
/* we skip the hard linked file containing the content */
|
|
|
23dfb9 |
@@ -969,47 +981,74 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
|
|
|
23dfb9 |
firstlink = NULL;
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- if (rc) {
|
|
|
23dfb9 |
- if (!fp->skip) {
|
|
|
23dfb9 |
- /* XXX only erase if temp fn w suffix is in use */
|
|
|
23dfb9 |
- if (fp->suffix) {
|
|
|
23dfb9 |
- (void) fsmRemove(fp->fpath, fp->sb.st_mode);
|
|
|
23dfb9 |
- }
|
|
|
23dfb9 |
- errno = saveerrno;
|
|
|
23dfb9 |
- }
|
|
|
23dfb9 |
- } else {
|
|
|
23dfb9 |
- /* Notify on success. */
|
|
|
23dfb9 |
+ /* Notify on success. */
|
|
|
23dfb9 |
+ if (rc)
|
|
|
23dfb9 |
+ *failedFile = xstrdup(fp->fpath);
|
|
|
23dfb9 |
+ else
|
|
|
23dfb9 |
rpmpsmNotify(psm, RPMCALLBACK_INST_PROGRESS, rpmfiArchiveTell(fi));
|
|
|
23dfb9 |
+ fp->stage = FILE_UNPACK;
|
|
|
23dfb9 |
+ }
|
|
|
23dfb9 |
+ fi = rpmfiFree(fi);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- if (!fp->skip) {
|
|
|
23dfb9 |
- /* Backup file if needed. Directories are handled earlier */
|
|
|
23dfb9 |
- if (fp->suffix)
|
|
|
23dfb9 |
- rc = fsmBackup(fi, fp->action);
|
|
|
23dfb9 |
+ if (!rc && fx < 0 && fx != RPMERR_ITER_END)
|
|
|
23dfb9 |
+ rc = fx;
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- if (!rc)
|
|
|
23dfb9 |
- rc = fsmCommit(&fp->fpath, fi, fp->action, fp->suffix);
|
|
|
23dfb9 |
- }
|
|
|
23dfb9 |
+ /* Set permissions, timestamps etc for non-hardlink entries */
|
|
|
23dfb9 |
+ fi = rpmfilesIter(files, RPMFI_ITER_FWD);
|
|
|
23dfb9 |
+ while (!rc && (fx = rpmfiNext(fi)) >= 0) {
|
|
|
23dfb9 |
+ struct filedata_s *fp = &fdata[fx];
|
|
|
23dfb9 |
+ if (!fp->skip && fp->setmeta) {
|
|
|
23dfb9 |
+ rc = fsmSetmeta(fp->fpath, fi, plugins, fp->action,
|
|
|
23dfb9 |
+ &fp->sb, nofcaps);
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
if (rc)
|
|
|
23dfb9 |
*failedFile = xstrdup(fp->fpath);
|
|
|
23dfb9 |
+ fp->stage = FILE_PREP;
|
|
|
23dfb9 |
+ }
|
|
|
23dfb9 |
+ fi = rpmfiFree(fi);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- /* Run fsm file post hook for all plugins */
|
|
|
23dfb9 |
- rpmpluginsCallFsmFilePost(plugins, fi, fp->fpath,
|
|
|
23dfb9 |
- fp->sb.st_mode, fp->action, rc);
|
|
|
23dfb9 |
+ /* If all went well, commit files to final destination */
|
|
|
23dfb9 |
+ fi = rpmfilesIter(files, RPMFI_ITER_FWD);
|
|
|
23dfb9 |
+ while (!rc && (fx = rpmfiNext(fi)) >= 0) {
|
|
|
23dfb9 |
+ struct filedata_s *fp = &fdata[fx];
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+ if (!fp->skip) {
|
|
|
23dfb9 |
+ /* Backup file if needed. Directories are handled earlier */
|
|
|
23dfb9 |
+ if (!rc && fp->suffix)
|
|
|
23dfb9 |
+ rc = fsmBackup(fi, fp->action);
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+ if (!rc)
|
|
|
23dfb9 |
+ rc = fsmCommit(&fp->fpath, fi, fp->action, fp->suffix);
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+ if (!rc)
|
|
|
23dfb9 |
+ fp->stage = FILE_COMMIT;
|
|
|
23dfb9 |
+ else
|
|
|
23dfb9 |
+ *failedFile = xstrdup(fp->fpath);
|
|
|
23dfb9 |
+ }
|
|
|
23dfb9 |
}
|
|
|
23dfb9 |
+ fi = rpmfiFree(fi);
|
|
|
23dfb9 |
|
|
|
23dfb9 |
- if (!rc && fx != RPMERR_ITER_END)
|
|
|
23dfb9 |
- rc = fx;
|
|
|
23dfb9 |
+ /* Walk backwards in case we need to erase */
|
|
|
23dfb9 |
+ fi = rpmfilesIter(files, RPMFI_ITER_BACK);
|
|
|
23dfb9 |
+ while ((fx = rpmfiNext(fi)) >= 0) {
|
|
|
23dfb9 |
+ struct filedata_s *fp = &fdata[fx];
|
|
|
23dfb9 |
+ /* Run fsm file post hook for all plugins for all processed files */
|
|
|
23dfb9 |
+ if (fp->stage) {
|
|
|
23dfb9 |
+ rpmpluginsCallFsmFilePost(plugins, fi, fp->fpath,
|
|
|
23dfb9 |
+ fp->sb.st_mode, fp->action, rc);
|
|
|
23dfb9 |
+ }
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+ /* On failure, erase non-committed files */
|
|
|
23dfb9 |
+ if (rc && fp->stage > FILE_NONE && !fp->skip) {
|
|
|
23dfb9 |
+ (void) fsmRemove(fp->fpath, fp->sb.st_mode);
|
|
|
23dfb9 |
+ }
|
|
|
23dfb9 |
+ }
|
|
|
23dfb9 |
|
|
|
23dfb9 |
rpmswAdd(rpmtsOp(ts, RPMTS_OP_UNCOMPRESS), fdOp(payload, FDSTAT_READ));
|
|
|
23dfb9 |
rpmswAdd(rpmtsOp(ts, RPMTS_OP_DIGEST), fdOp(payload, FDSTAT_DIGEST));
|
|
|
23dfb9 |
|
|
|
23dfb9 |
exit:
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
- /* No need to bother with close errors on read */
|
|
|
23dfb9 |
- rpmfiArchiveClose(fi);
|
|
|
23dfb9 |
- rpmfiFree(fi);
|
|
|
23dfb9 |
+ fi = rpmfiFree(fi);
|
|
|
23dfb9 |
Fclose(payload);
|
|
|
23dfb9 |
free(tid);
|
|
|
23dfb9 |
for (int i = 0; i < fc; i++)
|
|
|
23dfb9 |
diff --git a/tests/data/SPECS/hlinktest.spec b/tests/data/SPECS/hlinktest.spec
|
|
|
23dfb9 |
index 753c174cd8..3f1437d89c 100644
|
|
|
23dfb9 |
--- a/tests/data/SPECS/hlinktest.spec
|
|
|
23dfb9 |
+++ b/tests/data/SPECS/hlinktest.spec
|
|
|
23dfb9 |
@@ -1,5 +1,6 @@
|
|
|
23dfb9 |
%bcond_with unpackaged_dirs
|
|
|
23dfb9 |
%bcond_with unpackaged_files
|
|
|
23dfb9 |
+%bcond_with owned_dir
|
|
|
23dfb9 |
|
|
|
23dfb9 |
Summary: Testing hard link behavior
|
|
|
23dfb9 |
Name: hlinktest
|
|
|
23dfb9 |
@@ -43,4 +44,7 @@ touch $RPM_BUILD_ROOT/teet
|
|
|
23dfb9 |
|
|
|
23dfb9 |
%files
|
|
|
23dfb9 |
%defattr(-,root,root)
|
|
|
23dfb9 |
+%if %{with owned_dir}
|
|
|
23dfb9 |
+%dir /foo
|
|
|
23dfb9 |
+%endif
|
|
|
23dfb9 |
/foo/*
|
|
|
23dfb9 |
diff --git a/tests/rpmbuild.at b/tests/rpmbuild.at
|
|
|
23dfb9 |
index 1f0e679c44..f0eef4eff0 100644
|
|
|
23dfb9 |
--- a/tests/rpmbuild.at
|
|
|
23dfb9 |
+++ b/tests/rpmbuild.at
|
|
|
23dfb9 |
@@ -253,38 +253,6 @@ drwxrwxrwx zoot zoot /j/dir
|
|
|
23dfb9 |
[])
|
|
|
23dfb9 |
AT_CLEANUP
|
|
|
23dfb9 |
|
|
|
23dfb9 |
-# ------------------------------
|
|
|
23dfb9 |
-# hardlink tests
|
|
|
23dfb9 |
-AT_SETUP([rpmbuild hardlink])
|
|
|
23dfb9 |
-AT_KEYWORDS([build])
|
|
|
23dfb9 |
-RPMDB_INIT
|
|
|
23dfb9 |
-AT_CHECK([
|
|
|
23dfb9 |
-RPMDB_INIT
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
-runroot rpmbuild \
|
|
|
23dfb9 |
- -bb --quiet /data/SPECS/hlinktest.spec
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
-runroot rpm -i /build/RPMS/noarch/hlinktest-1.0-1.noarch.rpm
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
-runroot rpm -q --qf "[[%{filenlinks} %{filenames}\n]]%{longsize}\n" hlinktest
|
|
|
23dfb9 |
-runroot rpm -V --nouser --nogroup hlinktest
|
|
|
23dfb9 |
-ls -i "${RPMTEST}"/foo/hello* | awk {'print $1'} | sort -u | wc -l
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
-],
|
|
|
23dfb9 |
-[0],
|
|
|
23dfb9 |
-[2 /foo/aaaa
|
|
|
23dfb9 |
-1 /foo/copyllo
|
|
|
23dfb9 |
-4 /foo/hello
|
|
|
23dfb9 |
-4 /foo/hello-bar
|
|
|
23dfb9 |
-4 /foo/hello-foo
|
|
|
23dfb9 |
-4 /foo/hello-world
|
|
|
23dfb9 |
-2 /foo/zzzz
|
|
|
23dfb9 |
-87
|
|
|
23dfb9 |
-1
|
|
|
23dfb9 |
-],
|
|
|
23dfb9 |
-[])
|
|
|
23dfb9 |
-AT_CLEANUP
|
|
|
23dfb9 |
-
|
|
|
23dfb9 |
AT_SETUP([rpmbuild unpackaged files])
|
|
|
23dfb9 |
AT_KEYWORDS([build])
|
|
|
23dfb9 |
RPMDB_INIT
|
|
|
23dfb9 |
diff --git a/tests/rpmi.at b/tests/rpmi.at
|
|
|
23dfb9 |
index 42dc52ba35..295fbc230f 100644
|
|
|
23dfb9 |
--- a/tests/rpmi.at
|
|
|
23dfb9 |
+++ b/tests/rpmi.at
|
|
|
23dfb9 |
@@ -722,3 +722,95 @@ runroot rpm -V --nouser --nogroup suicidal
|
|
|
23dfb9 |
[],
|
|
|
23dfb9 |
[])
|
|
|
23dfb9 |
AT_CLEANUP
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+# ------------------------------
|
|
|
23dfb9 |
+# hardlink tests
|
|
|
23dfb9 |
+AT_SETUP([rpm -i hardlinks])
|
|
|
23dfb9 |
+AT_KEYWORDS([build install])
|
|
|
23dfb9 |
+RPMDB_INIT
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+# Need a reproducable test package
|
|
|
23dfb9 |
+runroot rpmbuild \
|
|
|
23dfb9 |
+ --define "%optflags -O2 -g" \
|
|
|
23dfb9 |
+ --define "%_target_platform noarch-linux" \
|
|
|
23dfb9 |
+ --define "%_binary_payload w.ufdio" \
|
|
|
23dfb9 |
+ --define "%_buildhost localhost" \
|
|
|
23dfb9 |
+ --define "%use_source_date_epoch_as_buildtime 1" \
|
|
|
23dfb9 |
+ --define "%source_date_epoch_from_changelog 1" \
|
|
|
23dfb9 |
+ --define "%clamp_mtime_to_source_date_epoch 1" \
|
|
|
23dfb9 |
+ --with owned_dir \
|
|
|
23dfb9 |
+ -bb --quiet /data/SPECS/hlinktest.spec
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+pkg="/build/RPMS/noarch/hlinktest-1.0-1.noarch.rpm"
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+cp "${RPMTEST}/${pkg}" "${RPMTEST}/tmp/1.rpm"
|
|
|
23dfb9 |
+dd if=/dev/zero of="${RPMTEST}/tmp/1.rpm" \
|
|
|
23dfb9 |
+ conv=notrunc bs=1 seek=8180 count=6 2> /dev/null
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+cp "${RPMTEST}/${pkg}" "${RPMTEST}/tmp/2.rpm"
|
|
|
23dfb9 |
+dd if=/dev/zero of="${RPMTEST}/tmp/2.rpm" \
|
|
|
23dfb9 |
+ conv=notrunc bs=1 seek=8150 count=6 2> /dev/null
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+cp "${RPMTEST}/${pkg}" "${RPMTEST}/tmp/3.rpm"
|
|
|
23dfb9 |
+dd if=/dev/zero of="${RPMTEST}/tmp/3.rpm" \
|
|
|
23dfb9 |
+ conv=notrunc bs=1 seek=8050 count=6 2> /dev/null
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+AT_CHECK([
|
|
|
23dfb9 |
+RPMDB_INIT
|
|
|
23dfb9 |
+runroot rpm -i --noverify /tmp/1.rpm
|
|
|
23dfb9 |
+# test that nothing of the contents remains after failure
|
|
|
23dfb9 |
+test -d "${RPMTEST}/foo"
|
|
|
23dfb9 |
+],
|
|
|
23dfb9 |
+[1],
|
|
|
23dfb9 |
+[],
|
|
|
23dfb9 |
+[error: unpacking of archive failed: cpio: Archive file not in header
|
|
|
23dfb9 |
+error: hlinktest-1.0-1.noarch: install failed
|
|
|
23dfb9 |
+])
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+AT_CHECK([
|
|
|
23dfb9 |
+RPMDB_INIT
|
|
|
23dfb9 |
+runroot rpm -i --noverify /tmp/2.rpm
|
|
|
23dfb9 |
+# test that nothing of the contents remains after failure
|
|
|
23dfb9 |
+test -d "${RPMTEST}/foo"
|
|
|
23dfb9 |
+],
|
|
|
23dfb9 |
+[1],
|
|
|
23dfb9 |
+[],
|
|
|
23dfb9 |
+[error: unpacking of archive failed: cpio: Bad/unreadable header
|
|
|
23dfb9 |
+error: hlinktest-1.0-1.noarch: install failed
|
|
|
23dfb9 |
+])
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+AT_CHECK([
|
|
|
23dfb9 |
+RPMDB_INIT
|
|
|
23dfb9 |
+runroot rpm -i --noverify /tmp/3.rpm 2>&1| sed 's/;.*:/:/g'
|
|
|
23dfb9 |
+# test that nothing of the contents remains after failure
|
|
|
23dfb9 |
+test -d "${RPMTEST}/foo"
|
|
|
23dfb9 |
+],
|
|
|
23dfb9 |
+[1],
|
|
|
23dfb9 |
+[error: unpacking of archive failed on file /foo/hello-world: Digest mismatch
|
|
|
23dfb9 |
+error: hlinktest-1.0-1.noarch: install failed
|
|
|
23dfb9 |
+],
|
|
|
23dfb9 |
+[])
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+AT_CHECK([
|
|
|
23dfb9 |
+RPMDB_INIT
|
|
|
23dfb9 |
+runroot rpm -i /build/RPMS/noarch/hlinktest-1.0-1.noarch.rpm
|
|
|
23dfb9 |
+runroot rpm -q --qf "[[%{filenlinks} %{filenames}\n]]%{longsize}\n" hlinktest
|
|
|
23dfb9 |
+ls -i "${RPMTEST}"/foo/hello* | awk {'print $1'} | sort -u | wc -l
|
|
|
23dfb9 |
+runroot rpm -e hlinktest
|
|
|
23dfb9 |
+
|
|
|
23dfb9 |
+],
|
|
|
23dfb9 |
+[0],
|
|
|
23dfb9 |
+[1 /foo
|
|
|
23dfb9 |
+2 /foo/aaaa
|
|
|
23dfb9 |
+1 /foo/copyllo
|
|
|
23dfb9 |
+4 /foo/hello
|
|
|
23dfb9 |
+4 /foo/hello-bar
|
|
|
23dfb9 |
+4 /foo/hello-foo
|
|
|
23dfb9 |
+4 /foo/hello-world
|
|
|
23dfb9 |
+2 /foo/zzzz
|
|
|
23dfb9 |
+87
|
|
|
23dfb9 |
+1
|
|
|
23dfb9 |
+],
|
|
|
23dfb9 |
+[])
|
|
|
23dfb9 |
+AT_CLEANUP
|
|
|
23dfb9 |
+
|