Browse Source

[Feature] Rework RRD ds count, add conversion path

tags/1.5.0
Vsevolod Stakhov 7 years ago
parent
commit
e5a9a22481
1 changed files with 157 additions and 37 deletions
  1. 157
    37
      src/libutil/rrd.c

+ 157
- 37
src/libutil/rrd.c View File

@@ -21,6 +21,10 @@
#include "cryptobox.h"
#include <math.h>

#define RSPAMD_RRD_DS_COUNT METRIC_ACTION_MAX
#define RSPAMD_RRD_OLD_DS_COUNT 4
#define RSPAMD_RRD_RRA_COUNT 4

#define msg_err_rrd(...) rspamd_default_log_function (G_LOG_LEVEL_CRITICAL, \
"rrd", file->id, \
G_STRFUNC, \
@@ -1266,54 +1270,31 @@ rspamd_rrd_close (struct rspamd_rrd_file * file)
return 0;
}

struct rspamd_rrd_file *
rspamd_rrd_file_default (const gchar *path,
GError **err)
static struct rspamd_rrd_file *
rspamd_rrd_create_file (const gchar *path, gboolean finalize, GError **err)
{
struct rspamd_rrd_file *file;
struct rrd_ds_def ds[4];
struct rrd_rra_def rra[4];
struct rrd_ds_def ds[RSPAMD_RRD_DS_COUNT];
struct rrd_rra_def rra[RSPAMD_RRD_RRA_COUNT];
gint i;
GArray ar;

g_assert (path != NULL);

if (access (path, R_OK) != -1) {
/* We can open rrd file */
file = rspamd_rrd_open (path, err);

if (file == NULL) {
return NULL;
}


if (file->stat_head->ds_cnt != 4 || file->stat_head->rra_cnt != 4) {
msg_err_rrd ("rrd file is not suitable for rspamd: it has "
"%ul ds and %ul rra", file->stat_head->ds_cnt,
file->stat_head->rra_cnt);
g_set_error (err, rrd_error_quark (), EINVAL, "bad rrd file");
rspamd_rrd_close (file);

return NULL;
}

return file;
}

/* Try to create new rrd file */

file = rspamd_rrd_create (path, 4, 4, 1, rspamd_get_calendar_ticks (), err);
file = rspamd_rrd_create (path, RSPAMD_RRD_DS_COUNT, RSPAMD_RRD_RRA_COUNT,
1, rspamd_get_calendar_ticks (), err);

if (file == NULL) {
return NULL;
}

/* Create DS and RRA */
rrd_make_default_ds ("spam", rrd_dst_to_string (RRD_DST_COUNTER), 1, &ds[0]);
rrd_make_default_ds ("probable", rrd_dst_to_string (RRD_DST_COUNTER), 1,
&ds[1]);
rrd_make_default_ds ("greylist", rrd_dst_to_string (RRD_DST_COUNTER), 1,
&ds[2]);
rrd_make_default_ds ("ham", rrd_dst_to_string (RRD_DST_COUNTER), 1, &ds[3]);

for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
rrd_make_default_ds (rspamd_action_to_str (i),
rrd_dst_to_string (RRD_DST_COUNTER), 1, &ds[i]);
}

ar.data = (gchar *)ds;
ar.len = sizeof (ds);

@@ -1342,7 +1323,7 @@ rspamd_rrd_file_default (const gchar *path,
return NULL;
}

if (!rspamd_rrd_finalize (file, err)) {
if (finalize && !rspamd_rrd_finalize (file, err)) {
rspamd_rrd_close (file);
return NULL;
}
@@ -1350,6 +1331,145 @@ rspamd_rrd_file_default (const gchar *path,
return file;
}

static void
rspamd_rrd_convert_ds (struct rspamd_rrd_file *old,
struct rspamd_rrd_file *cur, gint idx_old, gint idx_new)
{
struct rrd_pdp_prep *pdp_prep_old, *pdp_prep_new;
struct rrd_cdp_prep *cdp_prep_old, *cdp_prep_new;
gdouble *val_old, *val_new;
gulong rra_cnt, i, j, points_cnt, old_ds, new_ds;

rra_cnt = old->stat_head->rra_cnt;
pdp_prep_old = &old->pdp_prep[idx_old];
pdp_prep_new = &cur->pdp_prep[idx_new];
memcpy (pdp_prep_new, pdp_prep_old, sizeof (*pdp_prep_new));
memcpy (&old->rra_ptr[idx_old], &cur->rra_ptr[idx_new], sizeof (*old->rra_ptr));
val_old = old->rrd_value;
val_new = cur->rrd_value;
old_ds = old->stat_head->ds_cnt;
new_ds = cur->stat_head->ds_cnt;

for (i = 0; i < rra_cnt; i++) {
cdp_prep_old = &old->cdp_prep[i] + idx_old;
cdp_prep_new = &cur->cdp_prep[i] + idx_new;
memcpy (cdp_prep_new, cdp_prep_old, sizeof (*cdp_prep_new));
points_cnt = old->rra_def[i].row_cnt;

for (j = 0; j < points_cnt; j ++) {
val_new[j * new_ds + idx_new] = val_old[j * old_ds + idx_old];
}

val_new += points_cnt * new_ds;
val_old += points_cnt * old_ds;
}
}

static struct rspamd_rrd_file *
rspamd_rrd_convert (const gchar *path, struct rspamd_rrd_file *old,
GError **err)
{
struct rspamd_rrd_file *rrd;
gchar tpath[PATH_MAX];

g_assert (old != NULL);

rspamd_snprintf (tpath, sizeof (tpath), "%s.new", path);
rrd = rspamd_rrd_create_file (tpath, TRUE, err);

if (rrd) {
/* Copy old data */
memcpy (rrd->live_head, old->live_head, sizeof (*rrd->live_head));

/*
* Old DSes:
* 0 - spam -> reject
* 1 - probable spam -> add header
* 2 - greylist -> greylist
* 3 - ham -> ham
*/
rspamd_rrd_convert_ds (old, rrd, 0, METRIC_ACTION_REJECT);
rspamd_rrd_convert_ds (old, rrd, 1, METRIC_ACTION_ADD_HEADER);
rspamd_rrd_convert_ds (old, rrd, 2, METRIC_ACTION_GREYLIST);
rspamd_rrd_convert_ds (old, rrd, 3, METRIC_ACTION_NOACTION);

if (unlink (path) == -1) {
g_set_error (err, rrd_error_quark (), errno, "cannot unlink old rrd file %s: %s",
path, strerror (errno));
unlink (tpath);
rspamd_rrd_close (rrd);

return NULL;
}

if (rename (tpath, path) == -1) {
g_set_error (err, rrd_error_quark (), errno, "cannot rename old rrd file %s: %s",
path, strerror (errno));
unlink (tpath);
rspamd_rrd_close (rrd);

return NULL;
}
}

return rrd;
}

struct rspamd_rrd_file *
rspamd_rrd_file_default (const gchar *path,
GError **err)
{
struct rspamd_rrd_file *file, *nf;

g_assert (path != NULL);

if (access (path, R_OK) != -1) {
/* We can open rrd file */
file = rspamd_rrd_open (path, err);

if (file == NULL) {
return NULL;
}


if (file->stat_head->rra_cnt != RSPAMD_RRD_RRA_COUNT) {
msg_err_rrd ("rrd file is not suitable for rspamd: it has "
"%ul ds and %ul rra", file->stat_head->ds_cnt,
file->stat_head->rra_cnt);
g_set_error (err, rrd_error_quark (), EINVAL, "bad rrd file");
rspamd_rrd_close (file);

return NULL;
}
else if (file->stat_head->ds_cnt == RSPAMD_RRD_OLD_DS_COUNT) {
/* Old rrd, need to convert */
msg_info_rrd ("rrd file %s is not suitable for rspamd, convert it",
path);

nf = rspamd_rrd_convert (path, file, err);
rspamd_rrd_close (file);

return nf;
}
else if (file->stat_head->ds_cnt == RSPAMD_RRD_DS_COUNT) {
return file;
}
else {
msg_err_rrd ("rrd file is not suitable for rspamd: it has "
"%ul ds and %ul rra", file->stat_head->ds_cnt,
file->stat_head->rra_cnt);
g_set_error (err, rrd_error_quark (), EINVAL, "bad rrd file");
rspamd_rrd_close (file);

return NULL;
}
}

file = rspamd_rrd_create_file (path, TRUE, err);

return file;
}

struct rspamd_rrd_query_result *
rspamd_rrd_query (struct rspamd_rrd_file *file,
gulong rra_num)

Loading…
Cancel
Save