Skip to content

Commit

Permalink
Add API to completely disable librpm's use of Unix signal handlers
Browse files Browse the repository at this point in the history
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 <[email protected]>
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.
  • Loading branch information
cgwalters authored and ffesti committed Feb 20, 2015
1 parent b151b52 commit 56f49d7
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
26 changes: 26 additions & 0 deletions rpmio/rpmsq.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "debug.h"

static int disableInterruptSafety;
static sigset_t rpmsqCaught;

typedef struct rpmsig_s * rpmsig;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
2 changes: 2 additions & 0 deletions rpmio/rpmsq.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ void rpmsqAction(int signum);
*/
int rpmsqEnable(int signum, rpmsqAction_t handler);

void rpmsqSetInterruptSafety(int on);

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit 56f49d7

Please sign in to comment.