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 1190550
bit(uint8_t *p, unsigned no, enum bit_do act)
48
{
49
        uint8_t b;
50
51 1190550
        p += (no >> 3);
52 1190550
        b = (0x80 >> (no & 7));
53 1190550
        if (act == BSET)
54 51675
                *p |= b;
55 1138875
        else if (act == BCLR)
56 90
                *p &= ~b;
57 1190550
        return (*p & b);
58
}
59
60
/*--------------------------------------------------------------------
61
 */
62
63
static int
64 4410
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 4410
        av = VAV_Parse(arg, &n, ARGV_COMMA);
73 4410
        if (av[0] != NULL) {
74 5
                VSB_printf(vsb, "Cannot parse: %s\n", av[0]);
75 5
                VAV_Free(av);
76 5
                return (-1);
77
        }
78 8830
        for (i = 1; av[i] != NULL; i++) {
79 4435
                s = av[i];
80 4435
                if (*s != '-' && *s != '+') {
81 5
                        VSB_printf(vsb, "Missing '+' or '-' (%s)\n", s);
82 5
                        VAV_Free(av);
83 5
                        return (-1);
84
                }
85 51565
                for (j = 0; j < l; j++) {
86 51560
                        if (tags[j] != NULL && !strcasecmp(s + 1, tags[j]))
87 4425
                                break;
88
                }
89 4430
                if (tags[j] == NULL) {
90 5
                        VSB_printf(vsb, "Unknown %s (%s)\n", desc, s);
91 5
                        VAV_Free(av);
92 5
                        return (-1);
93
                }
94 4425
                assert(j < l);
95 4425
                if (s[0] == *sign)
96 4335
                        (void)bit(p, j, BSET);
97
                else
98 90
                        (void)bit(p, j, BCLR);
99
        }
100 4395
        VAV_Free(av);
101 4395
        return (0);
102
}
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 8040
tweak_vsl_mask(struct vsb *vsb, const struct parspec *par, const char *arg)
117
{
118
        unsigned j;
119
        const char *s;
120
        (void)par;
121
122 8040
        if (arg != NULL && arg != JSON_FMT) {
123 7960
                if (!strcmp(arg, "default")) {
124 3945
                        memset(mgt_param.vsl_mask,
125
                            0, sizeof mgt_param.vsl_mask);
126 3945
                        (void)bit(mgt_param.vsl_mask, SLT_VCL_trace, BSET);
127 3945
                        (void)bit(mgt_param.vsl_mask, SLT_WorkThread, BSET);
128 3945
                        (void)bit(mgt_param.vsl_mask, SLT_Hash, BSET);
129 3945
                        (void)bit(mgt_param.vsl_mask, SLT_VfpAcct, BSET);
130 3945
                        (void)bit(mgt_param.vsl_mask, SLT_H2TxBody, BSET);
131 3945
                        (void)bit(mgt_param.vsl_mask, SLT_H2TxHdr, BSET);
132 3945
                        (void)bit(mgt_param.vsl_mask, SLT_H2RxBody, BSET);
133 3945
                        (void)bit(mgt_param.vsl_mask, SLT_H2RxHdr, BSET);
134 3945
                        (void)bit(mgt_param.vsl_mask, SLT_ObjHeader, BSET);
135 3945
                        (void)bit(mgt_param.vsl_mask, SLT_ObjProtocol, BSET);
136 3945
                        (void)bit(mgt_param.vsl_mask, SLT_ObjReason, BSET);
137 3945
                        (void)bit(mgt_param.vsl_mask, SLT_ObjStatus, BSET);
138
                } else {
139 70
                        return (bit_tweak(vsb, mgt_param.vsl_mask,
140
                            SLT__Reserved, arg, VSL_tags,
141
                            "VSL tag", "-"));
142
                }
143
        } else {
144 4025
                if (arg == JSON_FMT)
145 10
                        VSB_putc(vsb, '"');
146 4025
                s = "";
147 1026375
                for (j = 0; j < (unsigned)SLT__Reserved; j++) {
148 1022350
                        if (bit(mgt_param.vsl_mask, j, BTST)) {
149 48280
                                VSB_printf(vsb, "%s-%s", s, VSL_tags[j]);
150 48280
                                s = ",";
151
                        }
152
                }
153 4025
                if (*s == '\0')
154 0
                        VSB_printf(vsb, "(all enabled)");
155 4025
                if (arg == JSON_FMT)
156 10
                        VSB_putc(vsb, '"');
157
        }
158 7970
        return (0);
159
}
160
161
/*--------------------------------------------------------------------
162
 * The debug parameter
163
 */
164
165
static const char * const debug_tags[] = {
166
#  define DEBUG_BIT(U, l, d) [DBG_##U] = #l,
167
#  include "tbl/debug_bits.h"
168
       NULL
169
};
170
171
static int
172 11950
tweak_debug(struct vsb *vsb, const struct parspec *par, const char *arg)
173
{
174
        const char *s;
175
        unsigned j;
176
        (void)par;
177
178 11950
        if (arg != NULL && arg != JSON_FMT) {
179 11880
                if (!strcmp(arg, "none")) {
180 3945
                        memset(mgt_param.debug_bits,
181
                            0, sizeof mgt_param.debug_bits);
182
                } else {
183 3990
                        return (bit_tweak(vsb, mgt_param.debug_bits,
184
                            DBG_Reserved, arg, debug_tags, "debug bit", "+"));
185
                }
186
        } else {
187 4015
                if (arg == JSON_FMT)
188 10
                        VSB_putc(vsb, '"');
189 4015
                s = "";
190 80300
                for (j = 0; j < (unsigned)DBG_Reserved; j++) {
191 76285
                        if (bit(mgt_param.debug_bits, j, BTST)) {
192 85
                                VSB_printf(vsb, "%s+%s", s, debug_tags[j]);
193 85
                                s = ",";
194
                        }
195
                }
196 4015
                if (*s == '\0')
197 3945
                        VSB_printf(vsb, "none");
198 4015
                if (arg == JSON_FMT)
199 10
                        VSB_putc(vsb, '"');
200
        }
201 7960
        return (0);
202
}
203
204
/*--------------------------------------------------------------------
205
 * The feature parameter
206
 */
207
208
static const char * const feature_tags[] = {
209
#  define FEATURE_BIT(U, l, d, ld) [FEATURE_##U] = #l,
210
#  include "tbl/feature_bits.h"
211
       NULL
212
};
213
214
static int
215 8310
tweak_feature(struct vsb *vsb, const struct parspec *par, const char *arg)
216
{
217
        const char *s;
218
        unsigned j;
219
        (void)par;
220
221 8310
        if (arg != NULL && arg != JSON_FMT) {
222 8240
                if (!strcmp(arg, "none")) {
223 3945
                        memset(mgt_param.feature_bits,
224
                            0, sizeof mgt_param.feature_bits);
225
                } else {
226 350
                        return (bit_tweak(vsb, mgt_param.feature_bits,
227
                            FEATURE_Reserved, arg, feature_tags,
228
                            "feature bit", "+"));
229
                }
230
        } else {
231 4015
                if (arg == JSON_FMT)
232 10
                        VSB_putc(vsb, '"');
233 4015
                s = "";
234 44165
                for (j = 0; j < (unsigned)FEATURE_Reserved; j++) {
235 40150
                        if (bit(mgt_param.feature_bits, j, BTST)) {
236 5
                                VSB_printf(vsb, "%s+%s", s, feature_tags[j]);
237 5
                                s = ",";
238
                        }
239
                }
240 4015
                if (*s == '\0')
241 4010
                        VSB_printf(vsb, "none");
242 4015
                if (arg == JSON_FMT)
243 10
                        VSB_putc(vsb, '"');
244
        }
245 7960
        return (0);
246
}
247
248
/*--------------------------------------------------------------------
249
 * The parameter table itself
250
 */
251
252
struct parspec VSL_parspec[] = {
253
        { "vsl_mask", tweak_vsl_mask, NULL, NULL, NULL,
254
                "Mask individual VSL messages from being logged.\n"
255
                "\tdefault\tSet default value\n"
256
                "\nUse +/- prefix in front of VSL tag name, to mask/unmask "
257
                "individual VSL messages.",
258
                0, "default", "" },
259
        { "debug", tweak_debug, NULL, NULL, NULL,
260
                "Enable/Disable various kinds of debugging.\n"
261
                "\tnone\tDisable all debugging\n\n"
262
                "Use +/- prefix to set/reset individual bits:"
263
#define DEBUG_BIT(U, l, d) "\n\t" #l "\t" d
264
#include "tbl/debug_bits.h"
265
#undef DEBUG_BIT
266
                , 0, "none", "" },
267
        { "feature", tweak_feature, NULL, NULL, NULL,
268
                "Enable/Disable various minor features.\n"
269
                "\tnone\tDisable all features.\n\n"
270
                "Use +/- prefix to enable/disable individual feature:"
271
#define FEATURE_BIT(U, l, d, ld) "\n\t" #l "\t" d
272
#include "tbl/feature_bits.h"
273
#undef FEATURE_BIT
274
                , 0, "none", "" },
275
        { NULL, NULL, NULL }
276
};