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 244581
bit(uint8_t *p, unsigned no, enum bit_do act)
48
{
49
        uint8_t b;
50
51 244581
        p += (no >> 3);
52 244581
        b = (0x80 >> (no & 7));
53 244581
        if (act == BSET)
54 10609
                *p |= b;
55 233972
        else if (act == BCLR)
56 16
                *p &= ~b;
57 244581
        return (*p & b);
58
}
59
60
/*--------------------------------------------------------------------
61
 */
62
63
static int
64 878
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 878
        av = VAV_Parse(arg, &n, ARGV_COMMA);
73 878
        if (av[0] != NULL) {
74 1
                VSB_printf(vsb, "Cannot parse: %s\n", av[0]);
75 1
                VAV_Free(av);
76 1
                return (-1);
77
        }
78 1758
        for (i = 1; av[i] != NULL; i++) {
79 883
                s = av[i];
80 883
                if (*s != '-' && *s != '+') {
81 1
                        VSB_printf(vsb, "Missing '+' or '-' (%s)\n", s);
82 1
                        VAV_Free(av);
83 1
                        return (-1);
84
                }
85 10127
                for (j = 0; j < l; j++) {
86 10126
                        if (tags[j] != NULL && !strcasecmp(s + 1, tags[j]))
87 881
                                break;
88
                }
89 882
                if (tags[j] == NULL) {
90 1
                        VSB_printf(vsb, "Unknown %s (%s)\n", desc, s);
91 1
                        VAV_Free(av);
92 1
                        return (-1);
93
                }
94 881
                assert(j < l);
95 881
                if (s[0] == *sign)
96 865
                        (void)bit(p, j, BSET);
97
                else
98 16
                        (void)bit(p, j, BCLR);
99
        }
100 875
        VAV_Free(av);
101 875
        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 1648
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 1648
        if (arg != NULL) {
123 824
                if (!strcmp(arg, "default")) {
124 812
                        memset(mgt_param.vsl_mask,
125
                            0, sizeof mgt_param.vsl_mask);
126 812
                        (void)bit(mgt_param.vsl_mask, SLT_VCL_trace, BSET);
127 812
                        (void)bit(mgt_param.vsl_mask, SLT_WorkThread, BSET);
128 812
                        (void)bit(mgt_param.vsl_mask, SLT_Hash, BSET);
129 812
                        (void)bit(mgt_param.vsl_mask, SLT_VfpAcct, BSET);
130 812
                        (void)bit(mgt_param.vsl_mask, SLT_H2TxBody, BSET);
131 812
                        (void)bit(mgt_param.vsl_mask, SLT_H2TxHdr, BSET);
132 812
                        (void)bit(mgt_param.vsl_mask, SLT_H2RxBody, BSET);
133 812
                        (void)bit(mgt_param.vsl_mask, SLT_H2RxHdr, BSET);
134 812
                        (void)bit(mgt_param.vsl_mask, SLT_ObjHeader, BSET);
135 812
                        (void)bit(mgt_param.vsl_mask, SLT_ObjProtocol, BSET);
136 812
                        (void)bit(mgt_param.vsl_mask, SLT_ObjReason, BSET);
137 812
                        (void)bit(mgt_param.vsl_mask, SLT_ObjStatus, BSET);
138
                } else {
139 12
                        return (bit_tweak(vsb, mgt_param.vsl_mask,
140
                            SLT__Reserved, arg, VSL_tags,
141
                            "VSL tag", "-"));
142
                }
143
        } else {
144 824
                s = "";
145 210120
                for (j = 0; j < (unsigned)SLT__Reserved; j++) {
146 209296
                        if (bit(mgt_param.vsl_mask, j, BTST)) {
147 9884
                                VSB_printf(vsb, "%s-%s", s, VSL_tags[j]);
148 9884
                                s = ",";
149
                        }
150
                }
151 824
                if (*s == '\0')
152 0
                        VSB_printf(vsb, "(all enabled)");
153
        }
154 1636
        return (0);
155
}
156
157
/*--------------------------------------------------------------------
158
 * The debug parameter
159
 */
160
161
static const char * const debug_tags[] = {
162
#  define DEBUG_BIT(U, l, d) [DBG_##U] = #l,
163
#  include "tbl/debug_bits.h"
164
       NULL
165
};
166
167
static int
168 2433
tweak_debug(struct vsb *vsb, const struct parspec *par, const char *arg)
169
{
170
        const char *s;
171
        unsigned j;
172
        (void)par;
173
174 2433
        if (arg != NULL) {
175 1611
                if (!strcmp(arg, "none")) {
176 812
                        memset(mgt_param.debug_bits,
177
                            0, sizeof mgt_param.debug_bits);
178
                } else {
179 799
                        return (bit_tweak(vsb, mgt_param.debug_bits,
180
                            DBG_Reserved, arg, debug_tags, "debug bit", "+"));
181
                }
182
        } else {
183 822
                s = "";
184 17262
                for (j = 0; j < (unsigned)DBG_Reserved; j++) {
185 16440
                        if (bit(mgt_param.debug_bits, j, BTST)) {
186 13
                                VSB_printf(vsb, "%s+%s", s, debug_tags[j]);
187 13
                                s = ",";
188
                        }
189
                }
190 822
                if (*s == '\0')
191 812
                        VSB_printf(vsb, "none");
192
        }
193 1634
        return (0);
194
}
195
196
/*--------------------------------------------------------------------
197
 * The feature parameter
198
 */
199
200
static const char * const feature_tags[] = {
201
#  define FEATURE_BIT(U, l, d, ld) [FEATURE_##U] = #l,
202
#  include "tbl/feature_bits.h"
203
       NULL
204
};
205
206
static int
207 1701
tweak_feature(struct vsb *vsb, const struct parspec *par, const char *arg)
208
{
209
        const char *s;
210
        unsigned j;
211
        (void)par;
212
213 1701
        if (arg != NULL) {
214 879
                if (!strcmp(arg, "none")) {
215 812
                        memset(mgt_param.feature_bits,
216
                            0, sizeof mgt_param.feature_bits);
217
                } else {
218 67
                        return (bit_tweak(vsb, mgt_param.feature_bits,
219
                            FEATURE_Reserved, arg, feature_tags,
220
                            "feature bit", "+"));
221
                }
222
        } else {
223 822
                s = "";
224 9042
                for (j = 0; j < (unsigned)FEATURE_Reserved; j++) {
225 8220
                        if (bit(mgt_param.feature_bits, j, BTST)) {
226 1
                                VSB_printf(vsb, "%s+%s", s, feature_tags[j]);
227 1
                                s = ",";
228
                        }
229
                }
230 822
                if (*s == '\0')
231 821
                        VSB_printf(vsb, "none");
232
        }
233 1634
        return (0);
234
}
235
236
/*--------------------------------------------------------------------
237
 * The parameter table itself
238
 */
239
240
struct parspec VSL_parspec[] = {
241
        { "vsl_mask", tweak_vsl_mask, NULL, NULL, NULL,
242
                "Mask individual VSL messages from being logged.\n"
243
                "\tdefault\tSet default value\n"
244
                "\nUse +/- prefix in front of VSL tag name, to mask/unmask "
245
                "individual VSL messages.",
246
                0, "default", "" },
247
        { "debug", tweak_debug, NULL, NULL, NULL,
248
                "Enable/Disable various kinds of debugging.\n"
249
                "\tnone\tDisable all debugging\n\n"
250
                "Use +/- prefix to set/reset individual bits:"
251
#define DEBUG_BIT(U, l, d) "\n\t" #l "\t" d
252
#include "tbl/debug_bits.h"
253
#undef DEBUG_BIT
254
                , 0, "none", "" },
255
        { "feature", tweak_feature, NULL, NULL, NULL,
256
                "Enable/Disable various minor features.\n"
257
                "\tnone\tDisable all features.\n\n"
258
                "Use +/- prefix to enable/disable individual feature:"
259
#define FEATURE_BIT(U, l, d, ld) "\n\t" #l "\t" d
260
#include "tbl/feature_bits.h"
261
#undef FEATURE_BIT
262
                , 0, "none", "" },
263
        { NULL, NULL, NULL }
264
};