Add API to completely disable librpm's use of Unix signal handlers

On Tue, Feb 17, 2015, at 07:07 AM, Florian Festi wrote:
> Sorry, for the last response. DevConf takes its toll...
>
> On 01/23/2015 04:07 AM, Colin Walters wrote:
> > Numerous consumers of librpm use it in a pattern where they're
> > constructing fresh chroots.  For example, rpm-ostree operates this
> > way, and is used to provide atomic upgrades in concert with rpm.
> >
> > If the process dies due to SIGINT or another signal, the root can
> > simply be discarded.
> >
> > Currently today, rpm-ostree undoes the signal handlers after loading
> > librpm so that Control-C does what I want, but there's still a race
> > condition where the interrupt can be lost.
> >
> > Add an API so callers can disable the behavior.
>
> Is there any chance someone would want to switch them back on?

I can't think of one offhand...tools that interact with a live root
should be happy with what RPM does today, right?

> My gut
> feeling tells me this should rather be rpmsqSetInterruptSafety(int on);

But here's a patch which does it, in case you prefer it.  I did write
a better API doc this time.

From ae6d2de85b7b81cf91318183ba253402ac538785 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Thu, 22 Jan 2015 17:57:14 -0500
Subject: [PATCH] Add API to disable librpm's use of Unix signal handlers

Numerous consumers of librpm use it in a pattern where they're
constructing fresh chroots.  For example, rpm-ostree operates this
way, and is used to provide atomic upgrades in concert with rpm.

If the process dies due to SIGINT or another signal, the root can
simply be discarded.

Currently today, rpm-ostree undoes the signal handlers after loading
librpm so that Control-C does what I want, but there's still a race
condition where the interrupt can be lost.

Add an API so callers can disable the behavior.
This commit is contained in:
Colin Walters 2015-02-19 15:50:38 -05:00 committed by Florian Festi
parent b151b5297b
commit 56f49d7f5a
2 changed files with 28 additions and 0 deletions

View File

@ -16,6 +16,7 @@
#include "debug.h"
static int disableInterruptSafety;
static sigset_t rpmsqCaught;
typedef struct rpmsig_s * rpmsig;
@ -70,6 +71,9 @@ int rpmsqEnable(int signum, rpmsqAction_t handler)
rpmsig tbl;
int ret = -1;
if (disableInterruptSafety)
return 0;
for (tbl = rpmsigTbl; tbl->signum >= 0; tbl++) {
if (tblsignum != tbl->signum)
continue;
@ -112,3 +116,25 @@ int rpmsqEnable(int signum, rpmsqAction_t handler)
return ret;
}
/** \ingroup rpmio
*
* By default, librpm will trap various unix signals such as SIGINT and SIGTERM,
* in order to avoid process exit while locks are held or a transaction is being
* performed. However, there exist tools that operate on non-running roots (traditionally
* build systems such as mock), as well as deployment tools such as rpm-ostree.
*
* These tools are more robust against interruption - typically they
* will just throw away the partially constructed root. This function
* is designed for use by those tools, so an operator can happily
* press Control-C.
*
* It's recommended to call this once only at process startup if this
* behavior is desired (and to then avoid using librpm against "live"
* databases), because currently signal handlers will not be retroactively
* applied if a database is open.
*/
void rpmsqSetInterruptSafety(int on)
{
disableInterruptSafety = !on;
}

View File

@ -52,6 +52,8 @@ void rpmsqAction(int signum);
*/
int rpmsqEnable(int signum, rpmsqAction_t handler);
void rpmsqSetInterruptSafety(int on);
#ifdef __cplusplus
}
#endif