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 409734
bit(uint8_t *p, unsigned no, enum bit_do act)
48
{
49
        uint8_t b;
50
51 409734
        p += (no >> 3);
52 409734
        b = (0x80 >> (no & 7));
53 409734
        if (act == BSET)
54 7126
                *p |= b;
55 402608
        else if (act == BCLR)
56 24
                *p &= ~b;
57 409734
        return (*p & b);
58
}
59
60
/*--------------------------------------------------------------------
61
 */
62
63
static int
64 1534
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 1534
        av = VAV_Parse(arg, &n, ARGV_COMMA);
73 1534
        if (av[0] != NULL) {
74 2
                VSB_printf(vsb, "Cannot parse: %s\n", av[0]);
75 2
                VAV_Free(av);
76 2
                return (-1);
77
        }
78 3066
        for (i = 1; av[i] != NULL; i++) {
79 1538
                s = av[i];
80 1538
                if (*s != '-' && *s != '+') {
81 2
                        VSB_printf(vsb, "Missing '+' or '-' (%s)\n", s);
82 2
                        VAV_Free(av);
83 2
                        return (-1);
84
                }
85 17254
                for (j = 0; j < l; j++) {
86 17252
                        if (tags[j] != NULL && !strcasecmp(s + 1, tags[j]))
87 1534
                                break;
88
                }
89 1536
                if (tags[j] == NULL) {
90 2
                        VSB_printf(vsb, "Unknown %s (%s)\n", desc, s);
91 2
                        VAV_Free(av);
92 2
                        return (-1);
93
                }
94 1534
                assert(j < l);
95 1534
                if (s[0] == *sign)
96 1510
                        (void)bit(p, j, BSET);
97
                else
98 24
                        (void)bit(p, j, BCLR);
99
        }
100 1528
        VAV_Free(av);
101 1528
        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 2854
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 2854
        if (arg != NULL) {
123 1426
                if (!strcmp(arg, "default")) {
124 1404
                        memset(mgt_param.vsl_mask,
125
                            0, sizeof mgt_param.vsl_mask);
126 1404
                        (void)bit(mgt_param.vsl_mask, SLT_VCL_trace, BSET);
127 1404
                        (void)bit(mgt_param.vsl_mask, SLT_WorkThread, BSET);
128 1404
                        (void)bit(mgt_param.vsl_mask, SLT_Hash, BSET);
129 1404
                        (void)bit(mgt_param.vsl_mask, SLT_VfpAcct, BSET);
130
                } else {
131 22
                        return (bit_tweak(vsb, mgt_param.vsl_mask,
132
                            SLT__Reserved, arg, VSL_tags,
133
                            "VSL tag", "-"));
134
                }
135
        } else {
136 1428
                s = "";
137 364140
                for (j = 0; j < (unsigned)SLT__Reserved; j++) {
138 362712
                        if (bit(mgt_param.vsl_mask, j, BTST)) {
139 5704
                                VSB_printf(vsb, "%s-%s", s, VSL_tags[j]);
140 5704
                                s = ",";
141
                        }
142
                }
143 1428
                if (*s == '\0')
144 0
                        VSB_printf(vsb, "(all enabled)");
145
        }
146 2832
        return (0);
147
}
148
149
/*--------------------------------------------------------------------
150
 * The debug parameter
151
 */
152
153
static const char * const debug_tags[] = {
154
#  define DEBUG_BIT(U, l, d) [DBG_##U] = #l,
155
#  include "tbl/debug_bits.h"
156
       NULL
157
};
158
159
static int
160 4224
tweak_debug(struct vsb *vsb, const struct parspec *par, const char *arg)
161
{
162
        const char *s;
163
        unsigned j;
164
        (void)par;
165
166 4224
        if (arg != NULL) {
167 2800
                if (!strcmp(arg, "none")) {
168 1404
                        memset(mgt_param.debug_bits,
169
                            0, sizeof mgt_param.debug_bits);
170
                } else {
171 1396
                        return (bit_tweak(vsb, mgt_param.debug_bits,
172
                            DBG_Reserved, arg, debug_tags, "debug bit", "+"));
173
                }
174
        } else {
175 1424
                s = "";
176 28480
                for (j = 0; j < (unsigned)DBG_Reserved; j++) {
177 27056
                        if (bit(mgt_param.debug_bits, j, BTST)) {
178 26
                                VSB_printf(vsb, "%s+%s", s, debug_tags[j]);
179 26
                                s = ",";
180
                        }
181
                }
182 1424
                if (*s == '\0')
183 1404
                        VSB_printf(vsb, "none");
184
        }
185 2828
        return (0);
186
}
187
188
/*--------------------------------------------------------------------
189
 * The feature parameter
190
 */
191
192
static const char * const feature_tags[] = {
193
#  define FEATURE_BIT(U, l, d, ld) [FEATURE_##U] = #l,
194
#  include "tbl/feature_bits.h"
195
       NULL
196
};
197
198
static int
199 2944
tweak_feature(struct vsb *vsb, const struct parspec *par, const char *arg)
200
{
201
        const char *s;
202
        unsigned j;
203
        (void)par;
204
205 2944
        if (arg != NULL) {
206 1520
                if (!strcmp(arg, "none")) {
207 1404
                        memset(mgt_param.feature_bits,
208
                            0, sizeof mgt_param.feature_bits);
209
                } else {
210 116
                        return (bit_tweak(vsb, mgt_param.feature_bits,
211
                            FEATURE_Reserved, arg, feature_tags,
212
                            "feature bit", "+"));
213
                }
214
        } else {
215 1424
                s = "";
216 14240
                for (j = 0; j < (unsigned)FEATURE_Reserved; j++) {
217 12816
                        if (bit(mgt_param.feature_bits, j, BTST)) {
218 2
                                VSB_printf(vsb, "%s+%s", s, feature_tags[j]);
219 2
                                s = ",";
220
                        }
221
                }
222 1424
                if (*s == '\0')
223 1422
                        VSB_printf(vsb, "none");
224
        }
225 2828
        return (0);
226
}
227
228
/*--------------------------------------------------------------------
229
 * The parameter table itself
230
 */
231
232
struct parspec VSL_parspec[] = {
233
        { "vsl_mask", tweak_vsl_mask, NULL, NULL, NULL,
234
                "Mask individual VSL messages from being logged.\n"
235
                "\tdefault\tSet default value\n"
236
                "\nUse +/- prefix in front of VSL tag name, to mask/unmask "
237
                "individual VSL messages.",
238
                0, "default", "" },
239
        { "debug", tweak_debug, NULL, NULL, NULL,
240
                "Enable/Disable various kinds of debugging.\n"
241
                "\tnone\tDisable all debugging\n\n"
242
                "Use +/- prefix to set/reset individual bits:"
243
#define DEBUG_BIT(U, l, d) "\n\t" #l "\t" d
244
#include "tbl/debug_bits.h"
245
#undef DEBUG_BIT
246
                , 0, "none", "" },
247
        { "feature", tweak_feature, NULL, NULL, NULL,
248
                "Enable/Disable various minor features.\n"
249
                "\tnone\tDisable all features.\n\n"
250
                "Use +/- prefix to enable/disable individual feature:"
251
#define FEATURE_BIT(U, l, d, ld) "\n\t" #l "\t" d
252
#include "tbl/feature_bits.h"
253
#undef FEATURE_BIT
254
                , 0, "none", "" },
255
        { NULL, NULL, NULL }
256
};