varnish-cache/bin/varnishd/mgt/mgt_param_bits.c
1
/*-
2
 * Copyright (c) 2006 Verdens Gang AS
3
 * Copyright (c) 2006-2011 Varnish Software AS
4
 * All rights reserved.
5
 *
6
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29
30
#include "config.h"
31
32
#include <string.h>
33
34
#include "mgt/mgt.h"
35
#include "mgt/mgt_param.h"
36
37
#include "vav.h"
38
39
#include "vsl_priv.h"
40
41
/*--------------------------------------------------------------------
42
 */
43
44
enum bit_do {BSET, BCLR, BTST};
45
46
static int
47 4494690
bit(uint8_t *p, unsigned no, enum bit_do act)
48
{
49
        uint8_t b;
50
51 4494690
        p += (no >> 3);
52 4494690
        b = (0x80 >> (no & 7));
53 4494690
        if (act == BSET)
54 208422
                *p |= b;
55 4286268
        else if (act == BCLR)
56 13716
                *p &= ~b;
57 4494690
        return (*p & b);
58
}
59
60
/*--------------------------------------------------------------------
61
 */
62
63
static int
64 30204
bit_tweak(struct vsb *vsb, uint8_t *p, unsigned l, const char *arg,
65
    const char * const *tags, const char *desc, const char *sign)
66
{
67
        int i, n;
68
        unsigned j;
69
        char **av;
70
        const char *s;
71
72 30204
        av = VAV_Parse(arg, &n, ARGV_COMMA);
73 30204
        if (av[0] != NULL) {
74 18
                VSB_printf(vsb, "Cannot parse: %s\n", av[0]);
75 18
                VAV_Free(av);
76 18
                return (-1);
77
        }
78 60444
        for (i = 1; av[i] != NULL; i++) {
79 30294
                s = av[i];
80 30294
                if (*s != '-' && *s != '+') {
81 18
                        VSB_printf(vsb, "Missing '+' or '-' (%s)\n", s);
82 18
                        VAV_Free(av);
83 18
                        return (-1);
84
                }
85 206478
                for (j = 0; j < l; j++) {
86 206460
                        if (tags[j] != NULL && !strcasecmp(s + 1, tags[j]))
87 30258
                                break;
88 176202
                }
89 30276
                if (tags[j] == NULL) {
90 18
                        VSB_printf(vsb, "Unknown %s (%s)\n", desc, s);
91 18
                        VAV_Free(av);
92 18
                        return (-1);
93
                }
94 30258
                assert(j < l);
95 30258
                if (s[0] == *sign)
96 16542
                        (void)bit(p, j, BSET);
97
                else
98 13716
                        (void)bit(p, j, BCLR);
99 30258
        }
100 30150
        VAV_Free(av);
101 30150
        return (0);
102 30204
}
103
104
105
/*--------------------------------------------------------------------
106
 * The vsl_mask parameter
107
 */
108
109
static const char * const VSL_tags[256] = {
110
#  define SLTM(foo,flags,sdesc,ldesc) [SLT_##foo] = #foo,
111
#  include "tbl/vsl_tags.h"
112
        NULL
113
};
114
115
static int
116 43434
tweak_vsl_mask(struct vsb *vsb, const struct parspec *par, const char *arg)
117
{
118
        unsigned j;
119
        const char *s;
120 43434
        (void)par;
121
122 43434
        if (arg != NULL && arg != JSON_FMT) {
123 28386
                if (!strcmp(arg, "default")) {
124 14760
                        memset(mgt_param.vsl_mask,
125
                            0, sizeof mgt_param.vsl_mask);
126 14760
                        (void)bit(mgt_param.vsl_mask, SLT_VCL_trace, BSET);
127 14760
                        (void)bit(mgt_param.vsl_mask, SLT_WorkThread, BSET);
128 14760
                        (void)bit(mgt_param.vsl_mask, SLT_Hash, BSET);
129 14760
                        (void)bit(mgt_param.vsl_mask, SLT_VfpAcct, BSET);
130 14760
                        (void)bit(mgt_param.vsl_mask, SLT_H2TxBody, BSET);
131 14760
                        (void)bit(mgt_param.vsl_mask, SLT_H2TxHdr, BSET);
132 14760
                        (void)bit(mgt_param.vsl_mask, SLT_H2RxBody, BSET);
133 14760
                        (void)bit(mgt_param.vsl_mask, SLT_H2RxHdr, BSET);
134 14760
                        (void)bit(mgt_param.vsl_mask, SLT_ObjHeader, BSET);
135 14760
                        (void)bit(mgt_param.vsl_mask, SLT_ObjProtocol, BSET);
136 14760
                        (void)bit(mgt_param.vsl_mask, SLT_ObjReason, BSET);
137 14760
                        (void)bit(mgt_param.vsl_mask, SLT_ObjStatus, BSET);
138 14760
                        (void)bit(mgt_param.vsl_mask, SLT_Debug, BSET);
139 14760
                } else {
140 27252
                        return (bit_tweak(vsb, mgt_param.vsl_mask,
141 13626
                            SLT__Reserved, arg, VSL_tags,
142
                            "VSL tag", "-"));
143
                }
144 14760
        } else {
145 15048
                if (arg == JSON_FMT)
146 36
                        VSB_putc(vsb, '"');
147 15048
                s = "";
148 3837240
                for (j = 0; j < (unsigned)SLT__Reserved; j++) {
149 3822192
                        if (bit(mgt_param.vsl_mask, j, BTST)) {
150 195264
                                VSB_printf(vsb, "%s-%s", s, VSL_tags[j]);
151 195264
                                s = ",";
152 195264
                        }
153 3822192
                }
154 15048
                if (*s == '\0')
155 0
                        VSB_printf(vsb, "(all enabled)");
156 15048
                if (arg == JSON_FMT)
157 36
                        VSB_putc(vsb, '"');
158
        }
159 29808
        return (0);
160 43434
}
161
162
/*--------------------------------------------------------------------
163
 * The debug parameter
164
 */
165
166
static const char * const debug_tags[] = {
167
#  define DEBUG_BIT(U, l, d) [DBG_##U] = #l,
168
#  include "tbl/debug_bits.h"
169
       NULL
170
};
171
172
static int
173 45000
tweak_debug(struct vsb *vsb, const struct parspec *par, const char *arg)
174
{
175
        const char *s;
176
        unsigned j;
177 45000
        (void)par;
178
179 45000
        if (arg != NULL && arg != JSON_FMT) {
180 29988
                if (!strcmp(arg, "none")) {
181 14760
                        memset(mgt_param.debug_bits,
182
                            0, sizeof mgt_param.debug_bits);
183 14760
                } else {
184 30456
                        return (bit_tweak(vsb, mgt_param.debug_bits,
185 15228
                            DBG_Reserved, arg, debug_tags, "debug bit", "+"));
186
                }
187 14760
        } else {
188 15012
                if (arg == JSON_FMT)
189 36
                        VSB_putc(vsb, '"');
190 15012
                s = "";
191 315252
                for (j = 0; j < (unsigned)DBG_Reserved; j++) {
192 300240
                        if (bit(mgt_param.debug_bits, j, BTST)) {
193 306
                                VSB_printf(vsb, "%s+%s", s, debug_tags[j]);
194 306
                                s = ",";
195 306
                        }
196 300240
                }
197 15012
                if (*s == '\0')
198 14760
                        VSB_printf(vsb, "none");
199 15012
                if (arg == JSON_FMT)
200 36
                        VSB_putc(vsb, '"');
201
        }
202 29772
        return (0);
203 45000
}
204
205
/*--------------------------------------------------------------------
206
 * The feature parameter
207
 */
208
209
static const char * const feature_tags[] = {
210
#  define FEATURE_BIT(U, l, d, ld) [FEATURE_##U] = #l,
211
#  include "tbl/feature_bits.h"
212
       NULL
213
};
214
215
static int
216 31122
tweak_feature(struct vsb *vsb, const struct parspec *par, const char *arg)
217
{
218
        const char *s;
219
        unsigned j;
220 31122
        (void)par;
221
222 31122
        if (arg != NULL && arg != JSON_FMT) {
223 16110
                if (!strcmp(arg, "none")) {
224 14760
                        memset(mgt_param.feature_bits,
225
                            0, sizeof mgt_param.feature_bits);
226 14760
                } else {
227 2700
                        return (bit_tweak(vsb, mgt_param.feature_bits,
228 1350
                            FEATURE_Reserved, arg, feature_tags,
229
                            "feature bit", "+"));
230
                }
231 14760
        } else {
232 15012
                if (arg == JSON_FMT)
233 36
                        VSB_putc(vsb, '"');
234 15012
                s = "";
235 165132
                for (j = 0; j < (unsigned)FEATURE_Reserved; j++) {
236 150120
                        if (bit(mgt_param.feature_bits, j, BTST)) {
237 18
                                VSB_printf(vsb, "%s+%s", s, feature_tags[j]);
238 18
                                s = ",";
239 18
                        }
240 150120
                }
241 15012
                if (*s == '\0')
242 14994
                        VSB_printf(vsb, "none");
243 15012
                if (arg == JSON_FMT)
244 36
                        VSB_putc(vsb, '"');
245
        }
246 29772
        return (0);
247 31122
}
248
249
/*--------------------------------------------------------------------
250
 * The parameter table itself
251
 */
252
253
struct parspec VSL_parspec[] = {
254
        { "vsl_mask", tweak_vsl_mask, NULL, NULL, NULL,
255
                "Mask individual VSL messages from being logged.\n"
256
                "\tdefault\tSet default value\n"
257
                "\nUse +/- prefix in front of VSL tag name, to mask/unmask "
258
                "individual VSL messages.",
259
                0, "default", "" },
260
        { "debug", tweak_debug, NULL, NULL, NULL,
261
                "Enable/Disable various kinds of debugging.\n"
262
                "\tnone\tDisable all debugging\n\n"
263
                "Use +/- prefix to set/reset individual bits:"
264
#define DEBUG_BIT(U, l, d) "\n\t" #l "\t" d
265
#include "tbl/debug_bits.h"
266
#undef DEBUG_BIT
267
                , 0, "none", "" },
268
        { "feature", tweak_feature, NULL, NULL, NULL,
269
                "Enable/Disable various minor features.\n"
270
                "\tnone\tDisable all features.\n\n"
271
                "Use +/- prefix to enable/disable individual feature:"
272
#define FEATURE_BIT(U, l, d, ld) "\n\t" #l "\t" d
273
#include "tbl/feature_bits.h"
274
#undef FEATURE_BIT
275
                , 0, "none", "" },
276
        { NULL, NULL, NULL }
277
};