journald-rate-limit.c revision b26fa1a2fbcfee7d03b0c8fd15ec3aa64ae70b9f
/***
This file is part of systemd.
Copyright 2011 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <errno.h>
#include <string.h>
#include "alloc-util.h"
#include "hashmap.h"
#include "journald-rate-limit.h"
#include "list.h"
#include "random-util.h"
#include "string-util.h"
#include "util.h"
#define POOLS_MAX 5
#define BUCKETS_MAX 127
#define GROUPS_MAX 2047
static const int priority_map[] = {
[LOG_EMERG] = 0,
[LOG_ALERT] = 0,
[LOG_CRIT] = 0,
[LOG_ERR] = 1,
[LOG_WARNING] = 2,
[LOG_NOTICE] = 3,
[LOG_INFO] = 3,
[LOG_DEBUG] = 4
};
typedef struct JournalRateLimitPool JournalRateLimitPool;
typedef struct JournalRateLimitGroup JournalRateLimitGroup;
struct JournalRateLimitPool {
unsigned num;
unsigned suppressed;
};
struct JournalRateLimitGroup {
char *id;
};
struct JournalRateLimit {
unsigned burst;
unsigned n_groups;
};
JournalRateLimit *r;
if (!r)
return NULL;
return r;
}
static void journal_rate_limit_group_free(JournalRateLimitGroup *g) {
assert(g);
if (g->parent) {
}
free(g);
}
void journal_rate_limit_free(JournalRateLimit *r) {
assert(r);
while (r->lru)
free(r);
}
unsigned i;
assert(g);
for (i = 0; i < POOLS_MAX; i++)
return false;
return true;
}
assert(r);
/* Makes room for at least one new item, but drop all
* expored items too. */
while (r->n_groups >= GROUPS_MAX ||
}
static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t ts) {
assert(r);
if (!g)
return NULL;
if (!g->id)
goto fail;
if (!g->lru_next)
r->lru_tail = g;
r->n_groups ++;
g->parent = r;
return g;
fail:
return NULL;
}
unsigned k;
/* Modulates the burst rate a bit with the amount of available
* disk space */
/* 1MB */
if (k <= 20)
return burst;
/*
* Example:
*
* <= 1MB = rate * 1
* 16MB = rate * 2
* 256MB = rate * 3
* 4GB = rate * 4
* 64GB = rate * 5
* 1TB = rate * 6
*/
return burst;
}
int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) {
uint64_t h;
unsigned burst;
if (!r)
return 1;
return 1;
h = siphash24_finalize(&state);
g = r->buckets[h % BUCKETS_MAX];
LIST_FOREACH(bucket, g, g)
break;
if (!g) {
if (!g)
return -ENOMEM;
}
if (p->begin <= 0) {
p->suppressed = 0;
p->num = 1;
return 1;
}
unsigned s;
s = p->suppressed;
p->suppressed = 0;
p->num = 1;
return 1 + s;
}
p->num++;
return 1;
}
p->suppressed++;
return 0;
}