From 7651936f80b1bc6f5b01477ee9e648843097d7b8 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Sun, 4 Feb 2018 10:11:07 +0100 Subject: Rewrite hash table support. * .gitignore: Update. * Makefile.am (EXTRA_DIST): Add perl modules from lib/VarnishMib * lib/VarnishMib/HashTable.pm: New file. * lib/VarnishMib/MIBTable.pm: New file. * src/Makefile.am (varnish_mib_la_SOURCES): Remove statdict. (.mib2c.c): Set PERL5LIB * src/betab.c (backend_dfn.vpt): Remove const qualifier. (backend_register): Store in vpt cloned points. (backend_clear): Destroy points in vpt. * src/statdict.c: Remove. * src/varnish_mib.mib2c: Use VarnishMib::MIBTable. Set mib2c variable $varnish_hash_table to an instance of VarnishMib::MIBTable. Use it to generate lookup table code section. (varnish_var_lookup, varnish_get_oid) (dict_clear, dict_install, dict_load): New functions. (handle_$i): Use direct addressing to obtain a vpt. Fix handling of ASN_TIMETICKS. --- .gitignore | 1 + Makefile.am | 6 +- bootstrap | 40 +++++++- configure.ac | 3 +- lib/VarnishMib/HashTable.pm | 242 ++++++++++++++++++++++++++++++++++++++++++++ lib/VarnishMib/MIBTable.pm | 70 +++++++++++++ lib/prereq.pl | 5 + src/Makefile.am | 5 +- src/betab.c | 7 +- src/statdict.c | 168 ------------------------------ src/varnish_mib.mib2c | 101 ++++++++++++++++-- 11 files changed, 465 insertions(+), 183 deletions(-) create mode 100644 lib/VarnishMib/HashTable.pm create mode 100644 lib/VarnishMib/MIBTable.pm create mode 100644 lib/prereq.pl delete mode 100644 src/statdict.c diff --git a/.gitignore b/.gitignore index 506e185..24dd695 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ core libtool m4 stamp-h1 +_Inline diff --git a/Makefile.am b/Makefile.am index 0334f01..30060d5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,11 @@ # along with varnish-mib. If not, see . ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src -EXTRA_DIST=git2chg.awk +EXTRA_DIST=\ + git2chg.awk\ + lib/prereq.pl\ + lib/VarnishMib/HashTable.pm\ + lib/VarnishMib/MIBTable.pm .PHONY: ChangeLog ChangeLog: diff --git a/bootstrap b/bootstrap index a4a33d4..5717cbc 100755 --- a/bootstrap +++ b/bootstrap @@ -1,4 +1,8 @@ -#!/usr/bin/perl +#!/bin/sh +#! -*-perl-*- +eval 'exec perl -x -wS $0 ${1+"$@"}' + if 0; + use strict; use autodie; @@ -7,6 +11,40 @@ my $mib2c_config = 'src/varnish_mib.mib2c'; die "This file must be run from the varnish-mib top level source directory" unless -r $mib2c_config; +sub vercmp { + my ($va, $vb) = @_; + my @a = split /\./, $va; + my @b = split /\./, $vb; + my $res; + while (defined(my $na = shift @a)) { + return 0 unless $na =~ /^\d+$/; + my $nb = shift @b; + return 1 unless defined($nb); + return 0 unless $nb =~ /^\d+$/; + $res = $na <=> $nb; + last if $res; + } + $res; +} + +if (-f 'lib/prereq.pl') { + print "$0: checking prerequisites\n"; + our @prereq; + do 'lib/prereq.pl'; + + while ((my $pkg = shift @prereq) && defined(my $req = shift @prereq)) { + my $v = eval "require $pkg; \$${pkg}::VERSION"; + if ($@) { + warn "$pkg not installed"; + next; + } + print "$0: $pkg version $v installed\n"; + if ($v && vercmp($v, $req) < 0) { + warn "$pkg: version $v too old (at least $req is required)"; + } + } +} + print "$0: creating ancillary directories and files\n"; foreach my $dir ('m4', 'build-aux') { mkdir($dir) unless -d $dir; diff --git a/configure.ac b/configure.ac index a800774..84544b2 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,8 @@ AC_CONFIG_MACRO_DIR([m4]) AC_CANONICAL_SYSTEM AC_LANG(C) -AM_INIT_AUTOMAKE([gnu tar-ustar]) +AM_INIT_AUTOMAKE([gnu tar-ustar silent-rules]) +AM_SILENT_RULES([yes]) AC_GNU_SOURCE AC_PROG_CC diff --git a/lib/VarnishMib/HashTable.pm b/lib/VarnishMib/HashTable.pm new file mode 100644 index 0000000..0f3b47e --- /dev/null +++ b/lib/VarnishMib/HashTable.pm @@ -0,0 +1,242 @@ +package VarnishMib::HashTable; +use strict; +use warnings; +use Carp; +use Inline 'C'; +use Pod::Usage; +use Pod::Man; + +=head1 NAME + +VarnishMib::HashTable - Create a hash table implementation in C + +=head1 DESCRIPTION + +Given a list of unique strings, creates a C code for fast look ups of +data associated with them. + +=head1 CONSTRUCTOR + + $ht = new VarnishMib::HashTable([KW => VAL,...]); + +Returns a new instance of the hash table generator. Allowed arguments are: + +=over 4 + +=item B + +Maximum number of collisions allowed for the resulting hash table. Default is +unlimited. + +=item B + +Maximum size of the resulting hash table (in items). + +=item B + +Basic indent value for the generated C text. Default is 4. + +=item B + +Produce verbose statistics about the created hash table. + +=item B + +Prefix all C identifiers with this string. Default is C. + +=back + +=cut + +sub new { + my $class = shift; + my $self = bless {}, $class; + my $v; + local %_ = @_; + $self->{max_collisions} = delete $_{max_collisions}; + $self->{max_hash_size} = delete $_{max_hash_size}; + $self->{indent} = ' ' x (delete $_{indent} || 4); + $self->{verbose} = delete $_{verbose}; + $self->{prefix} = delete $_{prefix} || 'ht_'; + croak "extra arguments" if keys %_; + return $self; +} + +=head1 METHODS + +=head2 prefix + + $s = $ht->prefix; + +Returns current prefix value. + +=cut + +sub prefix { shift->{prefix} } + +=head2 indent + + $s = $ht->indent; + +Returns the indent prefix string. I, that it is not the same as the +B parameter passed to the constructor. This method returs a string +filled with appropriate number of whitespace characters, such that it can +be used to produce the requested indentation. + +=cut + +sub indent { shift->{indent} } + +sub hash_string { + my ($self, $string, $hash_size) = @_; + string_hash($string, $hash_size); +} + +sub _mktab { + my ($self, $hash_size) = @_; + my @ht = (-1) x $hash_size; + my $cmax = 0; + for (my $i = 0; $i < @{$self->{input}}; $i++) { + my $h = $self->hash_string($self->{input}[$i], $hash_size); + my $cn = 0; + while ($ht[$h] != -1) { + ++$cn; + return if (++$h >= $hash_size); + } + $ht[$h] = $i; +# print STDERR $self->{input}[$i] . ' => ' . $h ." $i\n"; + $cmax = $cn if $cn > $cmax; + } +# print STDERR "$hash_size $cmax\n"; + $self->{hash_table} = \@ht; + $self->{collisions} = $cmax; + return $self->{hash_table}; +} + +=head2 create + + $success = $ht->create(LISTREF) + +B must be a reference to a list of unique string values. This method +creates a hash table. Returns true on success and undef on failure. + +=cut + +sub create { + my ($self, $names) = @_; + my $htab; + my $hsize; + + $self->{input} = $names; + delete $self->{hash_table}; + + for ($hsize = (2 * @$names + 1);; $hsize++) { + last if $self->{max_hash_size} && $hsize < $self->{max_hash_size}; + $self->_mktab($hsize) or next; + last unless (defined($self->{max_collisions}) + && $self->{collisions} > $self->{max_collisions}); + } + if ($self->{verbose}) { +# print STDERR "Input: " . @$names . "\n"; + if ($self->{hash_table}) { + print STDERR "Table size: " . @{$self->{hash_table}} . "\n"; + print STDERR "Collisions: " . $self->{collisions} . "\n"; + } else { + print STDERR "FAILED\n"; + } + } + return $self->{hash_table}; +} + +sub format_input_table { + my ($self, $fh) = @_; + $fh ||= \*STDOUT; + croak "no input data to format" unless $self->{input}; + print $fh 'char const *' . $self->{prefix} . "name_table[] = {\n"; + foreach my $name (@{$self->{input}}) { + printf $fh $self->{indent} . '"' . $name . "\",\n"; + } + print $fh "};\n"; + +} + +sub format_data_table { + my ($self, $type, $fh) = @_; + $fh ||= \*STDOUT; + croak "no data to format" unless $self->{input}; + my $n = @{$self->{input}}; + print $fh $type . ' ' . $self->{prefix} . "data_table[$n];\n"; +} + +sub format_hash_table { + my ($self, $fh) = @_; + $fh ||= \*STDOUT; + croak "no hash table to format" unless $self->{hash_table}; + print $fh "static int ".$self->{prefix}."hash_table[] = {\n"; + my $col = 0; + print $fh $self->{indent}; + foreach my $p (@{$self->{hash_table}}) { + printf $fh "%3d,", defined($p) ? $p : -1; + $col++; + print $fh ($col % 10 == 0) ? "\n".$self->{indent} : ' '; + } + print $fh "\n" if ($col % 10); + print $fh "};\n"; + my $pfx = $self->{prefix} . 'hash_table'; + print $fh "unsigned ${pfx}_size = sizeof($pfx) / sizeof(${pfx}[0]);\n"; +} + +sub format_code { + my ($self, $fh) = @_; + $fh ||= \*STDOUT; + seek DATA, 0, 0; + my $visible = 0; + while () { + if (/^__C__$/) { + $visible = 1; + } elsif ($visible) { + s{/\*\s*STATIC\s*\*/}{static}; + print $fh "$_"; + } + } +} + +sub format_program { + my ($self, $type, $fh) = @_; + $fh ||= \*STDOUT; + $self->format_input_table($fh); + print $fh "\n"; + $self->format_data_table($type, $fh); + print $fh "\n"; + $self->format_hash_table($fh); + print $fh "\n"; + $self->format_code($fh); +} + +Inline->init(); +1; +__DATA__ +__C__ +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif +#ifndef UINT_MAX +# define UINT_MAX ((unsigned)-1) +#endif + +static inline unsigned +rotl_sz(unsigned x, int n) +{ + return ((x << n) | (x >> ((CHAR_BIT * sizeof x) - n))) & UINT_MAX; +} + +/*STATIC*/ unsigned +string_hash(const char *str, unsigned size) +{ + unsigned value = 0; + unsigned char ch; + + for (; (ch = *str); str++) + value = ch + rotl_sz(value, 7); + return value % size; +} diff --git a/lib/VarnishMib/MIBTable.pm b/lib/VarnishMib/MIBTable.pm new file mode 100644 index 0000000..6aa959f --- /dev/null +++ b/lib/VarnishMib/MIBTable.pm @@ -0,0 +1,70 @@ +package VarnishMib::MIBTable; +use strict; +use warnings; +use parent 'VarnishMib::HashTable'; +use Carp; + +sub new { + my ($class, $type, $table, %args) = @_; + my @oids = + sort { $table->{$a}[1] cmp $table->{$b}[1] } + grep { $table->{$_}[0] eq 'DICT' } keys %{$table}; + + my @equiv; + my @uniq_oids; + for (my $i = 0; $i <= $#oids; $i++) { + unless ($i > 0 + && $table->{$uniq_oids[-1]}[1] eq $table->{$oids[$i]}[1]) { + push @uniq_oids, $oids[$i]; + } + push @equiv, $#uniq_oids; + } + my $self = bless $class->SUPER::new(%args), $class; + $self->{oids_all} = \@oids; + $self->{oids_uniq} = \@uniq_oids; + $self->{equiv} = \@equiv; + $self->{type} = $type; + + $self->create([map { $table->{$_}[1] } @{$self->{oids_uniq}}]); + return $self; +} + +sub format_oids { + my ($self, $fh) = @_; + $fh ||= \*STDOUT; + + print $fh "enum ".$self->prefix."oid {\n"; + for (my $i = 0; $i <= $#{$self->{oids_all}}; $i++) { + print $fh $self->indent . $self->{oids_all}[$i]; + if ($i > 0 + && $self->{oids_all}[$i] ne $self->{oids_uniq}[$self->{equiv}[$i]]) { + print $fh ' = ' . $self->{oids_uniq}[$self->{equiv}[$i]]; + } + print $fh ",\n"; + } + print $fh $self->indent . 'MAX_' . uc($self->prefix) . "OID\n"; + print $fh "};\n\n"; +} + +sub format_program { + my ($self, $fh) = @_; + $fh ||= \*STDOUT; + $self->format_oids($fh); + $self->SUPER::format_program($self->{type}, $fh); +} + +sub str { + my $self = shift; + my $str; + open(my $fh, '>', \$str) or croak "can't write to string"; + $self->format_program($fh); + close $fh; + return $str; +}; + +use overload '""' => \&str; + +1; + + + diff --git a/lib/prereq.pl b/lib/prereq.pl new file mode 100644 index 0000000..a1e9e2d --- /dev/null +++ b/lib/prereq.pl @@ -0,0 +1,5 @@ +@prereq = ( + 'Inline::C' => 0, + 'Pod::Usage' => 0, + 'Pod::Man' => 0 +); diff --git a/src/Makefile.am b/src/Makefile.am index 3ef9fa5..55cdb85 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,7 +27,6 @@ varnish_mib_la_SOURCES = \ modconf.c\ sha256.c\ sha256.h\ - statdict.c\ varnish_mib.c\ varnish_mib.h\ vcli.c\ @@ -40,7 +39,9 @@ BUILT_SOURCES = \ varnish_mib.c varnish_mib.h: varnish_mib.mib2c VARNISH-MIB.txt .mib2c.c: - MIBDIRS=${top_srcdir}/src:${NET_SNMP_MIBDIRS} MIBS="VARNISH-MIB:${NET_SNMP_MIBS}" \ + MIBDIRS=${top_srcdir}/src:${NET_SNMP_MIBDIRS}\ + MIBS="VARNISH-MIB:${NET_SNMP_MIBS}" \ + PERL5LIB=${top_srcdir}/lib \ mib2c -c $< -f $@ varnish #NET_SNMP_INCLUDES = `$(NET_SNMP_CONFIG) --cflags` diff --git a/src/betab.c b/src/betab.c index afec48a..2979f8b 100644 --- a/src/betab.c +++ b/src/betab.c @@ -79,7 +79,7 @@ struct backend_dfn { size_t vbeIPv6_len; u_long vbePort; - const struct VSC_point *vpt[VBE_MAX]; + struct VSC_point *vpt[VBE_MAX]; VTAILQ_ENTRY(backend_dfn) list; }; @@ -92,6 +92,9 @@ backend_clear(void) { while (!VTAILQ_EMPTY(&backends)) { struct backend_dfn *dfn = VTAILQ_FIRST(&backends); + int i; + for (i = 0; i < VBE_MAX; i++) + VSC_Destroy_Point(&dfn->vpt[i]); VTAILQ_REMOVE(&backends, dfn, list); free(dfn->vbeIdent); SNMP_FREE(dfn); @@ -124,7 +127,7 @@ backend_register(char const *name, size_t len, char const *param, } for (i = 0; betab_trans[i].param; i++) { if (strcmp(betab_trans[i].param, param) == 0) { - dfn->vpt[i] = vpt; + dfn->vpt[i] = VSC_Clone_Point(vpt); break; } } diff --git a/src/statdict.c b/src/statdict.c deleted file mode 100644 index 69b442f..0000000 --- a/src/statdict.c +++ /dev/null @@ -1,168 +0,0 @@ -/* This file is part of varnish-mib - Copyright (C) 2018 Sergey Poznyakoff - - Varnish-mib is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - Varnish-mib 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with varnish-mib. If not, see . -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "backend.h" - -static size_t hash_size[] = { - 7, 17, 37, 101, 229, 487, 1009, 2039, 4091, 8191, 16411 -}; -static size_t hash_num = 0; -static struct VSC_point **dict; - -#define SIZE_T_MAX ((size_t)-1) - -static inline size_t -rotl(size_t x, int n) -{ - return ((x << n) | (x >> ((CHAR_BIT * sizeof x) - n))) & SIZE_T_MAX; -} - -static size_t -hash(const char *str) -{ - size_t value = 0; - unsigned char ch; - - while ((ch = *str++)) - value = ch + rotl(value, 7); - return value % hash_size[hash_num]; -} - -struct VSC_point **lookup(const char *name, int install); - -static void -rehash(void) -{ - struct VSC_point **old_dict = dict; - size_t old_size = hash_size[hash_num]; - size_t i; - - ++hash_num; - AN(hash_num < sizeof(hash_size) / sizeof(hash_size[0])); - dict = calloc(hash_size[hash_num], sizeof(dict[0])); - AN(dict); - - for (i = 0; i < old_size; i++) { - if (old_dict[i]) - *lookup(old_dict[i]->name, 1) = old_dict[i]; - } - free(old_dict); -} - -struct VSC_point ** -lookup(const char *name, int install) -{ - size_t i, pos; - - if (!dict) { - if (install) { - dict = calloc(hash_size[hash_num], sizeof(dict[0])); - AN(dict); - } else - return NULL; - } - - pos = hash(name); - - for (i = pos; dict[i];) { - if (strcmp(dict[i]->name, name) == 0) { - return &dict[i]; - } - - if (++i >= hash_size[hash_num]) - i = 0; - if (i == pos) - break; - } - - if (!install) - return NULL; - - if (!dict[i]) - return &dict[i]; - - rehash(); - return lookup(name, install); -} - -int -dict_lookup(char const *key, uint64_t *val) -{ - struct VSC_point **ent; - - ent = lookup(key, 0); - if (!ent) - return -1; - *val = *(uint64_t*)(*ent)->ptr; - return 0; -} - -void -dict_clear(void) -{ - if (dict) { - size_t i; - for (i = 0; i < hash_size[hash_num]; i++) - if (dict[i]) - VSC_Destroy_Point(&dict[i]); - } -} - -struct VSC_point const * -dict_install(struct VSC_point const *pt) -{ - struct VSC_point **ent; - - ent = lookup(pt->name, 1); - AN(ent); - if (*ent) - VSC_Destroy_Point(ent); - *ent = VSC_Clone_Point(pt); - return *ent; -} - -static int -load_cb(void *priv, const struct VSC_point *vpt) -{ - AZ(strcmp(vpt->ctype, "uint64_t")); - vpt = dict_install(vpt); - if (strncmp(vpt->name, "VBE.", 4) == 0) { - char const *name = vpt->name + 4; - char *p = strrchr(name, '.'); - if (p) { - backend_register(name, p - name, p + 1, vpt); - } - } - return 0; -} - -void -dict_load(struct vsc *vsc) -{ - struct vsm_fantom fantom = VSM_FANTOM_NULL; - dict_clear(); - backend_clear(); - VSC_Iter(vsc, &fantom, load_cb, NULL); -} diff --git a/src/varnish_mib.mib2c b/src/varnish_mib.mib2c index 7084476..2b12090 100644 --- a/src/varnish_mib.mib2c +++ b/src/varnish_mib.mib2c @@ -24,6 +24,8 @@ */ @enddefine@ @startperl@ +use VarnishMib::MIBTable; + $vars{'varnish_translate_table'} = { uptime => [ DICT => 'MAIN.uptime' ], clientAcceptedConnections => [ DICT => 'MAIN.sess_conn' ], @@ -96,7 +98,7 @@ $vars{'varnish_translate_table'} = { bansLurkerObjKilled => [ DICT => 'MAIN.bans_lurker_obj_killed' ], bansDups => [ DICT => 'MAIN.bans_dups' ], bansLurkerContention => [ DICT => 'MAIN.bans_lurker_contention' ], - bansPersistedBytes => [ DICT => 'MAIN.bans_persisted_bytes' ], + bansPersistedBytes => [ DICT => 'MAIN.bans_persisted_bytes' ], bansPersistedFragmentation => [ DICT => 'MAIN.bans_persisted_fragmentation' ], objectsCount => [ DICT => 'MAIN.n_object' ], @@ -117,6 +119,12 @@ $vars{'varnish_translate_table'} = { vclFail => [ DICT => 'MAIN.vcl_fail' ], }; +$vars{'varnish_hash_table'} = new VarnishMib::MIBTable( + 'struct VSC_point *', + $vars{'varnish_translate_table'}, + prefix => 'vmib_', max_collisions => 0 + ); + my @reset_names; $vars{'varnish_translate'} = sub { @@ -155,12 +163,11 @@ $vars{'set_field_dim'} = sub { $vars{'modulename'} = $vars{'name'}; $vars{'modulename'} =~ s#.*/##; $vars{'modulename'} =~ s/\.c$//; -#print "$vars{'modulename'}\n"; - 0; @endperl@ @open ${modulename}.h@ /* THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT. */ + #include #include #include @@ -189,10 +196,6 @@ int varnish_ban(netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests, struct vsm *vsm); -int dict_lookup(char const *key, uint64_t *val); -void dict_install(struct VSC_point const *pt); -void dict_load(struct vsc *vsc); - @open ${name}@ /* THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT. */ @@ -202,6 +205,8 @@ void dict_load(struct vsc *vsc); static struct vsm *vd; static struct vsc *vsc; +static void dict_load(struct vsc *vsc); + int post_config(int majorID, int minorID, void *serverarg, void *clientarg) { @@ -253,6 +258,80 @@ varnish_get_vsm_data(void) return vd; } +${varnish_hash_table} + +static struct VSC_point ** +varnish_var_lookup(char const *str) +{ + if (str) { + int i, h; + + h = string_hash(str, vmib_hash_table_size); + i = h; + while (vmib_hash_table[i] != -1) { + if (strcmp(vmib_name_table[vmib_hash_table[i]], str) == 0) + return &vmib_data_table[vmib_hash_table[i]]; + i = (i + 1) % vmib_hash_table_size; + if (i == h) + break; + } + } + return NULL; +} + +static inline struct VSC_point * +varnish_get_oid(int i) +{ + return vmib_data_table[i]; +} + +static void +dict_clear(void) +{ + int i; + for (i = 0; i < MAX_VMIB_OID; i++) + if (vmib_data_table[i]) + VSC_Destroy_Point(&vmib_data_table[i]); +} + +static struct VSC_point const * +dict_install(struct VSC_point const *pt) +{ + struct VSC_point **ent; + + ent = varnish_var_lookup(pt->name); + if (!ent) + return NULL; + if (*ent) + VSC_Destroy_Point(ent); + *ent = VSC_Clone_Point(pt); + return *ent; +} + +static int +load_cb(void *priv, const struct VSC_point *vpt) +{ + AZ(strcmp(vpt->ctype, "uint64_t")); + if (strncmp(vpt->name, "VBE.", 4) == 0) { + char const *name = vpt->name + 4; + char *p = strrchr(name, '.'); + if (p) { + backend_register(name, p - name, p + 1, vpt); + } + } + vpt = dict_install(vpt); + return 0; +} + +static void +dict_load(struct vsc *vsc) +{ + struct vsm_fantom fantom = VSM_FANTOM_NULL; + dict_clear(); + backend_clear(); + VSC_Iter(vsc, &fantom, load_cb, NULL); +} + /* Variable handlers. An instance handler only hands us one request at a time, unwrapping @@ -282,9 +361,12 @@ handle_$i(netsnmp_mib_handler *handler, case MODE_GET: @if $varnish_type eq 'DICT'@ { + struct VSC_point *ent = varnish_get_oid($i); uint64_t val; - if (dict_lookup("$varnish_member", &val)) + + if (!ent) return SNMP_ERR_NOSUCHNAME; + val = *(uint64_t*)ent->ptr; @if $i.type eq 'ASN_COUNTER64'@ { struct counter64 ctr; @@ -295,6 +377,9 @@ handle_$i(netsnmp_mib_handler *handler, sizeof(ctr)); } @else@ + @if $i.type eq 'ASN_TIMETICKS'@ + val *= 100; + @end@ snmp_set_var_typed_value(requests->requestvb, $i.type, &val, sizeof(val)); -- cgit v1.2.1