Skip to content

Commit

Permalink
Add rpmlogOnce() and rpmlogReset()
Browse files Browse the repository at this point in the history
These are internal only for now to allow us gain soem more confidence on
the design.

rpmlogOnce allows showing a log message only once. rpmlogReset allows purging
the list of known message keys for a given domain. This allows for different
live times e.g. per transaction or per package.

Use in handleHdrVS. This does not add a new test case but various
existing test cases fail when the NOKEY message is omited or shown
more than once. The code uses the pointer to the rpmts object as a
domain and resets it when the rpmts is freed.

Resolves: #3336
Resolves: #3395
  • Loading branch information
ffesti committed Oct 31, 2024
1 parent ebc4068 commit bf6baaa
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 25 deletions.
31 changes: 7 additions & 24 deletions lib/package.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "rpmlead.hh"
#include "rpmio_internal.hh" /* fd digest bits */
#include "rpmlog_internal.hh" /* rpmlogOnce */
#include "header_internal.hh" /* XXX headerCheck */
#include "rpmvs.hh"

Expand All @@ -31,6 +32,7 @@ struct pkgdata_s {
hdrvsmsg msgfunc;
const char *fn;
char *msg;
uint64_t logDomain;
rpmRC rc;
};

Expand Down Expand Up @@ -110,28 +112,6 @@ rpmTagVal headerMergeLegacySigs(Header h, Header sigh, char **msg)
return xl->stag;
}

/**
* Remember current key id.
* XXX: This s*** needs to die. Hook it into keyring or sumthin...
* @param keyid signature keyid
* @return 0 if new keyid, otherwise 1
*/
static int stashKeyid(const char *keyid)
{
static std::mutex keyid_mutex;
static std::set<std::string> keyids;
int seen = 0;

if (keyid == NULL)
return 0;

std::lock_guard<std::mutex> lock(keyid_mutex);
auto ret = keyids.insert(keyid);
seen = (ret.second == false);

return seen;
}

static int handleHdrVS(struct rpmsinfo_s *sinfo, void *cbdata)
{
struct pkgdata_s *pkgdata = (struct pkgdata_s *)cbdata;
Expand Down Expand Up @@ -170,6 +150,7 @@ rpmRC headerCheck(rpmts ts, const void * uh, size_t uc, char ** msg)
.msgfunc = appendhdrmsg,
.fn = NULL,
.msg = NULL,
.logDomain = (uint64_t) ts,
.rc = RPMRC_OK,
};

Expand Down Expand Up @@ -294,8 +275,8 @@ static void loghdrmsg(struct rpmsinfo_s *sinfo, struct pkgdata_s *pkgdata,
case RPMRC_NOTTRUSTED: /* Signature is OK, but key is not trusted. */
case RPMRC_NOKEY: /* Public key is unavailable. */
/* XXX Print NOKEY/NOTTRUSTED warning only once. */
if (stashKeyid(sinfo->keyid) == 0)
lvl = RPMLOG_WARNING;
if (rpmlogOnce(pkgdata->logDomain, sinfo->keyid, RPMLOG_WARNING, "%s: %s\n", pkgdata->fn, msg))
goto exit;
break;
case RPMRC_NOTFOUND: /* Signature/digest not present. */
lvl = RPMLOG_WARNING;
Expand All @@ -307,6 +288,8 @@ static void loghdrmsg(struct rpmsinfo_s *sinfo, struct pkgdata_s *pkgdata,
}

rpmlog(lvl, "%s: %s\n", pkgdata->fn, msg);
exit:
;
}

rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
Expand Down
2 changes: 2 additions & 0 deletions lib/rpmts.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "rpmplugins.hh"
#include "rpmts_internal.hh"
#include "rpmte_internal.hh"
#include "rpmlog_internal.hh"
#include "misc.hh"
#include "rpmtriggers.hh"

Expand Down Expand Up @@ -575,6 +576,7 @@ rpmts rpmtsFree(rpmts ts)
ts->plugins = rpmpluginsFree(ts->plugins);

rpmtriggersFree(ts->trigs2run);
rpmlogReset((uint64_t) ts);

if (_rpmts_stats)
rpmtsPrintStats(ts);
Expand Down
37 changes: 36 additions & 1 deletion rpmio/rpmlog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <mutex>
#include <shared_mutex>
#include <vector>
#include <map>
#include <string>

#include <stdarg.h>
Expand All @@ -22,6 +23,7 @@ struct rpmlogCtx_s {
unsigned mask;
int nrecsPri[RPMLOG_NPRIS];
std::vector<rpmlogRec_s> recs;
std::map<uint64_t, std::map<std::pair<int, std::string>, int>> seen;
rpmlogCallback cbfunc;
rpmlogCallbackData cbdata;
FILE *stdlog;
Expand All @@ -41,7 +43,7 @@ using rdlock = std::shared_lock<std::shared_mutex>;
static rpmlogCtx rpmlogCtxAcquire()
{
static struct rpmlogCtx_s _globalCtx = { RPMLOG_UPTO(RPMLOG_NOTICE),
{0}, {}, NULL, NULL, NULL };
{0}, {}, {}, NULL, NULL, NULL };
return &_globalCtx;
}

Expand Down Expand Up @@ -127,6 +129,7 @@ void rpmlogClose (void)
wrlock lock(ctx->mutex);

ctx->recs.clear();
ctx->seen.clear();
memset(ctx->nrecsPri, 0, sizeof(ctx->nrecsPri));
}

Expand Down Expand Up @@ -412,3 +415,35 @@ void rpmlog (int code, const char *fmt, ...)
exit:
errno = saved_errno;
}

int rpmlogOnce (uint64_t domain, const char * key, int code, const char *fmt, ...)
{
int saved_errno = errno;
rpmlogCtx ctx = rpmlogCtxAcquire();
int newkey = 0;

if (ctx) {
wrlock lock(ctx->mutex);
newkey = !ctx->seen[domain][{code, key}]++;
}

if (newkey) {
va_list ap;
char *msg = NULL;
va_start(ap, fmt);
if (rvasprintf(&msg, fmt, ap) >= 0) {
rpmlog(code, msg);
free(msg);
}
va_end(ap);
}
errno = saved_errno;
return newkey;
}

void rpmlogReset(uint64_t domain, int mode=0)
{
rpmlogCtx ctx = rpmlogCtxAcquire();
wrlock lock(ctx->mutex);
ctx->seen.erase(domain);
}
23 changes: 23 additions & 0 deletions rpmio/rpmlog_internal.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef H_RPMLOG_INTERNAL
#define H_RPMLOG_INTERNAL 1


/** \ingroup rpmlog
* Generate a log message using FMT string and option arguments.
* Only actually log on the first time passing the key value
* @param domain group of messages to be reset together
* @param key key to match log messages together
* @param code rpmlogLvl
* @param fmt format string and parameter to render
* @return 1 if actually logging 0 otherwise
*/
int rpmlogOnce (uint64_t domain, const char * key, int code, const char *fmt, ...) RPM_GNUC_PRINTF(4, 5);

/** \ingroup rpmlog
* Clear memory of logmessages for a given domain
* @param domain group of messages to be reset together
* @param mode curretnly only 0 supported whihc drops everything
*/
void rpmlogReset(uint64_t domain, int mode=0);

#endif

0 comments on commit bf6baaa

Please sign in to comment.