From 164290832ee5f4fb8a5e3e48fa75d180d50a63b6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 7 Sep 2017 13:29:29 -0400 Subject: [PATCH 1/2] lib/transaction: Don't SEGV in sync if a txn was failed I was actually testing a change to better handle `rpm -e atomic` on Fedora Atomic Host, wondering why my patch was crashing, but in fact it was the recently added sync code in master. --- lib/transaction.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/transaction.c b/lib/transaction.c index 555441f3c0..fc0966c6e0 100644 --- a/lib/transaction.c +++ b/lib/transaction.c @@ -1499,6 +1499,12 @@ static void rpmtsSync(rpmts ts) { if (rpmChrootDone()) return; + /* If the txn didn't get as far as calculating disk space, + * or disk space warnings are filtered out, assume we + * shouldn't sync. + */ + if (!ts->dsi) + return; #if HAVE_SYNCFS for (rpmDiskSpaceInfo dsi = ts->dsi; dsi->bsize; dsi++) { From 4265db7663964099e40beb5dfd012e5642c8e674 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 7 Sep 2017 13:07:00 -0400 Subject: [PATCH 2/2] Hint to users to use ostree/rpm-ostree if we get EROFS Down the line, it's likely that for rpm-ostree based systems we'll install an interceptor for `/usr/bin/rpm` to redirect at least things like local package installs. There's a lot of work to do for that, so in the meantime let's help admins out by giving them a helpful error message. --- lib/rpmlock.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/rpmlock.c b/lib/rpmlock.c index 9c0765436e..66ec6a1e9f 100644 --- a/lib/rpmlock.c +++ b/lib/rpmlock.c @@ -18,6 +18,7 @@ struct rpmlock_s { char *path; char *descr; int fdrefs; + const char *managedby_instead; }; static rpmlock rpmlock_new(const char *lock_path, const char *descr) @@ -27,13 +28,26 @@ static rpmlock rpmlock_new(const char *lock_path, const char *descr) if (lock != NULL) { mode_t oldmask = umask(022); lock->fd = open(lock_path, O_RDWR|O_CREAT, 0644); + int errsv = errno; (void) umask(oldmask); - if (lock->fd == -1) { + /* Check if this is an ostree/rpm-ostree managed system */ + lock->fdrefs = 1; + lock->managedby_instead = NULL; + if (lock->fd == -1 && errsv == EROFS) { + struct stat stbuf; + if (stat ("/run/ostree-booted", &stbuf) == 0) { + lock->managedby_instead = "ostree"; + if (stat ("/usr/bin/rpm-ostree", &stbuf) == 0) { + lock->managedby_instead = "rpm-ostree"; + } + } + lock->openmode = RPMLOCK_READ; + } else if (lock->fd == -1) { lock->fd = open(lock_path, O_RDONLY); if (lock->fd == -1) { free(lock); - lock = NULL; + return NULL; } else { lock->openmode = RPMLOCK_READ; } @@ -43,7 +57,6 @@ static rpmlock rpmlock_new(const char *lock_path, const char *descr) if (lock) { lock->path = xstrdup(lock_path); lock->descr = xstrdup(descr); - lock->fdrefs = 1; } } return lock; @@ -54,7 +67,8 @@ static void rpmlock_free(rpmlock lock) if (--lock->fdrefs == 0) { free(lock->path); free(lock->descr); - (void) close(lock->fd); + if (lock->fd != -1) + (void) close(lock->fd); free(lock); } } @@ -117,6 +131,8 @@ rpmlock rpmlockNew(const char *lock_path, const char *descr) if (!lock) { rpmlog(RPMLOG_ERR, _("can't create %s lock on %s (%s)\n"), descr, lock_path, strerror(errno)); + } else if (lock->managedby_instead) { + rpmlog(RPMLOG_ERR, _("This system is managed by %s\n"), lock->managedby_instead); } return lock; }