1/*
2 * cfg.c
3 *
4 * Copyright (C) 2008-2016 Aerospike, Inc.
5 *
6 * Portions may be licensed to Aerospike, Inc. under one or more contributor
7 * license agreements.
8 *
9 * This program is free software: you can redistribute it and/or modify it under
10 * the terms of the GNU Affero General Public License as published by the Free
11 * Software Foundation, either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see http://www.gnu.org/licenses/
21 */
22
23#include "base/cfg.h"
24
25#include <errno.h>
26#include <grp.h>
27#include <pwd.h>
28#include <stdbool.h>
29#include <stddef.h>
30#include <stdint.h>
31#include <stdio.h>
32#include <string.h>
33#include <unistd.h>
34#include <linux/capability.h>
35#include <sys/resource.h>
36#include <sys/types.h>
37
38#include "aerospike/mod_lua_config.h"
39#include "citrusleaf/alloc.h"
40#include "citrusleaf/cf_atomic.h"
41#include "citrusleaf/cf_clock.h"
42#include "citrusleaf/cf_vector.h"
43
44#include "arenax.h"
45#include "bits.h"
46#include "cf_mutex.h"
47#include "cf_str.h"
48#include "daemon.h"
49#include "dynbuf.h"
50#include "fault.h"
51#include "hardware.h"
52#include "hist.h"
53#include "hist_track.h"
54#include "msg.h"
55#include "node.h"
56#include "socket.h"
57#include "tls.h"
58#include "xmem.h"
59
60#include "base/datamodel.h"
61#include "base/index.h"
62#include "base/proto.h"
63#include "base/secondary_index.h"
64#include "base/security_config.h"
65#include "base/service.h"
66#include "base/stats.h"
67#include "base/thr_info.h"
68#include "base/thr_info_port.h"
69#include "base/thr_query.h"
70#include "base/thr_sindex.h"
71#include "base/transaction_policy.h"
72#include "base/truncate.h"
73#include "base/xdr_config.h"
74#include "base/xdr_serverside.h"
75#include "fabric/fabric.h"
76#include "fabric/hb.h"
77#include "fabric/migrate.h"
78#include "fabric/partition_balance.h"
79#include "storage/storage.h"
80
81
82//==========================================================
83// Globals.
84//
85
86// The runtime configuration instance.
87as_config g_config;
88
89
90//==========================================================
91// Forward declarations.
92//
93
94void init_addr_list(cf_addr_list* addrs);
95void add_addr(const char* name, cf_addr_list* addrs);
96void add_tls_peer_name(const char* name, cf_serv_spec* spec);
97void copy_addrs(const cf_addr_list* from, cf_addr_list* to);
98void default_addrs(cf_addr_list* one, cf_addr_list* two);
99void bind_to_access(const cf_serv_spec* from, cf_addr_list* to);
100void cfg_add_addr_bind(const char* name, cf_serv_spec* spec);
101void cfg_add_addr_std(const char* name, cf_serv_spec* spec);
102void cfg_add_addr_alt(const char* name, cf_serv_spec* spec);
103void cfg_mserv_config_from_addrs(cf_addr_list* addrs, cf_addr_list* bind_addrs, cf_mserv_cfg* serv_cfg, cf_ip_port port, cf_sock_owner owner, uint8_t ttl);
104void cfg_serv_spec_to_bind(const cf_serv_spec* spec, const cf_serv_spec* def_spec, cf_serv_cfg* bind, cf_sock_owner owner);
105void cfg_serv_spec_std_to_access(const cf_serv_spec* spec, cf_addr_list* access);
106void cfg_serv_spec_alt_to_access(const cf_serv_spec* spec, cf_addr_list* access);
107void cfg_add_mesh_seed_addr_port(char* addr, cf_ip_port port, bool tls);
108as_set* cfg_add_set(as_namespace* ns);
109void cfg_add_xmem_mount(as_namespace* ns, const char* mount);
110void cfg_add_storage_file(as_namespace* ns, const char* file_name, const char* shadow_name);
111void cfg_add_storage_device(as_namespace* ns, const char* device_name, const char* shadow_name);
112void cfg_set_cluster_name(char* cluster_name);
113void cfg_add_ldap_role_query_pattern(char* pattern);
114void create_and_check_hist_track(cf_hist_track** h, const char* name, histogram_scale scale);
115void cfg_create_all_histograms();
116void cfg_init_serv_spec(cf_serv_spec* spec_p);
117cf_tls_spec* cfg_create_tls_spec(as_config* cfg, char* name);
118char* cfg_resolve_tls_name(char* tls_name, const char* cluster_name, const char* which);
119void cfg_keep_cap(bool keep, bool* what, int32_t cap);
120
121xdr_dest_config* xdr_cfg_add_datacenter(char* name);
122void xdr_cfg_associate_datacenter(char* dc, uint32_t nsid);
123void xdr_cfg_add_http_url(xdr_dest_config* dest_cfg, char* url);
124void xdr_cfg_add_node_addr_port(xdr_dest_config* dest_cfg, char* addr, int port);
125void xdr_cfg_add_tls_node(xdr_dest_config* dest_cfg, char* addr, char* tls_name, int port);
126
127
128//==========================================================
129// Helper - set as_config defaults.
130//
131
132void
133cfg_set_defaults()
134{
135 as_config* c = &g_config;
136
137 memset(c, 0, sizeof(as_config));
138
139 cfg_init_serv_spec(&c->service);
140 cfg_init_serv_spec(&c->tls_service);
141 cfg_init_serv_spec(&c->hb_serv_spec);
142 cfg_init_serv_spec(&c->hb_tls_serv_spec);
143 cfg_init_serv_spec(&c->fabric);
144 cfg_init_serv_spec(&c->tls_fabric);
145 cfg_init_serv_spec(&c->info);
146
147 c->uid = (uid_t)-1;
148 c->gid = (gid_t)-1;
149 c->paxos_single_replica_limit = 1; // by default all clusters obey replication counts
150 c->n_proto_fd_max = 15000;
151 c->batch_max_buffers_per_queue = 255; // maximum number of buffers allowed in a single queue
152 c->batch_max_requests = 5000; // maximum requests/digests in a single batch
153 c->batch_max_unused_buffers = 256; // maximum number of buffers allowed in batch buffer pool
154 c->feature_key_file = "/etc/aerospike/features.conf";
155 c->hist_track_back = 300;
156 c->hist_track_slice = 10;
157 c->n_info_threads = 16;
158 c->migrate_max_num_incoming = AS_MIGRATE_DEFAULT_MAX_NUM_INCOMING; // for receiver-side migration flow-control
159 c->n_migrate_threads = 1;
160 c->proto_fd_idle_ms = 60000; // 1 minute reaping of proto file descriptors
161 c->proto_slow_netio_sleep_ms = 1; // 1 ms sleep between retry for slow queries
162 c->run_as_daemon = true; // set false only to run in debugger & see console output
163 c->scan_max_done = 100;
164 c->n_scan_threads_limit = 128;
165 c->ticker_interval = 10;
166 c->transaction_max_ns = 1000 * 1000 * 1000; // 1 second
167 c->transaction_retry_ms = 1000 + 2; // 1 second + epsilon, so default timeout happens first
168 as_sindex_gconfig_default(c);
169 as_query_gconfig_default(c);
170 c->work_directory = "/opt/aerospike";
171 c->debug_allocations = CF_ALLOC_DEBUG_NONE;
172 c->fabric_dump_msgs = false;
173
174 // Network heartbeat defaults.
175 c->hb_config.mode = AS_HB_MODE_UNDEF;
176 c->hb_config.tx_interval = 150;
177 c->hb_config.max_intervals_missed = 10;
178 c->hb_config.protocol = AS_HB_PROTOCOL_V3;
179 c->hb_config.override_mtu = 0;
180
181 // Fabric defaults.
182 c->n_fabric_channel_fds[AS_FABRIC_CHANNEL_BULK] = 2;
183 c->n_fabric_channel_recv_threads[AS_FABRIC_CHANNEL_BULK] = 4;
184 c->n_fabric_channel_fds[AS_FABRIC_CHANNEL_CTRL] = 1;
185 c->n_fabric_channel_recv_threads[AS_FABRIC_CHANNEL_CTRL] = 4;
186 c->n_fabric_channel_fds[AS_FABRIC_CHANNEL_META] = 1;
187 c->n_fabric_channel_recv_threads[AS_FABRIC_CHANNEL_META] = 4;
188 c->n_fabric_channel_fds[AS_FABRIC_CHANNEL_RW] = 8;
189 c->n_fabric_channel_recv_threads[AS_FABRIC_CHANNEL_RW] = 16;
190 c->fabric_keepalive_enabled = true;
191 c->fabric_keepalive_intvl = 1; // seconds
192 c->fabric_keepalive_probes = 10; // tries
193 c->fabric_keepalive_time = 1; // seconds
194 c->fabric_latency_max_ms = 5; // assume a one way latency of 5 milliseconds by default
195 c->fabric_recv_rearm_threshold = 1024;
196 c->n_fabric_send_threads = 8;
197
198 // Clustering defaults.
199 c->clustering_config.cluster_size_min = 1;
200 c->clustering_config.clique_based_eviction_enabled = true;
201
202 // XDR defaults.
203 for (int i = 0; i < AS_CLUSTER_SZ ; i++) {
204 c->xdr_peers_lst[i].node = 0;
205
206 for (int j = 0; j < DC_MAX_NUM; j++) {
207 c->xdr_peers_lst[i].time[j] = 0;
208 }
209
210 c->xdr_clmap[i] = 0;
211 }
212
213 for (int j = 0; j < DC_MAX_NUM; j++) {
214 c->xdr_self_lastshiptime[j] = 0;
215 }
216
217 // Mod-lua defaults.
218 c->mod_lua.server_mode = true;
219 c->mod_lua.cache_enabled = true;
220 strcpy(c->mod_lua.user_path, "/opt/aerospike/usr/udf/lua");
221
222 // TODO - security set default config API?
223 // Security defaults.
224 c->sec_cfg.n_ldap_login_threads = 8;
225 c->sec_cfg.privilege_refresh_period = 60 * 5; // refresh socket privileges every 5 minutes
226 // Security LDAP defaults.
227 c->sec_cfg.ldap_polling_period = 60 * 5;
228 c->sec_cfg.ldap_session_ttl = 60 * 60 * 24;
229 c->sec_cfg.ldap_token_hash_method = AS_LDAP_EVP_SHA_256;
230 // Security syslog defaults.
231 c->sec_cfg.syslog_local = AS_SYSLOG_NONE;
232}
233
234//==========================================================
235// All configuration items must have a switch case
236// identifier somewhere in this enum. The order is not
237// important, other than for organizational sanity.
238//
239
240typedef enum {
241 // Generic:
242 // Token not found:
243 CASE_NOT_FOUND,
244 // Start of parsing context:
245 CASE_CONTEXT_BEGIN,
246 // End of parsing context:
247 CASE_CONTEXT_END,
248
249 // Top-level options:
250 // In canonical configuration file order:
251 CASE_SERVICE_BEGIN,
252 CASE_LOGGING_BEGIN,
253 CASE_NETWORK_BEGIN,
254 CASE_NAMESPACE_BEGIN,
255 CASE_MOD_LUA_BEGIN,
256 CASE_CLUSTER_BEGIN,
257 // Enterprise-only:
258 CASE_SECURITY_BEGIN,
259 CASE_XDR_BEGIN,
260
261 // Service options:
262 // Normally visible, in canonical configuration file order:
263 CASE_SERVICE_USER,
264 CASE_SERVICE_GROUP,
265 CASE_SERVICE_PAXOS_SINGLE_REPLICA_LIMIT,
266 CASE_SERVICE_PIDFILE,
267 CASE_SERVICE_CLIENT_FD_MAX, // renamed
268 CASE_SERVICE_PROTO_FD_MAX,
269 // Normally hidden:
270 CASE_SERVICE_ADVERTISE_IPV6,
271 CASE_SERVICE_AUTO_PIN,
272 CASE_SERVICE_BATCH_INDEX_THREADS,
273 CASE_SERVICE_BATCH_MAX_BUFFERS_PER_QUEUE,
274 CASE_SERVICE_BATCH_MAX_REQUESTS,
275 CASE_SERVICE_BATCH_MAX_UNUSED_BUFFERS,
276 CASE_SERVICE_CLUSTER_NAME,
277 CASE_SERVICE_ENABLE_BENCHMARKS_FABRIC,
278 CASE_SERVICE_ENABLE_BENCHMARKS_SVC,
279 CASE_SERVICE_ENABLE_HEALTH_CHECK,
280 CASE_SERVICE_ENABLE_HIST_INFO,
281 CASE_SERVICE_FEATURE_KEY_FILE,
282 CASE_SERVICE_HIST_TRACK_BACK,
283 CASE_SERVICE_HIST_TRACK_SLICE,
284 CASE_SERVICE_HIST_TRACK_THRESHOLDS,
285 CASE_SERVICE_INFO_THREADS,
286 CASE_SERVICE_KEEP_CAPS_SSD_HEALTH,
287 CASE_SERVICE_LOG_LOCAL_TIME,
288 CASE_SERVICE_LOG_MILLIS,
289 CASE_SERVICE_MIGRATE_FILL_DELAY,
290 CASE_SERVICE_MIGRATE_MAX_NUM_INCOMING,
291 CASE_SERVICE_MIGRATE_THREADS,
292 CASE_SERVICE_MIN_CLUSTER_SIZE,
293 CASE_SERVICE_NODE_ID,
294 CASE_SERVICE_NODE_ID_INTERFACE,
295 CASE_SERVICE_PROTO_FD_IDLE_MS,
296 CASE_SERVICE_QUERY_BATCH_SIZE,
297 CASE_SERVICE_QUERY_BUFPOOL_SIZE,
298 CASE_SERVICE_QUERY_IN_TRANSACTION_THREAD,
299 CASE_SERVICE_QUERY_LONG_Q_MAX_SIZE,
300 CASE_SERVICE_QUERY_PRE_RESERVE_PARTITIONS,
301 CASE_SERVICE_QUERY_PRIORITY,
302 CASE_SERVICE_QUERY_PRIORITY_SLEEP_US,
303 CASE_SERVICE_QUERY_REC_COUNT_BOUND,
304 CASE_SERVICE_QUERY_REQ_IN_QUERY_THREAD,
305 CASE_SERVICE_QUERY_REQ_MAX_INFLIGHT,
306 CASE_SERVICE_QUERY_SHORT_Q_MAX_SIZE,
307 CASE_SERVICE_QUERY_THREADS,
308 CASE_SERVICE_QUERY_THRESHOLD,
309 CASE_SERVICE_QUERY_UNTRACKED_TIME_MS,
310 CASE_SERVICE_QUERY_WORKER_THREADS,
311 CASE_SERVICE_RUN_AS_DAEMON,
312 CASE_SERVICE_SCAN_MAX_DONE,
313 CASE_SERVICE_SCAN_THREADS_LIMIT,
314 CASE_SERVICE_SERVICE_THREADS,
315 CASE_SERVICE_SINDEX_BUILDER_THREADS,
316 CASE_SERVICE_SINDEX_GC_MAX_RATE,
317 CASE_SERVICE_SINDEX_GC_PERIOD,
318 CASE_SERVICE_TICKER_INTERVAL,
319 CASE_SERVICE_TRANSACTION_MAX_MS,
320 CASE_SERVICE_TRANSACTION_RETRY_MS,
321 CASE_SERVICE_WORK_DIRECTORY,
322 // For special debugging or bug-related repair:
323 CASE_SERVICE_DEBUG_ALLOCATIONS,
324 CASE_SERVICE_FABRIC_DUMP_MSGS,
325 CASE_SERVICE_INDENT_ALLOCATIONS,
326 // Obsoleted:
327 CASE_SERVICE_ALLOW_INLINE_TRANSACTIONS,
328 CASE_SERVICE_NSUP_PERIOD,
329 CASE_SERVICE_OBJECT_SIZE_HIST_PERIOD,
330 CASE_SERVICE_RESPOND_CLIENT_ON_MASTER_COMPLETION,
331 CASE_SERVICE_SCAN_MAX_UDF_TRANSACTIONS,
332 CASE_SERVICE_SCAN_THREADS,
333 CASE_SERVICE_TRANSACTION_PENDING_LIMIT,
334 CASE_SERVICE_TRANSACTION_QUEUES,
335 CASE_SERVICE_TRANSACTION_REPEATABLE_READ,
336 CASE_SERVICE_TRANSACTION_THREADS_PER_QUEUE,
337 // Deprecated:
338 CASE_SERVICE_AUTO_DUN,
339 CASE_SERVICE_AUTO_UNDUN,
340 CASE_SERVICE_BATCH_PRIORITY,
341 CASE_SERVICE_BATCH_RETRANSMIT,
342 CASE_SERVICE_BATCH_THREADS,
343 CASE_SERVICE_CLIB_LIBRARY,
344 CASE_SERVICE_DEFRAG_QUEUE_ESCAPE,
345 CASE_SERVICE_DEFRAG_QUEUE_HWM,
346 CASE_SERVICE_DEFRAG_QUEUE_LWM,
347 CASE_SERVICE_DEFRAG_QUEUE_PRIORITY,
348 CASE_SERVICE_DUMP_MESSAGE_ABOVE_SIZE,
349 CASE_SERVICE_FABRIC_WORKERS,
350 CASE_SERVICE_FB_HEALTH_BAD_PCT,
351 CASE_SERVICE_FB_HEALTH_GOOD_PCT,
352 CASE_SERVICE_FB_HEALTH_MSG_PER_BURST,
353 CASE_SERVICE_FB_HEALTH_MSG_TIMEOUT,
354 CASE_SERVICE_GENERATION_DISABLE,
355 CASE_SERVICE_MAX_MSGS_PER_TYPE,
356 CASE_SERVICE_MIGRATE_READ_PRIORITY,
357 CASE_SERVICE_MIGRATE_READ_SLEEP,
358 CASE_SERVICE_MIGRATE_RX_LIFETIME_MS,
359 CASE_SERVICE_MIGRATE_XMIT_HWM,
360 CASE_SERVICE_MIGRATE_XMIT_LWM,
361 CASE_SERVICE_MIGRATE_PRIORITY, // renamed
362 CASE_SERVICE_MIGRATE_XMIT_PRIORITY,
363 CASE_SERVICE_MIGRATE_XMIT_SLEEP,
364 CASE_SERVICE_NSUP_AUTO_HWM,
365 CASE_SERVICE_NSUP_AUTO_HWM_PCT,
366 CASE_SERVICE_NSUP_DELETE_SLEEP,
367 CASE_SERVICE_NSUP_MAX_DELETES,
368 CASE_SERVICE_NSUP_QUEUE_HWM,
369 CASE_SERVICE_NSUP_QUEUE_LWM,
370 CASE_SERVICE_NSUP_QUEUE_ESCAPE,
371 CASE_SERVICE_NSUP_REDUCE_PRIORITY,
372 CASE_SERVICE_NSUP_REDUCE_SLEEP,
373 CASE_SERVICE_NSUP_STARTUP_EVICT,
374 CASE_SERVICE_NSUP_THREADS,
375 CASE_SERVICE_PAXOS_MAX_CLUSTER_SIZE,
376 CASE_SERVICE_PAXOS_PROTOCOL,
377 CASE_SERVICE_PAXOS_RECOVERY_POLICY,
378 CASE_SERVICE_PAXOS_RETRANSMIT_PERIOD,
379 CASE_SERVICE_PROLE_EXTRA_TTL,
380 CASE_SERVICE_REPLICATION_FIRE_AND_FORGET,
381 CASE_SERVICE_SCAN_MAX_ACTIVE,
382 CASE_SERVICE_SCAN_MEMORY,
383 CASE_SERVICE_SCAN_PRIORITY,
384 CASE_SERVICE_SCAN_RETRANSMIT,
385 CASE_SERVICE_SCHEDULER_PRIORITY,
386 CASE_SERVICE_SCHEDULER_TYPE,
387 CASE_SERVICE_TRANSACTION_DUPLICATE_THREADS,
388 CASE_SERVICE_TRIAL_ACCOUNT_KEY,
389 CASE_SERVICE_UDF_RUNTIME_MAX_GMEMORY,
390 CASE_SERVICE_UDF_RUNTIME_MAX_MEMORY,
391 CASE_SERVICE_USE_QUEUE_PER_DEVICE,
392 CASE_SERVICE_WRITE_DUPLICATE_RESOLUTION_DISABLE,
393
394 // Service auto-pin options (value tokens):
395 CASE_SERVICE_AUTO_PIN_NONE,
396 CASE_SERVICE_AUTO_PIN_CPU,
397 CASE_SERVICE_AUTO_PIN_NUMA,
398 CASE_SERVICE_AUTO_PIN_ADQ,
399
400 // Service debug-allocations options (value tokens):
401 CASE_SERVICE_DEBUG_ALLOCATIONS_NONE,
402 CASE_SERVICE_DEBUG_ALLOCATIONS_TRANSIENT,
403 CASE_SERVICE_DEBUG_ALLOCATIONS_PERSISTENT,
404 CASE_SERVICE_DEBUG_ALLOCATIONS_ALL,
405
406 // Logging options:
407 // Normally visible:
408 CASE_LOG_FILE_BEGIN,
409 // Normally hidden:
410 CASE_LOG_CONSOLE_BEGIN,
411
412 // Logging file options:
413 // Normally visible:
414 CASE_LOG_FILE_CONTEXT,
415
416 // Logging console options:
417 // Normally visible:
418 CASE_LOG_CONSOLE_CONTEXT,
419
420 // Network options:
421 // Normally visible, in canonical configuration file order:
422 CASE_NETWORK_SERVICE_BEGIN,
423 CASE_NETWORK_HEARTBEAT_BEGIN,
424 CASE_NETWORK_FABRIC_BEGIN,
425 CASE_NETWORK_INFO_BEGIN,
426 // Normally hidden:
427 CASE_NETWORK_TLS_BEGIN,
428
429 // Network service options:
430 // Normally visible, in canonical configuration file order:
431 CASE_NETWORK_SERVICE_ADDRESS,
432 CASE_NETWORK_SERVICE_PORT,
433 // Normally hidden:
434 CASE_NETWORK_SERVICE_EXTERNAL_ADDRESS, // renamed
435 CASE_NETWORK_SERVICE_ACCESS_ADDRESS,
436 CASE_NETWORK_SERVICE_ACCESS_PORT,
437 CASE_NETWORK_SERVICE_ALTERNATE_ACCESS_ADDRESS,
438 CASE_NETWORK_SERVICE_ALTERNATE_ACCESS_PORT,
439 CASE_NETWORK_SERVICE_TLS_ACCESS_ADDRESS,
440 CASE_NETWORK_SERVICE_TLS_ACCESS_PORT,
441 CASE_NETWORK_SERVICE_TLS_ADDRESS,
442 CASE_NETWORK_SERVICE_TLS_ALTERNATE_ACCESS_ADDRESS,
443 CASE_NETWORK_SERVICE_TLS_ALTERNATE_ACCESS_PORT,
444 CASE_NETWORK_SERVICE_TLS_AUTHENTICATE_CLIENT,
445 CASE_NETWORK_SERVICE_TLS_NAME,
446 CASE_NETWORK_SERVICE_TLS_PORT,
447 // Obsoleted:
448 CASE_NETWORK_SERVICE_ALTERNATE_ADDRESS,
449 CASE_NETWORK_SERVICE_NETWORK_INTERFACE_NAME,
450 // Deprecated:
451 CASE_NETWORK_SERVICE_REUSE_ADDRESS,
452
453 // Network heartbeat options:
454 // Normally visible, in canonical configuration file order:
455 CASE_NETWORK_HEARTBEAT_MODE,
456 CASE_NETWORK_HEARTBEAT_ADDRESS,
457 CASE_NETWORK_HEARTBEAT_MULTICAST_GROUP,
458 CASE_NETWORK_HEARTBEAT_PORT,
459 CASE_NETWORK_HEARTBEAT_MESH_SEED_ADDRESS_PORT,
460 CASE_NETWORK_HEARTBEAT_INTERVAL,
461 CASE_NETWORK_HEARTBEAT_TIMEOUT,
462 // Normally hidden:
463 CASE_NETWORK_HEARTBEAT_MTU,
464 CASE_NETWORK_HEARTBEAT_MCAST_TTL, // renamed
465 CASE_NETWORK_HEARTBEAT_MULTICAST_TTL,
466 CASE_NETWORK_HEARTBEAT_PROTOCOL,
467 CASE_NETWORK_HEARTBEAT_TLS_ADDRESS,
468 CASE_NETWORK_HEARTBEAT_TLS_MESH_SEED_ADDRESS_PORT,
469 CASE_NETWORK_HEARTBEAT_TLS_NAME,
470 CASE_NETWORK_HEARTBEAT_TLS_PORT,
471 // Obsoleted:
472 CASE_NETWORK_HEARTBEAT_INTERFACE_ADDRESS,
473
474 // Network heartbeat mode options (value tokens):
475 CASE_NETWORK_HEARTBEAT_MODE_MESH,
476 CASE_NETWORK_HEARTBEAT_MODE_MULTICAST,
477
478 // Network heartbeat protocol options (value tokens):
479 CASE_NETWORK_HEARTBEAT_PROTOCOL_NONE,
480 CASE_NETWORK_HEARTBEAT_PROTOCOL_V3,
481
482 // Network fabric options:
483 // Normally visible, in canonical configuration file order:
484 CASE_NETWORK_FABRIC_ADDRESS,
485 CASE_NETWORK_FABRIC_PORT,
486 // Normally hidden:
487 CASE_NETWORK_FABRIC_CHANNEL_BULK_FDS,
488 CASE_NETWORK_FABRIC_CHANNEL_BULK_RECV_THREADS,
489 CASE_NETWORK_FABRIC_CHANNEL_CTRL_FDS,
490 CASE_NETWORK_FABRIC_CHANNEL_CTRL_RECV_THREADS,
491 CASE_NETWORK_FABRIC_CHANNEL_META_FDS,
492 CASE_NETWORK_FABRIC_CHANNEL_META_RECV_THREADS,
493 CASE_NETWORK_FABRIC_CHANNEL_RW_FDS,
494 CASE_NETWORK_FABRIC_CHANNEL_RW_RECV_THREADS,
495 CASE_NETWORK_FABRIC_KEEPALIVE_ENABLED,
496 CASE_NETWORK_FABRIC_KEEPALIVE_INTVL,
497 CASE_NETWORK_FABRIC_KEEPALIVE_PROBES,
498 CASE_NETWORK_FABRIC_KEEPALIVE_TIME,
499 CASE_NETWORK_FABRIC_LATENCY_MAX_MS,
500 CASE_NETWORK_FABRIC_RECV_REARM_THRESHOLD,
501 CASE_NETWORK_FABRIC_SEND_THREADS,
502 CASE_NETWORK_FABRIC_TLS_ADDRESS,
503 CASE_NETWORK_FABRIC_TLS_NAME,
504 CASE_NETWORK_FABRIC_TLS_PORT,
505
506 // Network info options:
507 // Normally visible, in canonical configuration file order:
508 CASE_NETWORK_INFO_ADDRESS,
509 CASE_NETWORK_INFO_PORT,
510 // Deprecated:
511 CASE_NETWORK_INFO_ENABLE_FASTPATH,
512
513 // Network TLS options:
514 CASE_NETWORK_TLS_CA_FILE,
515 CASE_NETWORK_TLS_CA_PATH,
516 CASE_NETWORK_TLS_CERT_BLACKLIST,
517 CASE_NETWORK_TLS_CERT_FILE,
518 CASE_NETWORK_TLS_CIPHER_SUITE,
519 CASE_NETWORK_TLS_KEY_FILE,
520 CASE_NETWORK_TLS_KEY_FILE_PASSWORD,
521 CASE_NETWORK_TLS_PROTOCOLS,
522
523 // Namespace options:
524 // Normally visible, in canonical configuration file order:
525 CASE_NAMESPACE_REPLICATION_FACTOR,
526 CASE_NAMESPACE_LIMIT_SIZE, // renamed
527 CASE_NAMESPACE_MEMORY_SIZE,
528 CASE_NAMESPACE_DEFAULT_TTL,
529 CASE_NAMESPACE_STORAGE_ENGINE_BEGIN,
530 // For XDR only:
531 CASE_NAMESPACE_ENABLE_XDR,
532 CASE_NAMESPACE_SETS_ENABLE_XDR,
533 CASE_NAMESPACE_XDR_REMOTE_DATACENTER,
534 CASE_NAMESPACE_FORWARD_XDR_WRITES,
535 CASE_NAMESPACE_ALLOW_NONXDR_WRITES,
536 CASE_NAMESPACE_ALLOW_XDR_WRITES,
537 // Normally hidden:
538 CASE_NAMESPACE_BACKGROUND_SCAN_MAX_RPS,
539 CASE_NAMESPACE_CONFLICT_RESOLUTION_POLICY,
540 CASE_NAMESPACE_DATA_IN_INDEX,
541 CASE_NAMESPACE_DISABLE_COLD_START_EVICTION,
542 CASE_NAMESPACE_DISABLE_WRITE_DUP_RES,
543 CASE_NAMESPACE_DISALLOW_NULL_SETNAME,
544 CASE_NAMESPACE_ENABLE_BENCHMARKS_BATCH_SUB,
545 CASE_NAMESPACE_ENABLE_BENCHMARKS_OPS_SUB,
546 CASE_NAMESPACE_ENABLE_BENCHMARKS_READ,
547 CASE_NAMESPACE_ENABLE_BENCHMARKS_UDF,
548 CASE_NAMESPACE_ENABLE_BENCHMARKS_UDF_SUB,
549 CASE_NAMESPACE_ENABLE_BENCHMARKS_WRITE,
550 CASE_NAMESPACE_ENABLE_HIST_PROXY,
551 CASE_NAMESPACE_EVICT_HIST_BUCKETS,
552 CASE_NAMESPACE_EVICT_TENTHS_PCT,
553 CASE_NAMESPACE_HIGH_WATER_DISK_PCT,
554 CASE_NAMESPACE_HIGH_WATER_MEMORY_PCT,
555 CASE_NAMESPACE_INDEX_STAGE_SIZE,
556 CASE_NAMESPACE_INDEX_TYPE_BEGIN,
557 CASE_NAMESPACE_MIGRATE_ORDER,
558 CASE_NAMESPACE_MIGRATE_RETRANSMIT_MS,
559 CASE_NAMESPACE_MIGRATE_SLEEP,
560 CASE_NAMESPACE_NSUP_HIST_PERIOD,
561 CASE_NAMESPACE_NSUP_PERIOD,
562 CASE_NAMESPACE_NSUP_THREADS,
563 CASE_NAMESPACE_PARTITION_TREE_SPRIGS,
564 CASE_NAMESPACE_PREFER_UNIFORM_BALANCE,
565 CASE_NAMESPACE_RACK_ID,
566 CASE_NAMESPACE_READ_CONSISTENCY_LEVEL_OVERRIDE,
567 CASE_NAMESPACE_SET_BEGIN,
568 CASE_NAMESPACE_SINDEX_BEGIN,
569 CASE_NAMESPACE_GEO2DSPHERE_WITHIN_BEGIN,
570 CASE_NAMESPACE_SINGLE_BIN,
571 CASE_NAMESPACE_SINGLE_SCAN_THREADS,
572 CASE_NAMESPACE_STOP_WRITES_PCT,
573 CASE_NAMESPACE_STRONG_CONSISTENCY,
574 CASE_NAMESPACE_STRONG_CONSISTENCY_ALLOW_EXPUNGE,
575 CASE_NAMESPACE_TOMB_RAIDER_ELIGIBLE_AGE,
576 CASE_NAMESPACE_TOMB_RAIDER_PERIOD,
577 CASE_NAMESPACE_TRANSACTION_PENDING_LIMIT,
578 CASE_NAMESPACE_TRUNCATE_THREADS,
579 CASE_NAMESPACE_WRITE_COMMIT_LEVEL_OVERRIDE,
580 // Obsoleted:
581 CASE_NAMESPACE_DISABLE_NSUP,
582 // Deprecated:
583 CASE_NAMESPACE_ALLOW_VERSIONS,
584 CASE_NAMESPACE_COLD_START_EVICT_TTL,
585 CASE_NAMESPACE_DEMO_READ_MULTIPLIER,
586 CASE_NAMESPACE_DEMO_WRITE_MULTIPLIER,
587 CASE_NAMESPACE_HIGH_WATER_PCT,
588 CASE_NAMESPACE_LOW_WATER_PCT,
589 CASE_NAMESPACE_MAX_TTL,
590 CASE_NAMESPACE_OBJ_SIZE_HIST_MAX,
591 CASE_NAMESPACE_PARTITION_TREE_LOCKS,
592 CASE_NAMESPACE_SI_BEGIN,
593
594 // Namespace conflict-resolution-policy options (value tokens):
595 CASE_NAMESPACE_CONFLICT_RESOLUTION_GENERATION,
596 CASE_NAMESPACE_CONFLICT_RESOLUTION_LAST_UPDATE_TIME,
597
598 // Namespace read consistency level options:
599 CASE_NAMESPACE_READ_CONSISTENCY_ALL,
600 CASE_NAMESPACE_READ_CONSISTENCY_OFF,
601 CASE_NAMESPACE_READ_CONSISTENCY_ONE,
602
603 // Namespace write commit level options:
604 CASE_NAMESPACE_WRITE_COMMIT_ALL,
605 CASE_NAMESPACE_WRITE_COMMIT_MASTER,
606 CASE_NAMESPACE_WRITE_COMMIT_OFF,
607
608 // Namespace index-type options (value tokens):
609 CASE_NAMESPACE_INDEX_TYPE_SHMEM,
610 CASE_NAMESPACE_INDEX_TYPE_PMEM,
611 CASE_NAMESPACE_INDEX_TYPE_FLASH,
612
613 // Namespace storage-engine options (value tokens):
614 CASE_NAMESPACE_STORAGE_MEMORY,
615 CASE_NAMESPACE_STORAGE_SSD,
616 CASE_NAMESPACE_STORAGE_DEVICE,
617
618 // Namespace index-type pmem options:
619 CASE_NAMESPACE_INDEX_TYPE_PMEM_MOUNT,
620 CASE_NAMESPACE_INDEX_TYPE_PMEM_MOUNTS_HIGH_WATER_PCT,
621 CASE_NAMESPACE_INDEX_TYPE_PMEM_MOUNTS_SIZE_LIMIT,
622
623 // Namespace index-type flash options:
624 CASE_NAMESPACE_INDEX_TYPE_FLASH_MOUNT,
625 CASE_NAMESPACE_INDEX_TYPE_FLASH_MOUNTS_HIGH_WATER_PCT,
626 CASE_NAMESPACE_INDEX_TYPE_FLASH_MOUNTS_SIZE_LIMIT,
627
628 // Namespace storage-engine device options:
629 // Normally visible, in canonical configuration file order:
630 CASE_NAMESPACE_STORAGE_DEVICE_DEVICE,
631 CASE_NAMESPACE_STORAGE_DEVICE_FILE,
632 CASE_NAMESPACE_STORAGE_DEVICE_FILESIZE,
633 CASE_NAMESPACE_STORAGE_DEVICE_SCHEDULER_MODE,
634 CASE_NAMESPACE_STORAGE_DEVICE_WRITE_BLOCK_SIZE,
635 CASE_NAMESPACE_STORAGE_DEVICE_MEMORY_ALL, // renamed
636 CASE_NAMESPACE_STORAGE_DEVICE_DATA_IN_MEMORY,
637 // Normally hidden:
638 CASE_NAMESPACE_STORAGE_DEVICE_COLD_START_EMPTY,
639 CASE_NAMESPACE_STORAGE_DEVICE_COMMIT_TO_DEVICE,
640 CASE_NAMESPACE_STORAGE_DEVICE_COMMIT_MIN_SIZE,
641 CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION,
642 CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_LEVEL,
643 CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_LWM_PCT,
644 CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_QUEUE_MIN,
645 CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_SLEEP,
646 CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_STARTUP_MINIMUM,
647 CASE_NAMESPACE_STORAGE_DEVICE_DIRECT_FILES,
648 CASE_NAMESPACE_STORAGE_DEVICE_DISABLE_ODSYNC,
649 CASE_NAMESPACE_STORAGE_DEVICE_ENABLE_BENCHMARKS_STORAGE,
650 CASE_NAMESPACE_STORAGE_DEVICE_ENCRYPTION,
651 CASE_NAMESPACE_STORAGE_DEVICE_ENCRYPTION_KEY_FILE,
652 CASE_NAMESPACE_STORAGE_DEVICE_FLUSH_MAX_MS,
653 CASE_NAMESPACE_STORAGE_DEVICE_MAX_WRITE_CACHE,
654 CASE_NAMESPACE_STORAGE_DEVICE_MIN_AVAIL_PCT,
655 CASE_NAMESPACE_STORAGE_DEVICE_POST_WRITE_QUEUE,
656 CASE_NAMESPACE_STORAGE_DEVICE_READ_PAGE_CACHE,
657 CASE_NAMESPACE_STORAGE_DEVICE_SERIALIZE_TOMB_RAIDER,
658 CASE_NAMESPACE_STORAGE_DEVICE_TOMB_RAIDER_SLEEP,
659 // Obsoleted:
660 CASE_NAMESPACE_STORAGE_DEVICE_DISABLE_ODIRECT,
661 CASE_NAMESPACE_STORAGE_DEVICE_FSYNC_MAX_SEC,
662 // Deprecated:
663 CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_MAX_BLOCKS,
664 CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_PERIOD,
665 CASE_NAMESPACE_STORAGE_DEVICE_ENABLE_OSYNC,
666 CASE_NAMESPACE_STORAGE_DEVICE_LOAD_AT_STARTUP,
667 CASE_NAMESPACE_STORAGE_DEVICE_PERSIST,
668 CASE_NAMESPACE_STORAGE_DEVICE_READONLY,
669 CASE_NAMESPACE_STORAGE_DEVICE_SIGNATURE,
670 CASE_NAMESPACE_STORAGE_DEVICE_WRITE_SMOOTHING_PERIOD,
671 CASE_NAMESPACE_STORAGE_DEVICE_WRITE_THREADS,
672
673 // Namespace storage device compression options (value tokens):
674 CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_NONE,
675 CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_LZ4,
676 CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_SNAPPY,
677 CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_ZSTD,
678
679 // Namespace storage device encryption options (value tokens):
680 CASE_NAMESPACE_STORAGE_DEVICE_ENCRYPTION_AES_128,
681 CASE_NAMESPACE_STORAGE_DEVICE_ENCRYPTION_AES_256,
682
683 // Namespace set options:
684 CASE_NAMESPACE_SET_DISABLE_EVICTION,
685 CASE_NAMESPACE_SET_ENABLE_XDR,
686 CASE_NAMESPACE_SET_STOP_WRITES_COUNT,
687 // Deprecated:
688 CASE_NAMESPACE_SET_EVICT_HWM_COUNT,
689 CASE_NAMESPACE_SET_EVICT_HWM_PCT,
690 CASE_NAMESPACE_SET_STOP_WRITE_COUNT,
691 CASE_NAMESPACE_SET_STOP_WRITE_PCT,
692
693 // Namespace set set-enable-xdr options (value tokens):
694 CASE_NAMESPACE_SET_ENABLE_XDR_USE_DEFAULT,
695 CASE_NAMESPACE_SET_ENABLE_XDR_FALSE,
696 CASE_NAMESPACE_SET_ENABLE_XDR_TRUE,
697
698 // Namespace secondary-index options:
699 // Deprecated:
700 CASE_NAMESPACE_SI_GC_PERIOD,
701 CASE_NAMESPACE_SI_GC_MAX_UNITS,
702 CASE_NAMESPACE_SI_HISTOGRAM,
703 CASE_NAMESPACE_SI_IGNORE_NOT_SYNC,
704
705 // Namespace sindex options:
706 CASE_NAMESPACE_SINDEX_NUM_PARTITIONS,
707
708 // Namespace geo2dsphere within options:
709 CASE_NAMESPACE_GEO2DSPHERE_WITHIN_STRICT,
710 CASE_NAMESPACE_GEO2DSPHERE_WITHIN_MIN_LEVEL,
711 CASE_NAMESPACE_GEO2DSPHERE_WITHIN_MAX_LEVEL,
712 CASE_NAMESPACE_GEO2DSPHERE_WITHIN_MAX_CELLS,
713 CASE_NAMESPACE_GEO2DSPHERE_WITHIN_LEVEL_MOD,
714 CASE_NAMESPACE_GEO2DSPHERE_WITHIN_EARTH_RADIUS_METERS,
715
716 // Mod-lua options:
717 CASE_MOD_LUA_CACHE_ENABLED,
718 CASE_MOD_LUA_USER_PATH,
719 // Deprecated:
720 CASE_MOD_LUA_SYSTEM_PATH,
721
722 // Security options:
723 CASE_SECURITY_ENABLE_LDAP,
724 CASE_SECURITY_ENABLE_SECURITY,
725 CASE_SECURITY_LDAP_LOGIN_THREADS,
726 CASE_SECURITY_PRIVILEGE_REFRESH_PERIOD,
727 CASE_SECURITY_LDAP_BEGIN,
728 CASE_SECURITY_LOG_BEGIN,
729 CASE_SECURITY_SYSLOG_BEGIN,
730
731 // Security LDAP options:
732 CASE_SECURITY_LDAP_DISABLE_TLS,
733 CASE_SECURITY_LDAP_POLLING_PERIOD,
734 CASE_SECURITY_LDAP_QUERY_BASE_DN,
735 CASE_SECURITY_LDAP_QUERY_USER_DN,
736 CASE_SECURITY_LDAP_QUERY_USER_PASSWORD_FILE,
737 CASE_SECURITY_LDAP_ROLE_QUERY_BASE_DN,
738 CASE_SECURITY_LDAP_ROLE_QUERY_PATTERN,
739 CASE_SECURITY_LDAP_ROLE_QUERY_SEARCH_OU,
740 CASE_SECURITY_LDAP_SERVER,
741 CASE_SECURITY_LDAP_SESSION_TTL,
742 CASE_SECURITY_LDAP_TLS_CA_FILE,
743 CASE_SECURITY_LDAP_TOKEN_HASH_METHOD,
744 CASE_SECURITY_LDAP_USER_DN_PATTERN,
745 CASE_SECURITY_LDAP_USER_QUERY_PATTERN,
746
747 // Security LDAP token encryption options (value tokens):
748 CASE_SECURITY_LDAP_TOKEN_HASH_METHOD_SHA_256,
749 CASE_SECURITY_LDAP_TOKEN_HASH_METHOD_SHA_512,
750
751 // Security (Aerospike) log options:
752 CASE_SECURITY_LOG_REPORT_AUTHENTICATION,
753 CASE_SECURITY_LOG_REPORT_DATA_OP,
754 CASE_SECURITY_LOG_REPORT_SYS_ADMIN,
755 CASE_SECURITY_LOG_REPORT_USER_ADMIN,
756 CASE_SECURITY_LOG_REPORT_VIOLATION,
757
758 // Security syslog options:
759 CASE_SECURITY_SYSLOG_LOCAL,
760 CASE_SECURITY_SYSLOG_REPORT_AUTHENTICATION,
761 CASE_SECURITY_SYSLOG_REPORT_DATA_OP,
762 CASE_SECURITY_SYSLOG_REPORT_SYS_ADMIN,
763 CASE_SECURITY_SYSLOG_REPORT_USER_ADMIN,
764 CASE_SECURITY_SYSLOG_REPORT_VIOLATION,
765
766 // XDR options:
767 // Normally visible, in canonical configuration file order:
768 CASE_XDR_ENABLE_XDR,
769 CASE_XDR_ENABLE_CHANGE_NOTIFICATION,
770 CASE_XDR_DIGESTLOG_PATH,
771 CASE_XDR_DATACENTER_BEGIN,
772 // Normally hidden:
773 CASE_XDR_CLIENT_THREADS,
774 CASE_XDR_COMPRESSION_THRESHOLD,
775 CASE_XDR_DELETE_SHIPPING_ENABLED,
776 CASE_XDR_DIGESTLOG_IOWAIT_MS,
777 CASE_XDR_FORWARD_XDR_WRITES,
778 CASE_XDR_HOTKEY_TIME_MS,
779 CASE_XDR_INFO_PORT,
780 CASE_XDR_INFO_TIMEOUT,
781 CASE_XDR_MAX_SHIP_BANDWIDTH,
782 CASE_XDR_MAX_SHIP_THROUGHPUT,
783 CASE_XDR_MIN_DIGESTLOG_FREE_PCT,
784 CASE_XDR_NSUP_DELETES_ENABLED,
785 CASE_XDR_READ_THREADS,
786 CASE_XDR_SHIP_BINS,
787 CASE_XDR_SHIP_DELAY,
788 CASE_XDR_SHIPPING_ENABLED,
789 CASE_XDR_WRITE_TIMEOUT,
790
791 // XDR (remote) datacenter options:
792 // Normally visible, in canonical configuration file order:
793 CASE_XDR_DATACENTER_DC_NODE_ADDRESS_PORT,
794 // Normally hidden:
795 CASE_XDR_DATACENTER_AUTH_MODE,
796 CASE_XDR_DATACENTER_DC_CONNECTIONS,
797 CASE_XDR_DATACENTER_DC_CONNECTIONS_IDLE_MS,
798 CASE_XDR_DATACENTER_DC_INT_EXT_IPMAP,
799 CASE_XDR_DATACENTER_DC_SECURITY_CONFIG_FILE,
800 CASE_XDR_DATACENTER_DC_SHIP_BINS,
801 CASE_XDR_DATACENTER_DC_TYPE,
802 CASE_XDR_DATACENTER_DC_USE_ALTERNATE_SERVICES,
803 CASE_XDR_DATACENTER_HTTP_URL,
804 CASE_XDR_DATACENTER_HTTP_VERSION,
805 CASE_XDR_DATACENTER_TLS_NAME,
806 CASE_XDR_DATACENTER_TLS_NODE,
807
808 // XDR datacenter authentication mode (value tokens):
809 CASE_XDR_DATACENTER_AUTH_MODE_INTERNAL,
810 CASE_XDR_DATACENTER_AUTH_MODE_EXTERNAL,
811 CASE_XDR_DATACENTER_AUTH_MODE_EXTERNAL_INSECURE,
812
813 // Used parsing separate file, but share this enum:
814
815 // XDR security top-level options:
816 XDR_SEC_CASE_CREDENTIALS_BEGIN,
817
818 // XDR security credentials options:
819 // Normally visible, in canonical configuration file order:
820 XDR_SEC_CASE_CREDENTIALS_USERNAME,
821 XDR_SEC_CASE_CREDENTIALS_PASSWORD
822
823} cfg_case_id;
824
825
826//==========================================================
827// All configuration items must appear below as a cfg_opt
828// struct in the appropriate array. Order within an array is
829// not important, other than for organizational sanity.
830//
831
832typedef struct cfg_opt_s {
833 const char* tok;
834 cfg_case_id case_id;
835} cfg_opt;
836
837const cfg_opt GLOBAL_OPTS[] = {
838 { "service", CASE_SERVICE_BEGIN },
839 { "logging", CASE_LOGGING_BEGIN },
840 { "network", CASE_NETWORK_BEGIN },
841 { "namespace", CASE_NAMESPACE_BEGIN },
842 { "mod-lua", CASE_MOD_LUA_BEGIN },
843 { "cluster", CASE_CLUSTER_BEGIN },
844 { "security", CASE_SECURITY_BEGIN },
845 { "xdr", CASE_XDR_BEGIN }
846};
847
848const cfg_opt SERVICE_OPTS[] = {
849 { "user", CASE_SERVICE_USER },
850 { "group", CASE_SERVICE_GROUP },
851 { "paxos-single-replica-limit", CASE_SERVICE_PAXOS_SINGLE_REPLICA_LIMIT },
852 { "pidfile", CASE_SERVICE_PIDFILE },
853 { "client-fd-max", CASE_SERVICE_CLIENT_FD_MAX },
854 { "proto-fd-max", CASE_SERVICE_PROTO_FD_MAX },
855 { "advertise-ipv6", CASE_SERVICE_ADVERTISE_IPV6 },
856 { "auto-pin", CASE_SERVICE_AUTO_PIN },
857 { "batch-index-threads", CASE_SERVICE_BATCH_INDEX_THREADS },
858 { "batch-max-buffers-per-queue", CASE_SERVICE_BATCH_MAX_BUFFERS_PER_QUEUE },
859 { "batch-max-requests", CASE_SERVICE_BATCH_MAX_REQUESTS },
860 { "batch-max-unused-buffers", CASE_SERVICE_BATCH_MAX_UNUSED_BUFFERS },
861 { "cluster-name", CASE_SERVICE_CLUSTER_NAME },
862 { "enable-benchmarks-fabric", CASE_SERVICE_ENABLE_BENCHMARKS_FABRIC },
863 { "enable-benchmarks-svc", CASE_SERVICE_ENABLE_BENCHMARKS_SVC },
864 { "enable-health-check", CASE_SERVICE_ENABLE_HEALTH_CHECK },
865 { "enable-hist-info", CASE_SERVICE_ENABLE_HIST_INFO },
866 { "feature-key-file", CASE_SERVICE_FEATURE_KEY_FILE },
867 { "hist-track-back", CASE_SERVICE_HIST_TRACK_BACK },
868 { "hist-track-slice", CASE_SERVICE_HIST_TRACK_SLICE },
869 { "hist-track-thresholds", CASE_SERVICE_HIST_TRACK_THRESHOLDS },
870 { "info-threads", CASE_SERVICE_INFO_THREADS },
871 { "keep-caps-ssd-health", CASE_SERVICE_KEEP_CAPS_SSD_HEALTH },
872 { "log-local-time", CASE_SERVICE_LOG_LOCAL_TIME },
873 { "log-millis", CASE_SERVICE_LOG_MILLIS},
874 { "migrate-fill-delay", CASE_SERVICE_MIGRATE_FILL_DELAY },
875 { "migrate-max-num-incoming", CASE_SERVICE_MIGRATE_MAX_NUM_INCOMING },
876 { "migrate-threads", CASE_SERVICE_MIGRATE_THREADS },
877 { "min-cluster-size", CASE_SERVICE_MIN_CLUSTER_SIZE },
878 { "node-id", CASE_SERVICE_NODE_ID },
879 { "node-id-interface", CASE_SERVICE_NODE_ID_INTERFACE },
880 { "proto-fd-idle-ms", CASE_SERVICE_PROTO_FD_IDLE_MS },
881 { "query-batch-size", CASE_SERVICE_QUERY_BATCH_SIZE },
882 { "query-bufpool-size", CASE_SERVICE_QUERY_BUFPOOL_SIZE },
883 { "query-in-transaction-thread", CASE_SERVICE_QUERY_IN_TRANSACTION_THREAD },
884 { "query-long-q-max-size", CASE_SERVICE_QUERY_LONG_Q_MAX_SIZE },
885 { "query-pre-reserve-partitions", CASE_SERVICE_QUERY_PRE_RESERVE_PARTITIONS },
886 { "query-priority", CASE_SERVICE_QUERY_PRIORITY },
887 { "query-priority-sleep-us", CASE_SERVICE_QUERY_PRIORITY_SLEEP_US },
888 { "query-rec-count-bound", CASE_SERVICE_QUERY_REC_COUNT_BOUND },
889 { "query-req-in-query-thread", CASE_SERVICE_QUERY_REQ_IN_QUERY_THREAD },
890 { "query-req-max-inflight", CASE_SERVICE_QUERY_REQ_MAX_INFLIGHT },
891 { "query-short-q-max-size", CASE_SERVICE_QUERY_SHORT_Q_MAX_SIZE },
892 { "query-threads", CASE_SERVICE_QUERY_THREADS },
893 { "query-threshold", CASE_SERVICE_QUERY_THRESHOLD },
894 { "query-untracked-time-ms", CASE_SERVICE_QUERY_UNTRACKED_TIME_MS },
895 { "query-worker-threads", CASE_SERVICE_QUERY_WORKER_THREADS },
896 { "run-as-daemon", CASE_SERVICE_RUN_AS_DAEMON },
897 { "scan-max-done", CASE_SERVICE_SCAN_MAX_DONE },
898 { "scan-threads-limit", CASE_SERVICE_SCAN_THREADS_LIMIT },
899 { "service-threads", CASE_SERVICE_SERVICE_THREADS },
900 { "sindex-builder-threads", CASE_SERVICE_SINDEX_BUILDER_THREADS },
901 { "sindex-gc-max-rate", CASE_SERVICE_SINDEX_GC_MAX_RATE },
902 { "sindex-gc-period", CASE_SERVICE_SINDEX_GC_PERIOD },
903 { "ticker-interval", CASE_SERVICE_TICKER_INTERVAL },
904 { "transaction-max-ms", CASE_SERVICE_TRANSACTION_MAX_MS },
905 { "transaction-retry-ms", CASE_SERVICE_TRANSACTION_RETRY_MS },
906 { "work-directory", CASE_SERVICE_WORK_DIRECTORY },
907 { "debug-allocations", CASE_SERVICE_DEBUG_ALLOCATIONS },
908 { "fabric-dump-msgs", CASE_SERVICE_FABRIC_DUMP_MSGS },
909 { "indent-allocations", CASE_SERVICE_INDENT_ALLOCATIONS },
910 { "allow-inline-transactions", CASE_SERVICE_ALLOW_INLINE_TRANSACTIONS },
911 { "nsup-period", CASE_SERVICE_NSUP_PERIOD },
912 { "object-size-hist-period", CASE_SERVICE_OBJECT_SIZE_HIST_PERIOD },
913 { "respond-client-on-master-completion", CASE_SERVICE_RESPOND_CLIENT_ON_MASTER_COMPLETION },
914 { "scan-max-udf-transactions", CASE_SERVICE_SCAN_MAX_UDF_TRANSACTIONS },
915 { "scan-threads", CASE_SERVICE_SCAN_THREADS },
916 { "transaction-pending-limit", CASE_SERVICE_TRANSACTION_PENDING_LIMIT },
917 { "transaction-queues", CASE_SERVICE_TRANSACTION_QUEUES },
918 { "transaction-repeatable-read", CASE_SERVICE_TRANSACTION_REPEATABLE_READ },
919 { "transaction-threads-per-queue", CASE_SERVICE_TRANSACTION_THREADS_PER_QUEUE },
920 { "auto-dun", CASE_SERVICE_AUTO_DUN },
921 { "auto-undun", CASE_SERVICE_AUTO_UNDUN },
922 { "batch-priority", CASE_SERVICE_BATCH_PRIORITY },
923 { "batch-retransmit", CASE_SERVICE_BATCH_RETRANSMIT },
924 { "batch-threads", CASE_SERVICE_BATCH_THREADS },
925 { "clib-library", CASE_SERVICE_CLIB_LIBRARY },
926 { "defrag-queue-escape", CASE_SERVICE_DEFRAG_QUEUE_ESCAPE },
927 { "defrag-queue-hwm", CASE_SERVICE_DEFRAG_QUEUE_HWM },
928 { "defrag-queue-lwm", CASE_SERVICE_DEFRAG_QUEUE_LWM },
929 { "defrag-queue-priority", CASE_SERVICE_DEFRAG_QUEUE_PRIORITY },
930 { "dump-message-above-size", CASE_SERVICE_DUMP_MESSAGE_ABOVE_SIZE },
931 { "fabric-workers", CASE_SERVICE_FABRIC_WORKERS },
932 { "fb-health-bad-pct", CASE_SERVICE_FB_HEALTH_BAD_PCT },
933 { "fb-health-good-pct", CASE_SERVICE_FB_HEALTH_GOOD_PCT },
934 { "fb-health-msg-per-burst", CASE_SERVICE_FB_HEALTH_MSG_PER_BURST },
935 { "fb-health-msg-timeout", CASE_SERVICE_FB_HEALTH_MSG_TIMEOUT },
936 { "generation-disable", CASE_SERVICE_GENERATION_DISABLE },
937 { "max-msgs-per-type", CASE_SERVICE_MAX_MSGS_PER_TYPE },
938 { "migrate-read-priority", CASE_SERVICE_MIGRATE_READ_PRIORITY },
939 { "migrate-read-sleep", CASE_SERVICE_MIGRATE_READ_SLEEP },
940 { "migrate-rx-lifetime-ms", CASE_SERVICE_MIGRATE_RX_LIFETIME_MS },
941 { "migrate-xmit-hwm", CASE_SERVICE_MIGRATE_XMIT_HWM },
942 { "migrate-xmit-lwm", CASE_SERVICE_MIGRATE_XMIT_LWM },
943 { "migrate-priority", CASE_SERVICE_MIGRATE_PRIORITY },
944 { "migrate-xmit-priority", CASE_SERVICE_MIGRATE_XMIT_PRIORITY },
945 { "migrate-xmit-sleep", CASE_SERVICE_MIGRATE_XMIT_SLEEP },
946 { "nsup-auto-hwm", CASE_SERVICE_NSUP_AUTO_HWM },
947 { "nsup-auto-hwm-pct", CASE_SERVICE_NSUP_AUTO_HWM_PCT },
948 { "nsup-delete-sleep", CASE_SERVICE_NSUP_DELETE_SLEEP },
949 { "nsup-max-deletes", CASE_SERVICE_NSUP_MAX_DELETES },
950 { "nsup-queue-escape", CASE_SERVICE_NSUP_QUEUE_ESCAPE },
951 { "nsup-queue-hwm", CASE_SERVICE_NSUP_QUEUE_HWM },
952 { "nsup-queue-lwm", CASE_SERVICE_NSUP_QUEUE_LWM },
953 { "nsup-reduce-priority", CASE_SERVICE_NSUP_REDUCE_PRIORITY },
954 { "nsup-reduce-sleep", CASE_SERVICE_NSUP_REDUCE_SLEEP },
955 { "nsup-startup-evict", CASE_SERVICE_NSUP_STARTUP_EVICT },
956 { "nsup-threads", CASE_SERVICE_NSUP_THREADS },
957 { "paxos-max-cluster-size", CASE_SERVICE_PAXOS_MAX_CLUSTER_SIZE },
958 { "paxos-protocol", CASE_SERVICE_PAXOS_PROTOCOL },
959 { "paxos-recovery-policy", CASE_SERVICE_PAXOS_RECOVERY_POLICY },
960 { "paxos-retransmit-period", CASE_SERVICE_PAXOS_RETRANSMIT_PERIOD },
961 { "prole-extra-ttl", CASE_SERVICE_PROLE_EXTRA_TTL },
962 { "replication-fire-and-forget", CASE_SERVICE_REPLICATION_FIRE_AND_FORGET },
963 { "scan-max-active", CASE_SERVICE_SCAN_MAX_ACTIVE },
964 { "scan-memory", CASE_SERVICE_SCAN_MEMORY },
965 { "scan-priority", CASE_SERVICE_SCAN_PRIORITY },
966 { "scan-retransmit", CASE_SERVICE_SCAN_RETRANSMIT },
967 { "scheduler-priority", CASE_SERVICE_SCHEDULER_PRIORITY },
968 { "scheduler-type", CASE_SERVICE_SCHEDULER_TYPE },
969 { "transaction-duplicate-threads", CASE_SERVICE_TRANSACTION_DUPLICATE_THREADS },
970 { "trial-account-key", CASE_SERVICE_TRIAL_ACCOUNT_KEY },
971 { "udf-runtime-max-gmemory", CASE_SERVICE_UDF_RUNTIME_MAX_GMEMORY },
972 { "udf-runtime-max-memory", CASE_SERVICE_UDF_RUNTIME_MAX_MEMORY },
973 { "use-queue-per-device", CASE_SERVICE_USE_QUEUE_PER_DEVICE },
974 { "write-duplicate-resolution-disable", CASE_SERVICE_WRITE_DUPLICATE_RESOLUTION_DISABLE },
975 { "}", CASE_CONTEXT_END }
976};
977
978const cfg_opt SERVICE_AUTO_PIN_OPTS[] = {
979 { "none", CASE_SERVICE_AUTO_PIN_NONE },
980 { "cpu", CASE_SERVICE_AUTO_PIN_CPU },
981 { "numa", CASE_SERVICE_AUTO_PIN_NUMA },
982 { "adq", CASE_SERVICE_AUTO_PIN_ADQ }
983};
984
985const cfg_opt SERVICE_DEBUG_ALLOCATIONS_OPTS[] = {
986 { "none", CASE_SERVICE_DEBUG_ALLOCATIONS_NONE },
987 { "transient", CASE_SERVICE_DEBUG_ALLOCATIONS_TRANSIENT },
988 { "persistent", CASE_SERVICE_DEBUG_ALLOCATIONS_PERSISTENT },
989 { "all", CASE_SERVICE_DEBUG_ALLOCATIONS_ALL }
990};
991
992const cfg_opt LOGGING_OPTS[] = {
993 { "file", CASE_LOG_FILE_BEGIN },
994 { "console", CASE_LOG_CONSOLE_BEGIN },
995 { "}", CASE_CONTEXT_END }
996};
997
998const cfg_opt LOGGING_FILE_OPTS[] = {
999 { "context", CASE_LOG_FILE_CONTEXT },
1000 { "}", CASE_CONTEXT_END }
1001};
1002
1003const cfg_opt LOGGING_CONSOLE_OPTS[] = {
1004 { "context", CASE_LOG_CONSOLE_CONTEXT },
1005 { "}", CASE_CONTEXT_END }
1006};
1007
1008const cfg_opt NETWORK_OPTS[] = {
1009 { "service", CASE_NETWORK_SERVICE_BEGIN },
1010 { "heartbeat", CASE_NETWORK_HEARTBEAT_BEGIN },
1011 { "fabric", CASE_NETWORK_FABRIC_BEGIN },
1012 { "info", CASE_NETWORK_INFO_BEGIN },
1013 { "tls", CASE_NETWORK_TLS_BEGIN },
1014 { "}", CASE_CONTEXT_END }
1015};
1016
1017const cfg_opt NETWORK_SERVICE_OPTS[] = {
1018 { "address", CASE_NETWORK_SERVICE_ADDRESS },
1019 { "port", CASE_NETWORK_SERVICE_PORT },
1020 { "external-address", CASE_NETWORK_SERVICE_EXTERNAL_ADDRESS },
1021 { "access-address", CASE_NETWORK_SERVICE_ACCESS_ADDRESS },
1022 { "access-port", CASE_NETWORK_SERVICE_ACCESS_PORT },
1023 { "alternate-access-address", CASE_NETWORK_SERVICE_ALTERNATE_ACCESS_ADDRESS },
1024 { "alternate-access-port", CASE_NETWORK_SERVICE_ALTERNATE_ACCESS_PORT },
1025 { "tls-access-address", CASE_NETWORK_SERVICE_TLS_ACCESS_ADDRESS },
1026 { "tls-access-port", CASE_NETWORK_SERVICE_TLS_ACCESS_PORT },
1027 { "tls-address", CASE_NETWORK_SERVICE_TLS_ADDRESS },
1028 { "tls-alternate-access-address", CASE_NETWORK_SERVICE_TLS_ALTERNATE_ACCESS_ADDRESS },
1029 { "tls-alternate-access-port", CASE_NETWORK_SERVICE_TLS_ALTERNATE_ACCESS_PORT },
1030 { "tls-authenticate-client", CASE_NETWORK_SERVICE_TLS_AUTHENTICATE_CLIENT },
1031 { "tls-name", CASE_NETWORK_SERVICE_TLS_NAME },
1032 { "tls-port", CASE_NETWORK_SERVICE_TLS_PORT },
1033 { "alternate-address", CASE_NETWORK_SERVICE_ALTERNATE_ADDRESS },
1034 { "network-interface-name", CASE_NETWORK_SERVICE_NETWORK_INTERFACE_NAME },
1035 { "reuse-address", CASE_NETWORK_SERVICE_REUSE_ADDRESS },
1036 { "}", CASE_CONTEXT_END }
1037};
1038
1039const cfg_opt NETWORK_HEARTBEAT_OPTS[] = {
1040 { "mode", CASE_NETWORK_HEARTBEAT_MODE },
1041 { "address", CASE_NETWORK_HEARTBEAT_ADDRESS },
1042 { "multicast-group", CASE_NETWORK_HEARTBEAT_MULTICAST_GROUP },
1043 { "port", CASE_NETWORK_HEARTBEAT_PORT },
1044 { "mesh-seed-address-port", CASE_NETWORK_HEARTBEAT_MESH_SEED_ADDRESS_PORT },
1045 { "interval", CASE_NETWORK_HEARTBEAT_INTERVAL },
1046 { "timeout", CASE_NETWORK_HEARTBEAT_TIMEOUT },
1047 { "mtu", CASE_NETWORK_HEARTBEAT_MTU },
1048 { "mcast-ttl", CASE_NETWORK_HEARTBEAT_MCAST_TTL },
1049 { "multicast-ttl", CASE_NETWORK_HEARTBEAT_MULTICAST_TTL },
1050 { "protocol", CASE_NETWORK_HEARTBEAT_PROTOCOL },
1051 { "tls-address", CASE_NETWORK_HEARTBEAT_TLS_ADDRESS },
1052 { "tls-mesh-seed-address-port", CASE_NETWORK_HEARTBEAT_TLS_MESH_SEED_ADDRESS_PORT },
1053 { "tls-name", CASE_NETWORK_HEARTBEAT_TLS_NAME },
1054 { "tls-port", CASE_NETWORK_HEARTBEAT_TLS_PORT },
1055 { "interface-address", CASE_NETWORK_HEARTBEAT_INTERFACE_ADDRESS },
1056 { "}", CASE_CONTEXT_END }
1057};
1058
1059const cfg_opt NETWORK_HEARTBEAT_MODE_OPTS[] = {
1060 { "mesh", CASE_NETWORK_HEARTBEAT_MODE_MESH },
1061 { "multicast", CASE_NETWORK_HEARTBEAT_MODE_MULTICAST }
1062};
1063
1064const cfg_opt NETWORK_HEARTBEAT_PROTOCOL_OPTS[] = {
1065 { "none", CASE_NETWORK_HEARTBEAT_PROTOCOL_NONE },
1066 { "v3", CASE_NETWORK_HEARTBEAT_PROTOCOL_V3}
1067};
1068
1069const cfg_opt NETWORK_FABRIC_OPTS[] = {
1070 { "address", CASE_NETWORK_FABRIC_ADDRESS },
1071 { "port", CASE_NETWORK_FABRIC_PORT },
1072 { "channel-bulk-fds", CASE_NETWORK_FABRIC_CHANNEL_BULK_FDS },
1073 { "channel-bulk-recv-threads", CASE_NETWORK_FABRIC_CHANNEL_BULK_RECV_THREADS },
1074 { "channel-ctrl-fds", CASE_NETWORK_FABRIC_CHANNEL_CTRL_FDS },
1075 { "channel-ctrl-recv-threads", CASE_NETWORK_FABRIC_CHANNEL_CTRL_RECV_THREADS },
1076 { "channel-meta-fds", CASE_NETWORK_FABRIC_CHANNEL_META_FDS },
1077 { "channel-meta-recv-threads", CASE_NETWORK_FABRIC_CHANNEL_META_RECV_THREADS },
1078 { "channel-rw-fds", CASE_NETWORK_FABRIC_CHANNEL_RW_FDS },
1079 { "channel-rw-recv-threads", CASE_NETWORK_FABRIC_CHANNEL_RW_RECV_THREADS },
1080 { "keepalive-enabled", CASE_NETWORK_FABRIC_KEEPALIVE_ENABLED },
1081 { "keepalive-intvl", CASE_NETWORK_FABRIC_KEEPALIVE_INTVL },
1082 { "keepalive-probes", CASE_NETWORK_FABRIC_KEEPALIVE_PROBES },
1083 { "keepalive-time", CASE_NETWORK_FABRIC_KEEPALIVE_TIME },
1084 { "latency-max-ms", CASE_NETWORK_FABRIC_LATENCY_MAX_MS },
1085 { "recv-rearm-threshold", CASE_NETWORK_FABRIC_RECV_REARM_THRESHOLD },
1086 { "send-threads", CASE_NETWORK_FABRIC_SEND_THREADS },
1087 { "tls-address", CASE_NETWORK_FABRIC_TLS_ADDRESS },
1088 { "tls-name", CASE_NETWORK_FABRIC_TLS_NAME },
1089 { "tls-port", CASE_NETWORK_FABRIC_TLS_PORT },
1090 { "}", CASE_CONTEXT_END }
1091};
1092
1093const cfg_opt NETWORK_INFO_OPTS[] = {
1094 { "address", CASE_NETWORK_INFO_ADDRESS },
1095 { "port", CASE_NETWORK_INFO_PORT },
1096 { "enable-fastpath", CASE_NETWORK_INFO_ENABLE_FASTPATH },
1097 { "}", CASE_CONTEXT_END }
1098};
1099
1100const cfg_opt NETWORK_TLS_OPTS[] = {
1101 { "ca-file", CASE_NETWORK_TLS_CA_FILE },
1102 { "ca-path", CASE_NETWORK_TLS_CA_PATH },
1103 { "cert-blacklist", CASE_NETWORK_TLS_CERT_BLACKLIST },
1104 { "cert-file", CASE_NETWORK_TLS_CERT_FILE },
1105 { "cipher-suite", CASE_NETWORK_TLS_CIPHER_SUITE },
1106 { "key-file", CASE_NETWORK_TLS_KEY_FILE },
1107 { "key-file-password", CASE_NETWORK_TLS_KEY_FILE_PASSWORD },
1108 { "protocols", CASE_NETWORK_TLS_PROTOCOLS },
1109 { "}", CASE_CONTEXT_END }
1110};
1111
1112const cfg_opt NAMESPACE_OPTS[] = {
1113 { "replication-factor", CASE_NAMESPACE_REPLICATION_FACTOR },
1114 { "limit-size", CASE_NAMESPACE_LIMIT_SIZE },
1115 { "memory-size", CASE_NAMESPACE_MEMORY_SIZE },
1116 { "default-ttl", CASE_NAMESPACE_DEFAULT_TTL },
1117 { "storage-engine", CASE_NAMESPACE_STORAGE_ENGINE_BEGIN },
1118 { "enable-xdr", CASE_NAMESPACE_ENABLE_XDR },
1119 { "sets-enable-xdr", CASE_NAMESPACE_SETS_ENABLE_XDR },
1120 { "xdr-remote-datacenter", CASE_NAMESPACE_XDR_REMOTE_DATACENTER },
1121 { "ns-forward-xdr-writes", CASE_NAMESPACE_FORWARD_XDR_WRITES },
1122 { "allow-nonxdr-writes", CASE_NAMESPACE_ALLOW_NONXDR_WRITES },
1123 { "allow-xdr-writes", CASE_NAMESPACE_ALLOW_XDR_WRITES },
1124 { "background-scan-max-rps", CASE_NAMESPACE_BACKGROUND_SCAN_MAX_RPS },
1125 { "conflict-resolution-policy", CASE_NAMESPACE_CONFLICT_RESOLUTION_POLICY },
1126 { "data-in-index", CASE_NAMESPACE_DATA_IN_INDEX },
1127 { "disable-cold-start-eviction", CASE_NAMESPACE_DISABLE_COLD_START_EVICTION },
1128 { "disable-write-dup-res", CASE_NAMESPACE_DISABLE_WRITE_DUP_RES },
1129 { "disallow-null-setname", CASE_NAMESPACE_DISALLOW_NULL_SETNAME },
1130 { "enable-benchmarks-batch-sub", CASE_NAMESPACE_ENABLE_BENCHMARKS_BATCH_SUB },
1131 { "enable-benchmarks-ops-sub", CASE_NAMESPACE_ENABLE_BENCHMARKS_OPS_SUB },
1132 { "enable-benchmarks-read", CASE_NAMESPACE_ENABLE_BENCHMARKS_READ },
1133 { "enable-benchmarks-udf", CASE_NAMESPACE_ENABLE_BENCHMARKS_UDF },
1134 { "enable-benchmarks-udf-sub", CASE_NAMESPACE_ENABLE_BENCHMARKS_UDF_SUB },
1135 { "enable-benchmarks-write", CASE_NAMESPACE_ENABLE_BENCHMARKS_WRITE },
1136 { "enable-hist-proxy", CASE_NAMESPACE_ENABLE_HIST_PROXY },
1137 { "evict-hist-buckets", CASE_NAMESPACE_EVICT_HIST_BUCKETS },
1138 { "evict-tenths-pct", CASE_NAMESPACE_EVICT_TENTHS_PCT },
1139 { "high-water-disk-pct", CASE_NAMESPACE_HIGH_WATER_DISK_PCT },
1140 { "high-water-memory-pct", CASE_NAMESPACE_HIGH_WATER_MEMORY_PCT },
1141 { "index-stage-size", CASE_NAMESPACE_INDEX_STAGE_SIZE },
1142 { "index-type", CASE_NAMESPACE_INDEX_TYPE_BEGIN },
1143 { "migrate-order", CASE_NAMESPACE_MIGRATE_ORDER },
1144 { "migrate-retransmit-ms", CASE_NAMESPACE_MIGRATE_RETRANSMIT_MS },
1145 { "migrate-sleep", CASE_NAMESPACE_MIGRATE_SLEEP },
1146 { "nsup-hist-period", CASE_NAMESPACE_NSUP_HIST_PERIOD },
1147 { "nsup-period", CASE_NAMESPACE_NSUP_PERIOD },
1148 { "nsup-threads", CASE_NAMESPACE_NSUP_THREADS },
1149 { "partition-tree-sprigs", CASE_NAMESPACE_PARTITION_TREE_SPRIGS },
1150 { "prefer-uniform-balance", CASE_NAMESPACE_PREFER_UNIFORM_BALANCE },
1151 { "rack-id", CASE_NAMESPACE_RACK_ID },
1152 { "read-consistency-level-override", CASE_NAMESPACE_READ_CONSISTENCY_LEVEL_OVERRIDE },
1153 { "set", CASE_NAMESPACE_SET_BEGIN },
1154 { "sindex", CASE_NAMESPACE_SINDEX_BEGIN },
1155 { "geo2dsphere-within", CASE_NAMESPACE_GEO2DSPHERE_WITHIN_BEGIN },
1156 { "single-bin", CASE_NAMESPACE_SINGLE_BIN },
1157 { "single-scan-threads", CASE_NAMESPACE_SINGLE_SCAN_THREADS },
1158 { "stop-writes-pct", CASE_NAMESPACE_STOP_WRITES_PCT },
1159 { "strong-consistency", CASE_NAMESPACE_STRONG_CONSISTENCY },
1160 { "strong-consistency-allow-expunge", CASE_NAMESPACE_STRONG_CONSISTENCY_ALLOW_EXPUNGE },
1161 { "tomb-raider-eligible-age", CASE_NAMESPACE_TOMB_RAIDER_ELIGIBLE_AGE },
1162 { "tomb-raider-period", CASE_NAMESPACE_TOMB_RAIDER_PERIOD },
1163 { "transaction-pending-limit", CASE_NAMESPACE_TRANSACTION_PENDING_LIMIT },
1164 { "truncate-threads", CASE_NAMESPACE_TRUNCATE_THREADS },
1165 { "write-commit-level-override", CASE_NAMESPACE_WRITE_COMMIT_LEVEL_OVERRIDE },
1166 { "disable-nsup", CASE_NAMESPACE_DISABLE_NSUP },
1167 { "allow-versions", CASE_NAMESPACE_ALLOW_VERSIONS },
1168 { "cold-start-evict-ttl", CASE_NAMESPACE_COLD_START_EVICT_TTL },
1169 { "demo-read-multiplier", CASE_NAMESPACE_DEMO_READ_MULTIPLIER },
1170 { "demo-write-multiplier", CASE_NAMESPACE_DEMO_WRITE_MULTIPLIER },
1171 { "high-water-pct", CASE_NAMESPACE_HIGH_WATER_PCT },
1172 { "low-water-pct", CASE_NAMESPACE_LOW_WATER_PCT },
1173 { "max-ttl", CASE_NAMESPACE_MAX_TTL },
1174 { "obj-size-hist-max", CASE_NAMESPACE_OBJ_SIZE_HIST_MAX },
1175 { "partition-tree-locks", CASE_NAMESPACE_PARTITION_TREE_LOCKS },
1176 { "si", CASE_NAMESPACE_SI_BEGIN },
1177 { "}", CASE_CONTEXT_END }
1178};
1179
1180const cfg_opt NAMESPACE_CONFLICT_RESOLUTION_OPTS[] = {
1181 { "generation", CASE_NAMESPACE_CONFLICT_RESOLUTION_GENERATION },
1182 { "last-update-time", CASE_NAMESPACE_CONFLICT_RESOLUTION_LAST_UPDATE_TIME }
1183};
1184
1185const cfg_opt NAMESPACE_READ_CONSISTENCY_OPTS[] = {
1186 { "all", CASE_NAMESPACE_READ_CONSISTENCY_ALL },
1187 { "off", CASE_NAMESPACE_READ_CONSISTENCY_OFF },
1188 { "one", CASE_NAMESPACE_READ_CONSISTENCY_ONE }
1189};
1190
1191const cfg_opt NAMESPACE_WRITE_COMMIT_OPTS[] = {
1192 { "all", CASE_NAMESPACE_WRITE_COMMIT_ALL },
1193 { "master", CASE_NAMESPACE_WRITE_COMMIT_MASTER },
1194 { "off", CASE_NAMESPACE_WRITE_COMMIT_OFF }
1195};
1196
1197const cfg_opt NAMESPACE_INDEX_TYPE_OPTS[] = {
1198 { "shmem", CASE_NAMESPACE_INDEX_TYPE_SHMEM },
1199 { "pmem", CASE_NAMESPACE_INDEX_TYPE_PMEM },
1200 { "flash", CASE_NAMESPACE_INDEX_TYPE_FLASH }
1201};
1202
1203const cfg_opt NAMESPACE_STORAGE_OPTS[] = {
1204 { "memory", CASE_NAMESPACE_STORAGE_MEMORY },
1205 { "ssd", CASE_NAMESPACE_STORAGE_SSD },
1206 { "device", CASE_NAMESPACE_STORAGE_DEVICE }
1207};
1208
1209const cfg_opt NAMESPACE_INDEX_TYPE_PMEM_OPTS[] = {
1210 { "mount", CASE_NAMESPACE_INDEX_TYPE_PMEM_MOUNT },
1211 { "mounts-high-water-pct", CASE_NAMESPACE_INDEX_TYPE_PMEM_MOUNTS_HIGH_WATER_PCT },
1212 { "mounts-size-limit", CASE_NAMESPACE_INDEX_TYPE_PMEM_MOUNTS_SIZE_LIMIT },
1213 { "}", CASE_CONTEXT_END }
1214};
1215
1216const cfg_opt NAMESPACE_INDEX_TYPE_FLASH_OPTS[] = {
1217 { "mount", CASE_NAMESPACE_INDEX_TYPE_FLASH_MOUNT },
1218 { "mounts-high-water-pct", CASE_NAMESPACE_INDEX_TYPE_FLASH_MOUNTS_HIGH_WATER_PCT },
1219 { "mounts-size-limit", CASE_NAMESPACE_INDEX_TYPE_FLASH_MOUNTS_SIZE_LIMIT },
1220 { "}", CASE_CONTEXT_END }
1221};
1222
1223const cfg_opt NAMESPACE_STORAGE_DEVICE_OPTS[] = {
1224 { "device", CASE_NAMESPACE_STORAGE_DEVICE_DEVICE },
1225 { "file", CASE_NAMESPACE_STORAGE_DEVICE_FILE },
1226 { "filesize", CASE_NAMESPACE_STORAGE_DEVICE_FILESIZE },
1227 { "scheduler-mode", CASE_NAMESPACE_STORAGE_DEVICE_SCHEDULER_MODE },
1228 { "write-block-size", CASE_NAMESPACE_STORAGE_DEVICE_WRITE_BLOCK_SIZE },
1229 { "memory-all", CASE_NAMESPACE_STORAGE_DEVICE_MEMORY_ALL },
1230 { "data-in-memory", CASE_NAMESPACE_STORAGE_DEVICE_DATA_IN_MEMORY },
1231 { "cold-start-empty", CASE_NAMESPACE_STORAGE_DEVICE_COLD_START_EMPTY },
1232 { "commit-to-device", CASE_NAMESPACE_STORAGE_DEVICE_COMMIT_TO_DEVICE },
1233 { "commit-min-size", CASE_NAMESPACE_STORAGE_DEVICE_COMMIT_MIN_SIZE },
1234 { "compression", CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION },
1235 { "compression-level", CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_LEVEL },
1236 { "defrag-lwm-pct", CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_LWM_PCT },
1237 { "defrag-queue-min", CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_QUEUE_MIN },
1238 { "defrag-sleep", CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_SLEEP },
1239 { "defrag-startup-minimum", CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_STARTUP_MINIMUM },
1240 { "direct-files", CASE_NAMESPACE_STORAGE_DEVICE_DIRECT_FILES },
1241 { "disable-odsync", CASE_NAMESPACE_STORAGE_DEVICE_DISABLE_ODSYNC },
1242 { "enable-benchmarks-storage", CASE_NAMESPACE_STORAGE_DEVICE_ENABLE_BENCHMARKS_STORAGE },
1243 { "encryption", CASE_NAMESPACE_STORAGE_DEVICE_ENCRYPTION },
1244 { "encryption-key-file", CASE_NAMESPACE_STORAGE_DEVICE_ENCRYPTION_KEY_FILE },
1245 { "flush-max-ms", CASE_NAMESPACE_STORAGE_DEVICE_FLUSH_MAX_MS },
1246 { "max-write-cache", CASE_NAMESPACE_STORAGE_DEVICE_MAX_WRITE_CACHE },
1247 { "min-avail-pct", CASE_NAMESPACE_STORAGE_DEVICE_MIN_AVAIL_PCT },
1248 { "post-write-queue", CASE_NAMESPACE_STORAGE_DEVICE_POST_WRITE_QUEUE },
1249 { "read-page-cache", CASE_NAMESPACE_STORAGE_DEVICE_READ_PAGE_CACHE },
1250 { "serialize-tomb-raider", CASE_NAMESPACE_STORAGE_DEVICE_SERIALIZE_TOMB_RAIDER },
1251 { "tomb-raider-sleep", CASE_NAMESPACE_STORAGE_DEVICE_TOMB_RAIDER_SLEEP },
1252 { "disable-odirect", CASE_NAMESPACE_STORAGE_DEVICE_DISABLE_ODIRECT },
1253 { "fsync-max-sec", CASE_NAMESPACE_STORAGE_DEVICE_FSYNC_MAX_SEC },
1254 { "defrag-max-blocks", CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_MAX_BLOCKS },
1255 { "defrag-period", CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_PERIOD },
1256 { "enable-osync", CASE_NAMESPACE_STORAGE_DEVICE_ENABLE_OSYNC },
1257 { "load-at-startup", CASE_NAMESPACE_STORAGE_DEVICE_LOAD_AT_STARTUP },
1258 { "persist", CASE_NAMESPACE_STORAGE_DEVICE_PERSIST },
1259 { "readonly", CASE_NAMESPACE_STORAGE_DEVICE_READONLY },
1260 { "signature", CASE_NAMESPACE_STORAGE_DEVICE_SIGNATURE },
1261 { "write-smoothing-period", CASE_NAMESPACE_STORAGE_DEVICE_WRITE_SMOOTHING_PERIOD },
1262 { "write-threads", CASE_NAMESPACE_STORAGE_DEVICE_WRITE_THREADS },
1263 { "}", CASE_CONTEXT_END }
1264};
1265
1266const cfg_opt NAMESPACE_STORAGE_DEVICE_COMPRESSION_OPTS[] = {
1267 { "none", CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_NONE },
1268 { "lz4", CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_LZ4 },
1269 { "snappy", CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_SNAPPY },
1270 { "zstd", CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_ZSTD }
1271};
1272
1273const cfg_opt NAMESPACE_STORAGE_DEVICE_ENCRYPTION_OPTS[] = {
1274 { "aes-128", CASE_NAMESPACE_STORAGE_DEVICE_ENCRYPTION_AES_128 },
1275 { "aes-256", CASE_NAMESPACE_STORAGE_DEVICE_ENCRYPTION_AES_256 }
1276};
1277
1278const cfg_opt NAMESPACE_SET_OPTS[] = {
1279 { "set-disable-eviction", CASE_NAMESPACE_SET_DISABLE_EVICTION },
1280 { "set-enable-xdr", CASE_NAMESPACE_SET_ENABLE_XDR },
1281 { "set-stop-writes-count", CASE_NAMESPACE_SET_STOP_WRITES_COUNT },
1282 { "set-evict-hwm-count", CASE_NAMESPACE_SET_EVICT_HWM_COUNT },
1283 { "set-evict-hwm-pct", CASE_NAMESPACE_SET_EVICT_HWM_PCT },
1284 { "set-stop-write-count", CASE_NAMESPACE_SET_STOP_WRITE_COUNT },
1285 { "set-stop-write-pct", CASE_NAMESPACE_SET_STOP_WRITE_PCT },
1286 { "}", CASE_CONTEXT_END }
1287};
1288
1289const cfg_opt NAMESPACE_SET_ENABLE_XDR_OPTS[] = {
1290 { "use-default", CASE_NAMESPACE_SET_ENABLE_XDR_USE_DEFAULT },
1291 { "false", CASE_NAMESPACE_SET_ENABLE_XDR_FALSE },
1292 { "true", CASE_NAMESPACE_SET_ENABLE_XDR_TRUE }
1293};
1294
1295const cfg_opt NAMESPACE_SI_OPTS[] = {
1296 { "si-gc-period", CASE_NAMESPACE_SI_GC_PERIOD },
1297 { "si-gc-max-units", CASE_NAMESPACE_SI_GC_MAX_UNITS },
1298 { "si-histogram", CASE_NAMESPACE_SI_HISTOGRAM },
1299 { "si-ignore-not-sync", CASE_NAMESPACE_SI_IGNORE_NOT_SYNC },
1300 { "}", CASE_CONTEXT_END }
1301};
1302
1303const cfg_opt NAMESPACE_SINDEX_OPTS[] = {
1304 { "num-partitions", CASE_NAMESPACE_SINDEX_NUM_PARTITIONS },
1305 { "}", CASE_CONTEXT_END }
1306};
1307
1308const cfg_opt NAMESPACE_GEO2DSPHERE_WITHIN_OPTS[] = {
1309 { "strict", CASE_NAMESPACE_GEO2DSPHERE_WITHIN_STRICT },
1310 { "min-level", CASE_NAMESPACE_GEO2DSPHERE_WITHIN_MIN_LEVEL },
1311 { "max-level", CASE_NAMESPACE_GEO2DSPHERE_WITHIN_MAX_LEVEL },
1312 { "max-cells", CASE_NAMESPACE_GEO2DSPHERE_WITHIN_MAX_CELLS },
1313 { "level-mod", CASE_NAMESPACE_GEO2DSPHERE_WITHIN_LEVEL_MOD },
1314 { "earth-radius-meters", CASE_NAMESPACE_GEO2DSPHERE_WITHIN_EARTH_RADIUS_METERS },
1315 { "}", CASE_CONTEXT_END }
1316};
1317
1318const cfg_opt MOD_LUA_OPTS[] = {
1319 { "cache-enabled", CASE_MOD_LUA_CACHE_ENABLED },
1320 { "user-path", CASE_MOD_LUA_USER_PATH },
1321 { "system-path", CASE_MOD_LUA_SYSTEM_PATH },
1322 { "}", CASE_CONTEXT_END }
1323};
1324
1325const cfg_opt SECURITY_OPTS[] = {
1326 { "enable-ldap", CASE_SECURITY_ENABLE_LDAP },
1327 { "enable-security", CASE_SECURITY_ENABLE_SECURITY },
1328 { "ldap-login-threads", CASE_SECURITY_LDAP_LOGIN_THREADS },
1329 { "privilege-refresh-period", CASE_SECURITY_PRIVILEGE_REFRESH_PERIOD },
1330 { "ldap", CASE_SECURITY_LDAP_BEGIN },
1331 { "log", CASE_SECURITY_LOG_BEGIN },
1332 { "syslog", CASE_SECURITY_SYSLOG_BEGIN },
1333 { "}", CASE_CONTEXT_END }
1334};
1335
1336const cfg_opt SECURITY_LDAP_OPTS[] = {
1337 { "disable-tls", CASE_SECURITY_LDAP_DISABLE_TLS },
1338 { "polling-period", CASE_SECURITY_LDAP_POLLING_PERIOD },
1339 { "query-base-dn", CASE_SECURITY_LDAP_QUERY_BASE_DN },
1340 { "query-user-dn", CASE_SECURITY_LDAP_QUERY_USER_DN },
1341 { "query-user-password-file", CASE_SECURITY_LDAP_QUERY_USER_PASSWORD_FILE },
1342 { "role-query-base-dn", CASE_SECURITY_LDAP_ROLE_QUERY_BASE_DN },
1343 { "role-query-pattern", CASE_SECURITY_LDAP_ROLE_QUERY_PATTERN },
1344 { "role-query-search-ou", CASE_SECURITY_LDAP_ROLE_QUERY_SEARCH_OU },
1345 { "server", CASE_SECURITY_LDAP_SERVER },
1346 { "session-ttl", CASE_SECURITY_LDAP_SESSION_TTL },
1347 { "tls-ca-file", CASE_SECURITY_LDAP_TLS_CA_FILE },
1348 { "token-hash-method", CASE_SECURITY_LDAP_TOKEN_HASH_METHOD },
1349 { "user-dn-pattern", CASE_SECURITY_LDAP_USER_DN_PATTERN },
1350 { "user-query-pattern", CASE_SECURITY_LDAP_USER_QUERY_PATTERN },
1351 { "}", CASE_CONTEXT_END }
1352};
1353
1354const cfg_opt SECURITY_LDAP_TOKEN_HASH_METHOD_OPTS[] = {
1355 { "sha-256", CASE_SECURITY_LDAP_TOKEN_HASH_METHOD_SHA_256 },
1356 { "sha-512", CASE_SECURITY_LDAP_TOKEN_HASH_METHOD_SHA_512 }
1357};
1358
1359const cfg_opt SECURITY_LOG_OPTS[] = {
1360 { "report-authentication", CASE_SECURITY_LOG_REPORT_AUTHENTICATION },
1361 { "report-data-op", CASE_SECURITY_LOG_REPORT_DATA_OP },
1362 { "report-sys-admin", CASE_SECURITY_LOG_REPORT_SYS_ADMIN },
1363 { "report-user-admin", CASE_SECURITY_LOG_REPORT_USER_ADMIN },
1364 { "report-violation", CASE_SECURITY_LOG_REPORT_VIOLATION },
1365 { "}", CASE_CONTEXT_END }
1366};
1367
1368const cfg_opt SECURITY_SYSLOG_OPTS[] = {
1369 { "local", CASE_SECURITY_SYSLOG_LOCAL },
1370 { "report-authentication", CASE_SECURITY_SYSLOG_REPORT_AUTHENTICATION },
1371 { "report-data-op", CASE_SECURITY_SYSLOG_REPORT_DATA_OP },
1372 { "report-sys-admin", CASE_SECURITY_SYSLOG_REPORT_SYS_ADMIN },
1373 { "report-user-admin", CASE_SECURITY_SYSLOG_REPORT_USER_ADMIN },
1374 { "report-violation", CASE_SECURITY_SYSLOG_REPORT_VIOLATION },
1375 { "}", CASE_CONTEXT_END }
1376};
1377
1378const cfg_opt XDR_OPTS[] = {
1379 { "{", CASE_CONTEXT_BEGIN },
1380 { "enable-xdr", CASE_XDR_ENABLE_XDR },
1381 { "enable-change-notification", CASE_XDR_ENABLE_CHANGE_NOTIFICATION },
1382 { "xdr-digestlog-path", CASE_XDR_DIGESTLOG_PATH },
1383 { "datacenter", CASE_XDR_DATACENTER_BEGIN },
1384 { "xdr-client-threads", CASE_XDR_CLIENT_THREADS },
1385 { "xdr-compression-threshold", CASE_XDR_COMPRESSION_THRESHOLD },
1386 { "xdr-delete-shipping-enabled", CASE_XDR_DELETE_SHIPPING_ENABLED },
1387 { "xdr-digestlog-iowait-ms", CASE_XDR_DIGESTLOG_IOWAIT_MS },
1388 { "forward-xdr-writes", CASE_XDR_FORWARD_XDR_WRITES },
1389 { "xdr-hotkey-time-ms", CASE_XDR_HOTKEY_TIME_MS },
1390 { "xdr-info-port", CASE_XDR_INFO_PORT },
1391 { "xdr-info-timeout", CASE_XDR_INFO_TIMEOUT },
1392 { "xdr-max-ship-bandwidth", CASE_XDR_MAX_SHIP_BANDWIDTH },
1393 { "xdr-max-ship-throughput", CASE_XDR_MAX_SHIP_THROUGHPUT },
1394 { "xdr-min-digestlog-free-pct", CASE_XDR_MIN_DIGESTLOG_FREE_PCT },
1395 { "xdr-nsup-deletes-enabled", CASE_XDR_NSUP_DELETES_ENABLED },
1396 { "xdr-read-threads", CASE_XDR_READ_THREADS},
1397 { "xdr-ship-bins", CASE_XDR_SHIP_BINS },
1398 { "xdr-ship-delay", CASE_XDR_SHIP_DELAY }, // hidden
1399 { "xdr-shipping-enabled", CASE_XDR_SHIPPING_ENABLED },
1400 { "xdr-write-timeout", CASE_XDR_WRITE_TIMEOUT },
1401 { "}", CASE_CONTEXT_END }
1402};
1403
1404const cfg_opt XDR_DATACENTER_OPTS[] = {
1405 { "{", CASE_CONTEXT_BEGIN },
1406 { "auth-mode", CASE_XDR_DATACENTER_AUTH_MODE },
1407 { "dc-connections", CASE_XDR_DATACENTER_DC_CONNECTIONS },
1408 { "dc-connections-idle-ms", CASE_XDR_DATACENTER_DC_CONNECTIONS_IDLE_MS },
1409 { "dc-int-ext-ipmap", CASE_XDR_DATACENTER_DC_INT_EXT_IPMAP },
1410 { "dc-node-address-port", CASE_XDR_DATACENTER_DC_NODE_ADDRESS_PORT },
1411 { "dc-security-config-file", CASE_XDR_DATACENTER_DC_SECURITY_CONFIG_FILE },
1412 { "dc-ship-bins", CASE_XDR_DATACENTER_DC_SHIP_BINS },
1413 { "dc-type", CASE_XDR_DATACENTER_DC_TYPE },
1414 { "dc-use-alternate-services", CASE_XDR_DATACENTER_DC_USE_ALTERNATE_SERVICES },
1415 { "http-url", CASE_XDR_DATACENTER_HTTP_URL },
1416 { "http-version", CASE_XDR_DATACENTER_HTTP_VERSION },
1417 { "tls-name", CASE_XDR_DATACENTER_TLS_NAME },
1418 { "tls-node", CASE_XDR_DATACENTER_TLS_NODE },
1419 { "}", CASE_CONTEXT_END }
1420};
1421
1422const cfg_opt XDR_DATACENTER_AUTH_MODE_OPTS[] = {
1423 { "internal", CASE_XDR_DATACENTER_AUTH_MODE_INTERNAL },
1424 { "external", CASE_XDR_DATACENTER_AUTH_MODE_EXTERNAL },
1425 { "external-insecure", CASE_XDR_DATACENTER_AUTH_MODE_EXTERNAL_INSECURE }
1426};
1427
1428// Used parsing separate file, but share cfg_case_id enum.
1429
1430const cfg_opt XDR_SEC_GLOBAL_OPTS[] = {
1431 { "credentials", XDR_SEC_CASE_CREDENTIALS_BEGIN }
1432};
1433
1434const cfg_opt XDR_SEC_CREDENTIALS_OPTS[] = {
1435 { "{", CASE_CONTEXT_BEGIN },
1436 { "username", XDR_SEC_CASE_CREDENTIALS_USERNAME },
1437 { "password", XDR_SEC_CASE_CREDENTIALS_PASSWORD },
1438 { "}", CASE_CONTEXT_END }
1439};
1440
1441const int NUM_GLOBAL_OPTS = sizeof(GLOBAL_OPTS) / sizeof(cfg_opt);
1442const int NUM_SERVICE_OPTS = sizeof(SERVICE_OPTS) / sizeof(cfg_opt);
1443const int NUM_SERVICE_AUTO_PIN_OPTS = sizeof(SERVICE_AUTO_PIN_OPTS) / sizeof(cfg_opt);
1444const int NUM_SERVICE_DEBUG_ALLOCATIONS_OPTS = sizeof(SERVICE_DEBUG_ALLOCATIONS_OPTS) / sizeof(cfg_opt);
1445const int NUM_LOGGING_OPTS = sizeof(LOGGING_OPTS) / sizeof(cfg_opt);
1446const int NUM_LOGGING_FILE_OPTS = sizeof(LOGGING_FILE_OPTS) / sizeof(cfg_opt);
1447const int NUM_LOGGING_CONSOLE_OPTS = sizeof(LOGGING_CONSOLE_OPTS) / sizeof(cfg_opt);
1448const int NUM_NETWORK_OPTS = sizeof(NETWORK_OPTS) / sizeof(cfg_opt);
1449const int NUM_NETWORK_SERVICE_OPTS = sizeof(NETWORK_SERVICE_OPTS) / sizeof(cfg_opt);
1450const int NUM_NETWORK_HEARTBEAT_OPTS = sizeof(NETWORK_HEARTBEAT_OPTS) / sizeof(cfg_opt);
1451const int NUM_NETWORK_HEARTBEAT_MODE_OPTS = sizeof(NETWORK_HEARTBEAT_MODE_OPTS) / sizeof(cfg_opt);
1452const int NUM_NETWORK_HEARTBEAT_PROTOCOL_OPTS = sizeof(NETWORK_HEARTBEAT_PROTOCOL_OPTS) / sizeof(cfg_opt);
1453const int NUM_NETWORK_FABRIC_OPTS = sizeof(NETWORK_FABRIC_OPTS) / sizeof(cfg_opt);
1454const int NUM_NETWORK_INFO_OPTS = sizeof(NETWORK_INFO_OPTS) / sizeof(cfg_opt);
1455const int NUM_NETWORK_TLS_OPTS = sizeof(NETWORK_TLS_OPTS) / sizeof(cfg_opt);
1456const int NUM_NAMESPACE_OPTS = sizeof(NAMESPACE_OPTS) / sizeof(cfg_opt);
1457const int NUM_NAMESPACE_CONFLICT_RESOLUTION_OPTS = sizeof(NAMESPACE_CONFLICT_RESOLUTION_OPTS) / sizeof(cfg_opt);
1458const int NUM_NAMESPACE_READ_CONSISTENCY_OPTS = sizeof(NAMESPACE_READ_CONSISTENCY_OPTS) / sizeof(cfg_opt);
1459const int NUM_NAMESPACE_WRITE_COMMIT_OPTS = sizeof(NAMESPACE_WRITE_COMMIT_OPTS) / sizeof(cfg_opt);
1460const int NUM_NAMESPACE_INDEX_TYPE_OPTS = sizeof(NAMESPACE_INDEX_TYPE_OPTS) / sizeof(cfg_opt);
1461const int NUM_NAMESPACE_STORAGE_OPTS = sizeof(NAMESPACE_STORAGE_OPTS) / sizeof(cfg_opt);
1462const int NUM_NAMESPACE_INDEX_TYPE_PMEM_OPTS = sizeof(NAMESPACE_INDEX_TYPE_PMEM_OPTS) / sizeof(cfg_opt);
1463const int NUM_NAMESPACE_INDEX_TYPE_FLASH_OPTS = sizeof(NAMESPACE_INDEX_TYPE_FLASH_OPTS) / sizeof(cfg_opt);
1464const int NUM_NAMESPACE_STORAGE_DEVICE_OPTS = sizeof(NAMESPACE_STORAGE_DEVICE_OPTS) / sizeof(cfg_opt);
1465const int NUM_NAMESPACE_STORAGE_DEVICE_COMPRESSION_OPTS = sizeof(NAMESPACE_STORAGE_DEVICE_COMPRESSION_OPTS) / sizeof(cfg_opt);
1466const int NUM_NAMESPACE_STORAGE_DEVICE_ENCRYPTION_OPTS = sizeof(NAMESPACE_STORAGE_DEVICE_ENCRYPTION_OPTS) / sizeof(cfg_opt);
1467const int NUM_NAMESPACE_SET_OPTS = sizeof(NAMESPACE_SET_OPTS) / sizeof(cfg_opt);
1468const int NUM_NAMESPACE_SET_ENABLE_XDR_OPTS = sizeof(NAMESPACE_SET_ENABLE_XDR_OPTS) / sizeof(cfg_opt);
1469const int NUM_NAMESPACE_SI_OPTS = sizeof(NAMESPACE_SI_OPTS) / sizeof(cfg_opt);
1470const int NUM_NAMESPACE_SINDEX_OPTS = sizeof(NAMESPACE_SINDEX_OPTS) / sizeof(cfg_opt);
1471const int NUM_NAMESPACE_GEO2DSPHERE_WITHIN_OPTS = sizeof(NAMESPACE_GEO2DSPHERE_WITHIN_OPTS) / sizeof(cfg_opt);
1472const int NUM_MOD_LUA_OPTS = sizeof(MOD_LUA_OPTS) / sizeof(cfg_opt);
1473const int NUM_SECURITY_OPTS = sizeof(SECURITY_OPTS) / sizeof(cfg_opt);
1474const int NUM_SECURITY_LDAP_OPTS = sizeof(SECURITY_LDAP_OPTS) / sizeof(cfg_opt);
1475const int NUM_SECURITY_LDAP_TOKEN_HASH_METHOD_OPTS = sizeof(SECURITY_LDAP_TOKEN_HASH_METHOD_OPTS) / sizeof(cfg_opt);
1476const int NUM_SECURITY_LOG_OPTS = sizeof(SECURITY_LOG_OPTS) / sizeof(cfg_opt);
1477const int NUM_SECURITY_SYSLOG_OPTS = sizeof(SECURITY_SYSLOG_OPTS) / sizeof(cfg_opt);
1478const int NUM_XDR_OPTS = sizeof(XDR_OPTS) / sizeof(cfg_opt);
1479const int NUM_XDR_DATACENTER_OPTS = sizeof(XDR_DATACENTER_OPTS) / sizeof(cfg_opt);
1480const int NUM_XDR_DATACENTER_AUTH_MODE_OPTS = sizeof(XDR_DATACENTER_AUTH_MODE_OPTS) / sizeof(cfg_opt);
1481
1482// Used parsing separate file, but share cfg_case_id enum.
1483
1484const int NUM_XDR_SEC_GLOBAL_OPTS = sizeof(XDR_SEC_GLOBAL_OPTS) / sizeof(cfg_opt);
1485const int NUM_XDR_SEC_CREDENTIALS_OPTS = sizeof(XDR_SEC_CREDENTIALS_OPTS) / sizeof(cfg_opt);
1486
1487
1488//==========================================================
1489// Configuration value constants not for switch cases.
1490//
1491
1492const char* DEVICE_SCHEDULER_MODES[] = {
1493 "anticipatory",
1494 "cfq", // best for rotational drives
1495 "deadline",
1496 "noop" // best for SSDs
1497};
1498
1499const int NUM_DEVICE_SCHEDULER_MODES = sizeof(DEVICE_SCHEDULER_MODES) / sizeof(const char*);
1500
1501const char* XDR_DESTINATION_TYPES[] = {
1502 XDR_CFG_DEST_AEROSPIKE, // remote Aerospike cluster
1503 XDR_CFG_DEST_HTTP // HTTP server
1504};
1505
1506const int NUM_XDR_DESTINATION_TYPES = sizeof(XDR_DESTINATION_TYPES) / sizeof(const char*);
1507
1508const char* XDR_HTTP_VERSION_TYPES[] = {
1509 XDR_CFG_HTTP_VERSION_1,
1510 XDR_CFG_HTTP_VERSION_2,
1511 XDR_CFG_HTTP_VERSION_2_PRIOR_KNOWLEDGE
1512};
1513
1514const int NUM_XDR_HTTP_VERSION_TYPES = sizeof(XDR_HTTP_VERSION_TYPES) / sizeof(const char*);
1515
1516
1517//==========================================================
1518// Generic parsing utilities.
1519//
1520
1521// Don't use these functions. Use the cf_str functions, which have better error
1522// handling, and support K, M, B/G, etc.
1523#undef atoi
1524#define atoi() DO_NOT_USE
1525#undef atol
1526#define atol() DO_NOT_USE
1527#undef atoll
1528#define atol() DO_NOT_USE
1529
1530//------------------------------------------------
1531// Parsing state (context) tracking & switching.
1532//
1533
1534typedef enum {
1535 GLOBAL,
1536 SERVICE,
1537 LOGGING, LOGGING_FILE, LOGGING_CONSOLE,
1538 NETWORK, NETWORK_SERVICE, NETWORK_HEARTBEAT, NETWORK_FABRIC, NETWORK_INFO, NETWORK_TLS,
1539 NAMESPACE, NAMESPACE_INDEX_TYPE_PMEM, NAMESPACE_INDEX_TYPE_FLASH, NAMESPACE_STORAGE_DEVICE, NAMESPACE_SET, NAMESPACE_SI, NAMESPACE_SINDEX, NAMESPACE_GEO2DSPHERE_WITHIN,
1540 MOD_LUA,
1541 SECURITY, SECURITY_LDAP, SECURITY_LOG, SECURITY_SYSLOG,
1542 XDR, XDR_DATACENTER,
1543 // Used parsing separate file, but shares this enum:
1544 XDR_SEC_CREDENTIALS,
1545 // Must be last, use for sanity-checking:
1546 PARSER_STATE_MAX_PLUS_1
1547} as_config_parser_state;
1548
1549// For detail logging only - keep in sync with as_config_parser_state.
1550const char* CFG_PARSER_STATES[] = {
1551 "GLOBAL",
1552 "SERVICE",
1553 "LOGGING", "LOGGING_FILE", "LOGGING_CONSOLE",
1554 "NETWORK", "NETWORK_SERVICE", "NETWORK_HEARTBEAT", "NETWORK_FABRIC", "NETWORK_INFO", "NETWORK_TLS",
1555 "NAMESPACE", "NAMESPACE_INDEX_TYPE_PMEM", "NAMESPACE_INDEX_TYPE_SSD", "NAMESPACE_STORAGE_DEVICE", "NAMESPACE_SET", "NAMESPACE_SI", "NAMESPACE_SINDEX", "NAMESPACE_GEO2DSPHERE_WITHIN",
1556 "MOD_LUA",
1557 "SECURITY", "SECURITY_LDAP", "SECURITY_LOG", "SECURITY_SYSLOG",
1558 "XDR", "XDR_DATACENTER",
1559 // Used parsing separate file, but shares corresponding enum:
1560 "XDR_SEC_CREDENTIALS"
1561};
1562
1563#define MAX_STACK_DEPTH 8
1564
1565typedef struct cfg_parser_state_s {
1566 as_config_parser_state current;
1567 as_config_parser_state stack[MAX_STACK_DEPTH];
1568 int depth;
1569} cfg_parser_state;
1570
1571void
1572cfg_parser_state_init(cfg_parser_state* p_state)
1573{
1574 p_state->current = p_state->stack[0] = GLOBAL;
1575 p_state->depth = 0;
1576}
1577
1578void
1579cfg_begin_context(cfg_parser_state* p_state, as_config_parser_state context)
1580{
1581 if (context < 0 || context >= PARSER_STATE_MAX_PLUS_1) {
1582 cf_crash(AS_CFG, "parsing - unknown context");
1583 }
1584
1585 as_config_parser_state prev_context = p_state->stack[p_state->depth];
1586
1587 if (++p_state->depth >= MAX_STACK_DEPTH) {
1588 cf_crash(AS_CFG, "parsing - context too deep");
1589 }
1590
1591 p_state->current = p_state->stack[p_state->depth] = context;
1592
1593 // To see this log, change NO_SINKS_LIMIT in fault.c:
1594 cf_detail(AS_CFG, "begin context: %s -> %s", CFG_PARSER_STATES[prev_context], CFG_PARSER_STATES[context]);
1595}
1596
1597void
1598cfg_end_context(cfg_parser_state* p_state)
1599{
1600 as_config_parser_state prev_context = p_state->stack[p_state->depth];
1601
1602 if (--p_state->depth < 0) {
1603 cf_crash(AS_CFG, "parsing - can't end context depth 0");
1604 }
1605
1606 p_state->current = p_state->stack[p_state->depth];
1607
1608 // To see this log, change NO_SINKS_LIMIT in fault.c:
1609 cf_detail(AS_CFG, "end context: %s -> %s", CFG_PARSER_STATES[prev_context], CFG_PARSER_STATES[p_state->current]);
1610}
1611
1612void
1613cfg_parser_done(cfg_parser_state* p_state)
1614{
1615 if (p_state->depth != 0) {
1616 cf_crash_nostack(AS_CFG, "parsing - final context missing '}'?");
1617 }
1618}
1619
1620//------------------------------------------------
1621// Given a token, return switch case identifier.
1622//
1623
1624cfg_case_id
1625cfg_find_tok(const char* tok, const cfg_opt opts[], int num_opts)
1626{
1627 for (int i = 0; i < num_opts; i++) {
1628 if (strcmp(tok, opts[i].tok) == 0) {
1629 return opts[i].case_id;
1630 }
1631 }
1632
1633 return CASE_NOT_FOUND;
1634}
1635
1636//------------------------------------------------
1637// Value parsing and sanity-checking utilities.
1638//
1639
1640void
1641cfg_renamed_name_tok(const cfg_line* p_line, const char* new_tok)
1642{
1643 cf_warning(AS_CFG, "line %d :: %s was renamed - please use '%s'",
1644 p_line->num, p_line->name_tok, new_tok);
1645}
1646
1647void
1648cfg_renamed_val_tok_1(const cfg_line* p_line, const char* new_tok)
1649{
1650 cf_warning(AS_CFG, "line %d :: %s value '%s' was renamed - please use '%s'",
1651 p_line->num, p_line->name_tok, p_line->val_tok_1, new_tok);
1652}
1653
1654void
1655cfg_deprecated_name_tok(const cfg_line* p_line)
1656{
1657 cf_warning(AS_CFG, "line %d :: %s is deprecated - please remove",
1658 p_line->num, p_line->name_tok);
1659}
1660
1661void
1662cfg_deprecated_val_tok_1(const cfg_line* p_line)
1663{
1664 cf_warning(AS_CFG, "line %d :: %s value '%s' is deprecated - please remove",
1665 p_line->num, p_line->name_tok, p_line->val_tok_1);
1666}
1667
1668void
1669cfg_unknown_name_tok(const cfg_line* p_line)
1670{
1671 cf_crash_nostack(AS_CFG, "line %d :: unknown config parameter name '%s'",
1672 p_line->num, p_line->name_tok);
1673}
1674
1675void
1676cfg_unknown_val_tok_1(const cfg_line* p_line)
1677{
1678 cf_crash_nostack(AS_CFG, "line %d :: %s has unknown value '%s'",
1679 p_line->num, p_line->name_tok, p_line->val_tok_1);
1680}
1681
1682void
1683cfg_obsolete(const cfg_line* p_line, const char* message)
1684{
1685 cf_crash_nostack(AS_CFG, "line %d :: '%s' is obsolete%s%s",
1686 p_line->num, p_line->name_tok, message ? " - " : "",
1687 message ? message : "");
1688}
1689
1690char*
1691cfg_strdup_no_checks(const cfg_line* p_line)
1692{
1693 return cf_strdup(p_line->val_tok_1);
1694}
1695
1696char*
1697cfg_strdup_val2_no_checks(const cfg_line* p_line)
1698{
1699 return cf_strdup(p_line->val_tok_2);
1700}
1701
1702char*
1703cfg_strdup_anyval(const cfg_line* p_line, const char* val_tok, bool is_required)
1704{
1705 if (val_tok[0] == 0) {
1706 if (is_required) {
1707 cf_crash_nostack(AS_CFG, "line %d :: %s must have a value specified",
1708 p_line->num, p_line->name_tok);
1709 }
1710
1711 // Do not duplicate empty strings.
1712 return NULL;
1713 }
1714
1715 return cf_strdup(val_tok);
1716}
1717
1718char*
1719cfg_strdup(const cfg_line* p_line, bool is_required)
1720{
1721 return cfg_strdup_anyval(p_line, p_line->val_tok_1, is_required);
1722}
1723
1724char*
1725cfg_strdup_val2(const cfg_line* p_line, bool is_required)
1726{
1727 return cfg_strdup_anyval(p_line, p_line->val_tok_2, is_required);
1728}
1729
1730char*
1731cfg_strdup_one_of(const cfg_line* p_line, const char* toks[], int num_toks)
1732{
1733 for (int i = 0; i < num_toks; i++) {
1734 if (strcmp(p_line->val_tok_1, toks[i]) == 0) {
1735 return cfg_strdup_no_checks(p_line);
1736 }
1737 }
1738
1739 uint32_t valid_toks_size = (num_toks * 2) + 1;
1740
1741 for (int i = 0; i < num_toks; i++) {
1742 valid_toks_size += strlen(toks[i]);
1743 }
1744
1745 char valid_toks[valid_toks_size];
1746
1747 valid_toks[0] = 0;
1748
1749 for (int i = 0; i < num_toks; i++) {
1750 strcat(valid_toks, toks[i]);
1751 strcat(valid_toks, ", ");
1752 }
1753
1754 cf_crash_nostack(AS_CFG, "line %d :: %s must be one of: %snot %s",
1755 p_line->num, p_line->name_tok, valid_toks, p_line->val_tok_1);
1756
1757 // Won't get here, but quiet warnings...
1758 return NULL;
1759}
1760
1761void
1762cfg_strcpy(const cfg_line* p_line, char* p_str, size_t max_size)
1763{
1764 size_t tok1_len = strlen(p_line->val_tok_1);
1765
1766 if (tok1_len == 0) {
1767 cf_crash_nostack(AS_CFG, "line %d :: %s must have a value specified",
1768 p_line->num, p_line->name_tok);
1769 }
1770
1771 if (tok1_len >= max_size) {
1772 cf_crash_nostack(AS_CFG, "line %d :: %s must be < %lu characters long, not %s",
1773 p_line->num, p_line->name_tok, max_size, p_line->val_tok_1);
1774 }
1775
1776 strcpy(p_str, p_line->val_tok_1);
1777}
1778
1779bool
1780cfg_bool(const cfg_line* p_line)
1781{
1782 if (strcasecmp(p_line->val_tok_1, "true") == 0 || strcasecmp(p_line->val_tok_1, "yes") == 0) {
1783 return true;
1784 }
1785
1786 if (strcasecmp(p_line->val_tok_1, "false") == 0 || strcasecmp(p_line->val_tok_1, "no") == 0) {
1787 return false;
1788 }
1789
1790 if (*p_line->val_tok_1 == '\0') {
1791 cf_crash_nostack(AS_CFG, "line %d :: %s must be true or false or yes or no",
1792 p_line->num, p_line->name_tok);
1793 }
1794
1795 cf_crash_nostack(AS_CFG, "line %d :: %s must be true or false or yes or no, not %s",
1796 p_line->num, p_line->name_tok, p_line->val_tok_1);
1797
1798 // Won't get here, but quiet warnings...
1799 return false;
1800}
1801
1802bool
1803cfg_bool_no_value_is_true(const cfg_line* p_line)
1804{
1805 return (*p_line->val_tok_1 == '\0') ? true : cfg_bool(p_line);
1806}
1807
1808int64_t
1809cfg_i64_anyval_no_checks(const cfg_line* p_line, char* val_tok)
1810{
1811 if (*val_tok == '\0') {
1812 cf_crash_nostack(AS_CFG, "line %d :: %s must specify an integer value",
1813 p_line->num, p_line->name_tok);
1814 }
1815
1816 int64_t value;
1817
1818 if (0 != cf_str_atoi_64(val_tok, &value)) {
1819 cf_crash_nostack(AS_CFG, "line %d :: %s must be a number, not %s",
1820 p_line->num, p_line->name_tok, val_tok);
1821 }
1822
1823 return value;
1824}
1825
1826int64_t
1827cfg_i64_no_checks(const cfg_line* p_line)
1828{
1829 return cfg_i64_anyval_no_checks(p_line, p_line->val_tok_1);
1830}
1831
1832int64_t
1833cfg_i64_val2_no_checks(const cfg_line* p_line)
1834{
1835 return cfg_i64_anyval_no_checks(p_line, p_line->val_tok_2);
1836}
1837
1838int64_t
1839cfg_i64_val3_no_checks(const cfg_line* p_line)
1840{
1841 return cfg_i64_anyval_no_checks(p_line, p_line->val_tok_3);
1842}
1843
1844int64_t
1845cfg_i64(const cfg_line* p_line, int64_t min, int64_t max)
1846{
1847 int64_t value = cfg_i64_no_checks(p_line);
1848
1849 if (value < min || value > max) {
1850 cf_crash_nostack(AS_CFG, "line %d :: %s must be >= %ld and <= %ld, not %ld",
1851 p_line->num, p_line->name_tok, min, max, value);
1852 }
1853
1854 return value;
1855}
1856
1857int
1858cfg_int_no_checks(const cfg_line* p_line)
1859{
1860 int64_t value = cfg_i64_no_checks(p_line);
1861
1862 if (value < INT32_MIN || value > INT32_MAX) {
1863 cf_crash_nostack(AS_CFG, "line %d :: %s %ld overflows int",
1864 p_line->num, p_line->name_tok, value);
1865 }
1866
1867 return (int)value;
1868}
1869
1870int
1871cfg_int(const cfg_line* p_line, int min, int max)
1872{
1873 int value = cfg_int_no_checks(p_line);
1874
1875 if (value < min || value > max) {
1876 cf_crash_nostack(AS_CFG, "line %d :: %s must be >= %d and <= %d, not %d",
1877 p_line->num, p_line->name_tok, min, max, value);
1878 }
1879
1880 return value;
1881}
1882
1883int
1884cfg_int_val2_no_checks(const cfg_line* p_line)
1885{
1886 int64_t value = cfg_i64_val2_no_checks(p_line);
1887
1888 if (value < INT32_MIN || value > INT32_MAX) {
1889 cf_crash_nostack(AS_CFG, "line %d :: %s %ld overflows int",
1890 p_line->num, p_line->name_tok, value);
1891 }
1892
1893 return (int)value;
1894}
1895
1896int
1897cfg_int_val3_no_checks(const cfg_line* p_line)
1898{
1899 int64_t value = cfg_i64_val3_no_checks(p_line);
1900
1901 if (value < INT32_MIN || value > INT32_MAX) {
1902 cf_crash_nostack(AS_CFG, "line %d :: %s %ld overflows int",
1903 p_line->num, p_line->name_tok, value);
1904 }
1905
1906 return (int)value;
1907}
1908int
1909cfg_int_val2(const cfg_line* p_line, int min, int max)
1910{
1911 int value = cfg_int_val2_no_checks(p_line);
1912
1913 if (value < min || value > max) {
1914 cf_crash_nostack(AS_CFG, "line %d :: %s must be >= %d and <= %d, not %d",
1915 p_line->num, p_line->name_tok, min, max, value);
1916 }
1917
1918 return value;
1919}
1920
1921int
1922cfg_int_val3(const cfg_line* p_line, int min, int max)
1923{
1924 int value = cfg_int_val3_no_checks(p_line);
1925
1926 if (value < min || value > max) {
1927 cf_crash_nostack(AS_CFG, "line %d :: %s must be >= %d and <= %d, not %d",
1928 p_line->num, p_line->name_tok, min, max, value);
1929 }
1930
1931 return value;
1932}
1933
1934uint64_t
1935cfg_x64_anyval_no_checks(const cfg_line* p_line, char* val_tok)
1936{
1937 if (*val_tok == '\0') {
1938 cf_crash_nostack(AS_CFG, "line %d :: %s must specify a hex value",
1939 p_line->num, p_line->name_tok);
1940 }
1941
1942 uint64_t value;
1943
1944 if (0 != cf_strtoul_x64(val_tok, &value)) {
1945 cf_crash_nostack(AS_CFG, "line %d :: %s must be a 64-bit hex number, not %s",
1946 p_line->num, p_line->name_tok, val_tok);
1947 }
1948
1949 return value;
1950}
1951
1952uint64_t
1953cfg_x64_no_checks(const cfg_line* p_line)
1954{
1955 return cfg_x64_anyval_no_checks(p_line, p_line->val_tok_1);
1956}
1957
1958uint64_t
1959cfg_x64(const cfg_line* p_line, uint64_t min, uint64_t max)
1960{
1961 uint64_t value = cfg_x64_no_checks(p_line);
1962
1963 if (min == 0) {
1964 if (value > max) {
1965 cf_crash_nostack(AS_CFG, "line %d :: %s must be <= %lx, not %lx",
1966 p_line->num, p_line->name_tok, max, value);
1967 }
1968 }
1969 else if (value < min || value > max) {
1970 cf_crash_nostack(AS_CFG, "line %d :: %s must be >= %lx and <= %lx, not %lx",
1971 p_line->num, p_line->name_tok, min, max, value);
1972 }
1973
1974 return value;
1975}
1976
1977uint64_t
1978cfg_u64_anyval_no_checks(const cfg_line* p_line, char* val_tok)
1979{
1980 if (*val_tok == '\0') {
1981 cf_crash_nostack(AS_CFG, "line %d :: %s must specify an unsigned integer value",
1982 p_line->num, p_line->name_tok);
1983 }
1984
1985 uint64_t value;
1986
1987 if (0 != cf_str_atoi_u64(val_tok, &value)) {
1988 cf_crash_nostack(AS_CFG, "line %d :: %s must be an unsigned number, not %s",
1989 p_line->num, p_line->name_tok, val_tok);
1990 }
1991
1992 return value;
1993}
1994
1995uint64_t
1996cfg_u64_no_checks(const cfg_line* p_line)
1997{
1998 return cfg_u64_anyval_no_checks(p_line, p_line->val_tok_1);
1999}
2000
2001uint64_t
2002cfg_u64_val2_no_checks(const cfg_line* p_line)
2003{
2004 return cfg_u64_anyval_no_checks(p_line, p_line->val_tok_2);
2005}
2006
2007uint64_t
2008cfg_u64(const cfg_line* p_line, uint64_t min, uint64_t max)
2009{
2010 uint64_t value = cfg_u64_no_checks(p_line);
2011
2012 if (min == 0) {
2013 if (value > max) {
2014 cf_crash_nostack(AS_CFG, "line %d :: %s must be <= %lu, not %lu",
2015 p_line->num, p_line->name_tok, max, value);
2016 }
2017 }
2018 else if (value < min || value > max) {
2019 cf_crash_nostack(AS_CFG, "line %d :: %s must be >= %lu and <= %lu, not %lu",
2020 p_line->num, p_line->name_tok, min, max, value);
2021 }
2022
2023 return value;
2024}
2025
2026// Note - accepts 0 if min is 0.
2027uint64_t
2028cfg_u64_power_of_2(const cfg_line* p_line, uint64_t min, uint64_t max)
2029{
2030 uint64_t value = cfg_u64(p_line, min, max);
2031
2032 if ((value & (value - 1)) != 0) {
2033 cf_crash_nostack(AS_CFG, "line %d :: %s must be an exact power of 2, not %lu",
2034 p_line->num, p_line->name_tok, value);
2035 }
2036
2037 return value;
2038}
2039
2040uint32_t
2041cfg_u32_no_checks(const cfg_line* p_line)
2042{
2043 uint64_t value = cfg_u64_no_checks(p_line);
2044
2045 if (value > UINT32_MAX) {
2046 cf_crash_nostack(AS_CFG, "line %d :: %s %lu overflows unsigned int",
2047 p_line->num, p_line->name_tok, value);
2048 }
2049
2050 return (uint32_t)value;
2051}
2052
2053uint32_t
2054cfg_u32(const cfg_line* p_line, uint32_t min, uint32_t max)
2055{
2056 uint32_t value = cfg_u32_no_checks(p_line);
2057
2058 if (min == 0) {
2059 if (value > max) {
2060 cf_crash_nostack(AS_CFG, "line %d :: %s must be <= %u, not %u",
2061 p_line->num, p_line->name_tok, max, value);
2062 }
2063 }
2064 else if (value < min || value > max) {
2065 cf_crash_nostack(AS_CFG, "line %d :: %s must be >= %u and <= %u, not %u",
2066 p_line->num, p_line->name_tok, min, max, value);
2067 }
2068
2069 return value;
2070}
2071
2072// Note - accepts 0 if min is 0.
2073uint32_t
2074cfg_u32_power_of_2(const cfg_line* p_line, uint32_t min, uint32_t max)
2075{
2076 uint32_t value = cfg_u32(p_line, min, max);
2077
2078 if ((value & (value - 1)) != 0) {
2079 cf_crash_nostack(AS_CFG, "line %d :: %s must be an exact power of 2, not %u",
2080 p_line->num, p_line->name_tok, value);
2081 }
2082
2083 return value;
2084}
2085
2086uint16_t
2087cfg_u16_no_checks(const cfg_line* p_line)
2088{
2089 uint64_t value = cfg_u64_no_checks(p_line);
2090
2091 if (value > UINT16_MAX) {
2092 cf_crash_nostack(AS_CFG, "line %d :: %s %lu overflows unsigned short",
2093 p_line->num, p_line->name_tok, value);
2094 }
2095
2096 return (uint16_t)value;
2097}
2098
2099uint16_t
2100cfg_u16(const cfg_line* p_line, uint16_t min, uint16_t max)
2101{
2102 uint16_t value = cfg_u16_no_checks(p_line);
2103
2104 if (min == 0) {
2105 if (value > max) {
2106 cf_crash_nostack(AS_CFG, "line %d :: %s must be <= %u, not %u",
2107 p_line->num, p_line->name_tok, max, value);
2108 }
2109 }
2110 else if (value < min || value > max) {
2111 cf_crash_nostack(AS_CFG, "line %d :: %s must be >= %u and <= %u, not %u",
2112 p_line->num, p_line->name_tok, min, max, value);
2113 }
2114
2115 return value;
2116}
2117
2118uint8_t
2119cfg_u8_no_checks(const cfg_line* p_line)
2120{
2121 uint64_t value = cfg_u64_no_checks(p_line);
2122
2123 if (value > UINT8_MAX) {
2124 cf_crash_nostack(AS_CFG, "line %d :: %s %lu overflows unsigned char",
2125 p_line->num, p_line->name_tok, value);
2126 }
2127
2128 return (uint8_t)value;
2129}
2130
2131uint8_t
2132cfg_u8(const cfg_line* p_line, uint8_t min, uint8_t max)
2133{
2134 uint8_t value = cfg_u8_no_checks(p_line);
2135
2136 if (min == 0) {
2137 if (value > max) {
2138 cf_crash_nostack(AS_CFG, "line %d :: %s must be <= %u, not %u",
2139 p_line->num, p_line->name_tok, max, value);
2140 }
2141 }
2142 else if (value < min || value > max) {
2143 cf_crash_nostack(AS_CFG, "line %d :: %s must be >= %u and <= %u, not %u",
2144 p_line->num, p_line->name_tok, min, max, value);
2145 }
2146
2147 return value;
2148}
2149
2150uint32_t
2151cfg_seconds_no_checks(const cfg_line* p_line)
2152{
2153 if (*p_line->val_tok_1 == '\0') {
2154 cf_crash_nostack(AS_CFG, "line %d :: %s must specify an unsigned integer value with time unit (s, m, h, or d)",
2155 p_line->num, p_line->name_tok);
2156 }
2157
2158 uint32_t value;
2159
2160 if (cf_str_atoi_seconds(p_line->val_tok_1, &value) != 0) {
2161 cf_crash_nostack(AS_CFG, "line %d :: %s must be a small enough unsigned number with time unit (s, m, h, or d), not %s",
2162 p_line->num, p_line->name_tok, p_line->val_tok_1);
2163 }
2164
2165 return value;
2166}
2167
2168uint32_t
2169cfg_seconds(const cfg_line* p_line, uint32_t min, uint32_t max)
2170{
2171 uint32_t value = cfg_seconds_no_checks(p_line);
2172
2173 if (min == 0) {
2174 if (value > max) {
2175 cf_crash_nostack(AS_CFG, "line %d :: %s must be <= %u seconds, not %u seconds",
2176 p_line->num, p_line->name_tok, max, value);
2177 }
2178 }
2179 else if (value < min || value > max) {
2180 cf_crash_nostack(AS_CFG, "line %d :: %s must be >= %u seconds and <= %u seconds, not %u seconds",
2181 p_line->num, p_line->name_tok, min, max, value);
2182 }
2183
2184 return value;
2185}
2186
2187// Minimum & maximum port numbers:
2188const int CFG_MIN_PORT = 1024;
2189const int CFG_MAX_PORT = UINT16_MAX;
2190
2191cf_ip_port
2192cfg_port(const cfg_line* p_line)
2193{
2194 return (cf_ip_port)cfg_int(p_line, CFG_MIN_PORT, CFG_MAX_PORT);
2195}
2196
2197cf_ip_port
2198cfg_port_val2(const cfg_line* p_line)
2199{
2200 return (cf_ip_port)cfg_int_val2(p_line, CFG_MIN_PORT, CFG_MAX_PORT);
2201}
2202
2203cf_ip_port
2204cfg_port_val3(const cfg_line* p_line)
2205{
2206 return (cf_ip_port)cfg_int_val3(p_line, CFG_MIN_PORT, CFG_MAX_PORT);
2207}
2208
2209//------------------------------------------------
2210// Constants used in parsing.
2211//
2212
2213// Token delimiter characters:
2214const char CFG_WHITESPACE[] = " \t\n\r\f\v";
2215
2216
2217//==========================================================
2218// Public API - parse the configuration file.
2219//
2220
2221as_config*
2222as_config_init(const char* config_file)
2223{
2224 as_config* c = &g_config; // shortcut pointer
2225
2226 // Set the service context defaults. Values parsed from the config file will
2227 // override the defaults.
2228 cfg_set_defaults();
2229 xdr_config_defaults();
2230
2231 FILE* FD;
2232 char iobuf[256];
2233 int line_num = 0;
2234 cfg_parser_state state;
2235
2236 cfg_parser_state_init(&state);
2237
2238 as_namespace* ns = NULL;
2239 xdr_dest_config *cur_dest_cfg = NULL;
2240 cf_tls_spec* tls_spec = NULL;
2241 cf_fault_sink* sink = NULL;
2242 as_set* p_set = NULL; // local variable used for set initialization
2243
2244 // Open the configuration file for reading.
2245 if (NULL == (FD = fopen(config_file, "r"))) {
2246 cf_crash_nostack(AS_CFG, "couldn't open configuration file %s: %s", config_file, cf_strerror(errno));
2247 }
2248
2249 // Parse the configuration file, line by line.
2250 while (fgets(iobuf, sizeof(iobuf), FD)) {
2251 line_num++;
2252
2253 // First chop the comment off, if there is one.
2254
2255 char* p_comment = strchr(iobuf, '#');
2256
2257 if (p_comment) {
2258 *p_comment = '\0';
2259 }
2260
2261 // Find (and null-terminate) up to three whitespace-delimited tokens in
2262 // the line, a 'name' token and up to two 'value' tokens.
2263
2264 cfg_line line = { line_num, NULL, NULL, NULL, NULL };
2265
2266 line.name_tok = strtok(iobuf, CFG_WHITESPACE);
2267
2268 // If there are no tokens, ignore this line, get the next line.
2269 if (! line.name_tok) {
2270 continue;
2271 }
2272
2273 line.val_tok_1 = strtok(NULL, CFG_WHITESPACE);
2274
2275 if (! line.val_tok_1) {
2276 line.val_tok_1 = ""; // in case it's used where NULL can't be used
2277 }
2278 else {
2279 line.val_tok_2 = strtok(NULL, CFG_WHITESPACE);
2280 }
2281
2282 if (! line.val_tok_2) {
2283 line.val_tok_2 = ""; // in case it's used where NULL can't be used
2284 }
2285 else {
2286 line.val_tok_3 = strtok(NULL, CFG_WHITESPACE);
2287 }
2288
2289 if (! line.val_tok_3) {
2290 line.val_tok_3 = ""; // in case it's used where NULL can't be used
2291 }
2292
2293 // Note that we can't see this output until a logging sink is specified.
2294 cf_detail(AS_CFG, "line %d :: %s %s %s %s", line_num, line.name_tok, line.val_tok_1, line.val_tok_2, line.val_tok_3);
2295
2296 // Parse the directive.
2297 switch (state.current) {
2298
2299 //==================================================
2300 // Parse top-level items.
2301 //
2302 case GLOBAL:
2303 switch (cfg_find_tok(line.name_tok, GLOBAL_OPTS, NUM_GLOBAL_OPTS)) {
2304 case CASE_SERVICE_BEGIN:
2305 cfg_begin_context(&state, SERVICE);
2306 break;
2307 case CASE_LOGGING_BEGIN:
2308 cfg_begin_context(&state, LOGGING);
2309 break;
2310 case CASE_NETWORK_BEGIN:
2311 cfg_begin_context(&state, NETWORK);
2312 break;
2313 case CASE_NAMESPACE_BEGIN:
2314 // Create the namespace objects.
2315 ns = as_namespace_create(line.val_tok_1);
2316 cfg_begin_context(&state, NAMESPACE);
2317 break;
2318 case CASE_MOD_LUA_BEGIN:
2319 cfg_begin_context(&state, MOD_LUA);
2320 break;
2321 case CASE_SECURITY_BEGIN:
2322 cfg_enterprise_only(&line);
2323 cfg_begin_context(&state, SECURITY);
2324 break;
2325 case CASE_XDR_BEGIN:
2326 g_xcfg.xdr_section_configured = true;
2327 cfg_enterprise_only(&line);
2328 cfg_begin_context(&state, XDR);
2329 break;
2330 case CASE_NOT_FOUND:
2331 default:
2332 cfg_unknown_name_tok(&line);
2333 break;
2334 }
2335 break;
2336
2337 //==================================================
2338 // Parse service context items.
2339 //
2340 case SERVICE:
2341 switch (cfg_find_tok(line.name_tok, SERVICE_OPTS, NUM_SERVICE_OPTS)) {
2342 case CASE_SERVICE_USER:
2343 {
2344 struct passwd* pwd;
2345 if (NULL == (pwd = getpwnam(line.val_tok_1))) {
2346 cf_crash_nostack(AS_CFG, "line %d :: user not found: %s", line_num, line.val_tok_1);
2347 }
2348 c->uid = pwd->pw_uid;
2349 endpwent();
2350 }
2351 break;
2352 case CASE_SERVICE_GROUP:
2353 {
2354 struct group* grp;
2355 if (NULL == (grp = getgrnam(line.val_tok_1))) {
2356 cf_crash_nostack(AS_CFG, "line %d :: group not found: %s", line_num, line.val_tok_1);
2357 }
2358 c->gid = grp->gr_gid;
2359 endgrent();
2360 }
2361 break;
2362 case CASE_SERVICE_PAXOS_SINGLE_REPLICA_LIMIT:
2363 c->paxos_single_replica_limit = cfg_u32_no_checks(&line);
2364 break;
2365 case CASE_SERVICE_PIDFILE:
2366 c->pidfile = cfg_strdup_no_checks(&line);
2367 break;
2368 case CASE_SERVICE_CLIENT_FD_MAX:
2369 cfg_renamed_name_tok(&line, "proto-fd-max");
2370 // No break.
2371 case CASE_SERVICE_PROTO_FD_MAX:
2372 c->n_proto_fd_max = cfg_u32(&line, MIN_PROTO_FD_MAX, UINT32_MAX);
2373 break;
2374 case CASE_SERVICE_ADVERTISE_IPV6:
2375 cf_socket_set_advertise_ipv6(cfg_bool(&line));
2376 break;
2377 case CASE_SERVICE_AUTO_PIN:
2378 switch (cfg_find_tok(line.val_tok_1, SERVICE_AUTO_PIN_OPTS, NUM_SERVICE_AUTO_PIN_OPTS)) {
2379 case CASE_SERVICE_AUTO_PIN_NONE:
2380 c->auto_pin = CF_TOPO_AUTO_PIN_NONE;
2381 break;
2382 case CASE_SERVICE_AUTO_PIN_CPU:
2383 c->auto_pin = CF_TOPO_AUTO_PIN_CPU;
2384 break;
2385 case CASE_SERVICE_AUTO_PIN_NUMA:
2386 c->auto_pin = CF_TOPO_AUTO_PIN_NUMA;
2387 break;
2388 case CASE_SERVICE_AUTO_PIN_ADQ:
2389 c->auto_pin = CF_TOPO_AUTO_PIN_ADQ;
2390 break;
2391 case CASE_NOT_FOUND:
2392 default:
2393 cfg_unknown_val_tok_1(&line);
2394 break;
2395 }
2396 break;
2397 case CASE_SERVICE_BATCH_INDEX_THREADS:
2398 c->n_batch_index_threads = cfg_u32(&line, 1, MAX_BATCH_THREADS);
2399 break;
2400 case CASE_SERVICE_BATCH_MAX_BUFFERS_PER_QUEUE:
2401 c->batch_max_buffers_per_queue = cfg_u32_no_checks(&line);
2402 break;
2403 case CASE_SERVICE_BATCH_MAX_REQUESTS:
2404 c->batch_max_requests = cfg_u32_no_checks(&line);
2405 break;
2406 case CASE_SERVICE_BATCH_MAX_UNUSED_BUFFERS:
2407 c->batch_max_unused_buffers = cfg_u32_no_checks(&line);
2408 break;
2409 case CASE_SERVICE_CLUSTER_NAME:
2410 cfg_set_cluster_name(line.val_tok_1);
2411 break;
2412 case CASE_SERVICE_ENABLE_BENCHMARKS_FABRIC:
2413 c->fabric_benchmarks_enabled = cfg_bool(&line);
2414 break;
2415 case CASE_SERVICE_ENABLE_BENCHMARKS_SVC:
2416 c->svc_benchmarks_enabled = cfg_bool(&line);
2417 break;
2418 case CASE_SERVICE_ENABLE_HEALTH_CHECK:
2419 c->health_check_enabled = cfg_bool(&line);
2420 break;
2421 case CASE_SERVICE_ENABLE_HIST_INFO:
2422 c->info_hist_enabled = cfg_bool(&line);
2423 break;
2424 case CASE_SERVICE_FEATURE_KEY_FILE:
2425 c->feature_key_file = cfg_strdup(&line, true);
2426 break;
2427 case CASE_SERVICE_HIST_TRACK_BACK:
2428 c->hist_track_back = cfg_u32_no_checks(&line);
2429 break;
2430 case CASE_SERVICE_HIST_TRACK_SLICE:
2431 c->hist_track_slice = cfg_u32_no_checks(&line);
2432 break;
2433 case CASE_SERVICE_HIST_TRACK_THRESHOLDS:
2434 c->hist_track_thresholds = cfg_strdup_no_checks(&line);
2435 // TODO - if config key present but no value (not even space) failure mode is bad...
2436 break;
2437 case CASE_SERVICE_INFO_THREADS:
2438 c->n_info_threads = cfg_u32(&line, 1, MAX_INFO_THREADS);
2439 break;
2440 case CASE_SERVICE_KEEP_CAPS_SSD_HEALTH:
2441 cfg_keep_cap(cfg_bool(&line), &c->keep_caps_ssd_health, CAP_SYS_ADMIN);
2442 break;
2443 case CASE_SERVICE_LOG_LOCAL_TIME:
2444 cf_fault_use_local_time(cfg_bool(&line));
2445 break;
2446 case CASE_SERVICE_LOG_MILLIS:
2447 cf_fault_log_millis(cfg_bool(&line));
2448 break;
2449 case CASE_SERVICE_MIGRATE_FILL_DELAY:
2450 cfg_enterprise_only(&line);
2451 c->migrate_fill_delay = cfg_seconds_no_checks(&line);
2452 break;
2453 case CASE_SERVICE_MIGRATE_MAX_NUM_INCOMING:
2454 c->migrate_max_num_incoming = cfg_u32(&line, 0, AS_MIGRATE_LIMIT_MAX_NUM_INCOMING);
2455 break;
2456 case CASE_SERVICE_MIGRATE_THREADS:
2457 c->n_migrate_threads = cfg_u32(&line, 0, MAX_NUM_MIGRATE_XMIT_THREADS);
2458 break;
2459 case CASE_SERVICE_MIN_CLUSTER_SIZE:
2460 c->clustering_config.cluster_size_min = cfg_u32(&line, 0, AS_CLUSTER_SZ);
2461 break;
2462 case CASE_SERVICE_NODE_ID:
2463 c->self_node = cfg_x64(&line, 1, UINT64_MAX);
2464 break;
2465 case CASE_SERVICE_NODE_ID_INTERFACE:
2466 c->node_id_interface = cfg_strdup_no_checks(&line);
2467 break;
2468 case CASE_SERVICE_PROTO_FD_IDLE_MS:
2469 c->proto_fd_idle_ms = cfg_int_no_checks(&line);
2470 break;
2471 case CASE_SERVICE_QUERY_BATCH_SIZE:
2472 c->query_bsize = cfg_int_no_checks(&line);
2473 break;
2474 case CASE_SERVICE_QUERY_BUFPOOL_SIZE:
2475 c->query_bufpool_size = cfg_u32(&line, 1, UINT32_MAX);
2476 break;
2477 case CASE_SERVICE_QUERY_IN_TRANSACTION_THREAD:
2478 c->query_in_transaction_thr = cfg_bool(&line);
2479 break;
2480 case CASE_SERVICE_QUERY_LONG_Q_MAX_SIZE:
2481 c->query_long_q_max_size = cfg_u32(&line, 1, UINT32_MAX);
2482 break;
2483 case CASE_SERVICE_QUERY_PRE_RESERVE_PARTITIONS:
2484 c->partitions_pre_reserved = cfg_bool(&line);
2485 break;
2486 case CASE_SERVICE_QUERY_PRIORITY:
2487 c->query_priority = cfg_int_no_checks(&line);
2488 break;
2489 case CASE_SERVICE_QUERY_PRIORITY_SLEEP_US:
2490 c->query_sleep_us = cfg_u64_no_checks(&line);
2491 break;
2492 case CASE_SERVICE_QUERY_REC_COUNT_BOUND:
2493 c->query_rec_count_bound = cfg_u64(&line, 1, UINT64_MAX);
2494 break;
2495 case CASE_SERVICE_QUERY_REQ_IN_QUERY_THREAD:
2496 c->query_req_in_query_thread = cfg_bool(&line);
2497 break;
2498 case CASE_SERVICE_QUERY_REQ_MAX_INFLIGHT:
2499 c->query_req_max_inflight = cfg_u32(&line, 1, UINT32_MAX);
2500 break;
2501 case CASE_SERVICE_QUERY_SHORT_Q_MAX_SIZE:
2502 c->query_short_q_max_size = cfg_u32(&line, 1, UINT32_MAX);
2503 break;
2504 case CASE_SERVICE_QUERY_THREADS:
2505 c->query_threads = cfg_u32(&line, 1, AS_QUERY_MAX_THREADS);
2506 break;
2507 case CASE_SERVICE_QUERY_THRESHOLD:
2508 c->query_threshold = cfg_int_no_checks(&line);
2509 break;
2510 case CASE_SERVICE_QUERY_UNTRACKED_TIME_MS:
2511 c->query_untracked_time_ms = cfg_u64_no_checks(&line);
2512 break;
2513 case CASE_SERVICE_QUERY_WORKER_THREADS:
2514 c->query_worker_threads = cfg_u32(&line, 1, AS_QUERY_MAX_WORKER_THREADS);
2515 break;
2516 case CASE_SERVICE_RUN_AS_DAEMON:
2517 c->run_as_daemon = cfg_bool_no_value_is_true(&line);
2518 break;
2519 case CASE_SERVICE_SCAN_MAX_DONE:
2520 c->scan_max_done = cfg_u32(&line, 0, 1000);
2521 break;
2522 case CASE_SERVICE_SCAN_THREADS_LIMIT:
2523 c->n_scan_threads_limit = cfg_u32(&line, 1, 1024);
2524 break;
2525 case CASE_SERVICE_SERVICE_THREADS:
2526 c->n_service_threads = cfg_u32(&line, 1, MAX_SERVICE_THREADS);
2527 break;
2528 case CASE_SERVICE_SINDEX_BUILDER_THREADS:
2529 c->sindex_builder_threads = cfg_u32(&line, 1, MAX_SINDEX_BUILDER_THREADS);
2530 break;
2531 case CASE_SERVICE_SINDEX_GC_MAX_RATE:
2532 c->sindex_gc_max_rate = cfg_u32_no_checks(&line);
2533 break;
2534 case CASE_SERVICE_SINDEX_GC_PERIOD:
2535 c->sindex_gc_period = cfg_u32_no_checks(&line);
2536 break;
2537 case CASE_SERVICE_TICKER_INTERVAL:
2538 c->ticker_interval = cfg_u32_no_checks(&line);
2539 break;
2540 case CASE_SERVICE_TRANSACTION_MAX_MS:
2541 c->transaction_max_ns = cfg_u64_no_checks(&line) * 1000000;
2542 break;
2543 case CASE_SERVICE_TRANSACTION_RETRY_MS:
2544 c->transaction_retry_ms = cfg_u32_no_checks(&line);
2545 break;
2546 case CASE_SERVICE_WORK_DIRECTORY:
2547 c->work_directory = cfg_strdup_no_checks(&line);
2548 break;
2549 case CASE_SERVICE_DEBUG_ALLOCATIONS:
2550 switch (cfg_find_tok(line.val_tok_1, SERVICE_DEBUG_ALLOCATIONS_OPTS, NUM_SERVICE_DEBUG_ALLOCATIONS_OPTS)) {
2551 case CASE_SERVICE_DEBUG_ALLOCATIONS_NONE:
2552 c->debug_allocations = CF_ALLOC_DEBUG_NONE;
2553 break;
2554 case CASE_SERVICE_DEBUG_ALLOCATIONS_TRANSIENT:
2555 c->debug_allocations = CF_ALLOC_DEBUG_TRANSIENT;
2556 break;
2557 case CASE_SERVICE_DEBUG_ALLOCATIONS_PERSISTENT:
2558 c->debug_allocations = CF_ALLOC_DEBUG_PERSISTENT;
2559 break;
2560 case CASE_SERVICE_DEBUG_ALLOCATIONS_ALL:
2561 c->debug_allocations = CF_ALLOC_DEBUG_ALL;
2562 break;
2563 case CASE_NOT_FOUND:
2564 default:
2565 cfg_unknown_val_tok_1(&line);
2566 break;
2567 }
2568 break;
2569 case CASE_SERVICE_FABRIC_DUMP_MSGS:
2570 c->fabric_dump_msgs = cfg_bool(&line);
2571 break;
2572 case CASE_SERVICE_INDENT_ALLOCATIONS:
2573 c->indent_allocations = cfg_bool(&line);
2574 break;
2575 case CASE_SERVICE_ALLOW_INLINE_TRANSACTIONS:
2576 cfg_obsolete(&line, "please configure 'service-threads' carefully");
2577 break;
2578 case CASE_SERVICE_NSUP_PERIOD:
2579 cfg_obsolete(&line, "please use namespace-context 'nsup-period'");
2580 break;
2581 case CASE_SERVICE_OBJECT_SIZE_HIST_PERIOD:
2582 cfg_obsolete(&line, "please use namespace-context 'nsup-hist-period'");
2583 break;
2584 case CASE_SERVICE_RESPOND_CLIENT_ON_MASTER_COMPLETION:
2585 cfg_obsolete(&line, "please use namespace-context 'write-commit-level-override' and/or write transaction policy");
2586 break;
2587 case CASE_SERVICE_SCAN_MAX_UDF_TRANSACTIONS:
2588 cfg_obsolete(&line, "please use namespace-context 'background-scan-max-rps'");
2589 break;
2590 case CASE_SERVICE_SCAN_THREADS:
2591 cfg_obsolete(&line, "please use 'scan-threads-limit' and namespace-context 'single-scan-threads'");
2592 break;
2593 case CASE_SERVICE_TRANSACTION_PENDING_LIMIT:
2594 cfg_obsolete(&line, "please use namespace-context 'transaction-pending-limit'");
2595 break;
2596 case CASE_SERVICE_TRANSACTION_QUEUES:
2597 cfg_obsolete(&line, "please configure 'service-threads' carefully");
2598 break;
2599 case CASE_SERVICE_TRANSACTION_REPEATABLE_READ:
2600 cfg_obsolete(&line, "please use namespace-context 'read-consistency-level-override' and/or read transaction policy");
2601 break;
2602 case CASE_SERVICE_TRANSACTION_THREADS_PER_QUEUE:
2603 cfg_obsolete(&line, "please configure 'service-threads' carefully");
2604 break;
2605 case CASE_SERVICE_AUTO_DUN:
2606 case CASE_SERVICE_AUTO_UNDUN:
2607 case CASE_SERVICE_BATCH_PRIORITY:
2608 case CASE_SERVICE_BATCH_RETRANSMIT:
2609 case CASE_SERVICE_BATCH_THREADS:
2610 case CASE_SERVICE_CLIB_LIBRARY:
2611 case CASE_SERVICE_DEFRAG_QUEUE_ESCAPE:
2612 case CASE_SERVICE_DEFRAG_QUEUE_HWM:
2613 case CASE_SERVICE_DEFRAG_QUEUE_LWM:
2614 case CASE_SERVICE_DEFRAG_QUEUE_PRIORITY:
2615 case CASE_SERVICE_DUMP_MESSAGE_ABOVE_SIZE:
2616 case CASE_SERVICE_FABRIC_WORKERS:
2617 case CASE_SERVICE_FB_HEALTH_BAD_PCT:
2618 case CASE_SERVICE_FB_HEALTH_GOOD_PCT:
2619 case CASE_SERVICE_FB_HEALTH_MSG_PER_BURST:
2620 case CASE_SERVICE_FB_HEALTH_MSG_TIMEOUT:
2621 case CASE_SERVICE_GENERATION_DISABLE:
2622 case CASE_SERVICE_MAX_MSGS_PER_TYPE:
2623 case CASE_SERVICE_MIGRATE_READ_PRIORITY:
2624 case CASE_SERVICE_MIGRATE_READ_SLEEP:
2625 case CASE_SERVICE_MIGRATE_RX_LIFETIME_MS:
2626 case CASE_SERVICE_MIGRATE_XMIT_HWM:
2627 case CASE_SERVICE_MIGRATE_XMIT_LWM:
2628 case CASE_SERVICE_MIGRATE_PRIORITY:
2629 case CASE_SERVICE_MIGRATE_XMIT_PRIORITY:
2630 case CASE_SERVICE_MIGRATE_XMIT_SLEEP:
2631 case CASE_SERVICE_NSUP_AUTO_HWM:
2632 case CASE_SERVICE_NSUP_AUTO_HWM_PCT:
2633 case CASE_SERVICE_NSUP_DELETE_SLEEP:
2634 case CASE_SERVICE_NSUP_MAX_DELETES:
2635 case CASE_SERVICE_NSUP_QUEUE_ESCAPE:
2636 case CASE_SERVICE_NSUP_QUEUE_HWM:
2637 case CASE_SERVICE_NSUP_QUEUE_LWM:
2638 case CASE_SERVICE_NSUP_REDUCE_PRIORITY:
2639 case CASE_SERVICE_NSUP_REDUCE_SLEEP:
2640 case CASE_SERVICE_NSUP_STARTUP_EVICT:
2641 case CASE_SERVICE_NSUP_THREADS:
2642 case CASE_SERVICE_PAXOS_MAX_CLUSTER_SIZE:
2643 case CASE_SERVICE_PAXOS_PROTOCOL:
2644 case CASE_SERVICE_PAXOS_RECOVERY_POLICY:
2645 case CASE_SERVICE_PAXOS_RETRANSMIT_PERIOD:
2646 case CASE_SERVICE_PROLE_EXTRA_TTL:
2647 case CASE_SERVICE_REPLICATION_FIRE_AND_FORGET:
2648 case CASE_SERVICE_SCAN_MAX_ACTIVE:
2649 case CASE_SERVICE_SCAN_MEMORY:
2650 case CASE_SERVICE_SCAN_PRIORITY:
2651 case CASE_SERVICE_SCAN_RETRANSMIT:
2652 case CASE_SERVICE_SCHEDULER_PRIORITY:
2653 case CASE_SERVICE_SCHEDULER_TYPE:
2654 case CASE_SERVICE_TRANSACTION_DUPLICATE_THREADS:
2655 case CASE_SERVICE_TRIAL_ACCOUNT_KEY:
2656 case CASE_SERVICE_UDF_RUNTIME_MAX_GMEMORY:
2657 case CASE_SERVICE_UDF_RUNTIME_MAX_MEMORY:
2658 case CASE_SERVICE_USE_QUEUE_PER_DEVICE:
2659 case CASE_SERVICE_WRITE_DUPLICATE_RESOLUTION_DISABLE:
2660 cfg_deprecated_name_tok(&line);
2661 break;
2662 case CASE_CONTEXT_END:
2663 cfg_end_context(&state);
2664 break;
2665 case CASE_NOT_FOUND:
2666 default:
2667 cfg_unknown_name_tok(&line);
2668 break;
2669 }
2670 break;
2671
2672 //==================================================
2673 // Parse logging context items.
2674 //
2675 case LOGGING:
2676 switch (cfg_find_tok(line.name_tok, LOGGING_OPTS, NUM_LOGGING_OPTS)) {
2677 case CASE_LOG_FILE_BEGIN:
2678 if ((sink = cf_fault_sink_hold(line.val_tok_1)) == NULL) {
2679 cf_crash_nostack(AS_CFG, "line %d :: can't add file %s as log sink", line_num, line.val_tok_1);
2680 }
2681 cfg_begin_context(&state, LOGGING_FILE);
2682 break;
2683 case CASE_LOG_CONSOLE_BEGIN:
2684 if ((sink = cf_fault_sink_hold("stderr")) == NULL) {
2685 cf_crash_nostack(AS_CFG, "line %d :: can't add stderr as log sink", line_num);
2686 }
2687 cfg_begin_context(&state, LOGGING_CONSOLE);
2688 break;
2689 case CASE_CONTEXT_END:
2690 cfg_end_context(&state);
2691 break;
2692 case CASE_NOT_FOUND:
2693 default:
2694 cfg_unknown_name_tok(&line);
2695 break;
2696 }
2697 break;
2698
2699 //----------------------------------------
2700 // Parse logging::file context items.
2701 //
2702 case LOGGING_FILE:
2703 switch (cfg_find_tok(line.name_tok, LOGGING_FILE_OPTS, NUM_LOGGING_FILE_OPTS)) {
2704 case CASE_LOG_FILE_CONTEXT:
2705 if (0 != cf_fault_sink_addcontext(sink, line.val_tok_1, line.val_tok_2)) {
2706 cf_crash_nostack(AS_CFG, "line %d :: can't add logging file context %s %s", line_num, line.val_tok_1, line.val_tok_2);
2707 }
2708 break;
2709 case CASE_CONTEXT_END:
2710 sink = NULL;
2711 cfg_end_context(&state);
2712 break;
2713 case CASE_NOT_FOUND:
2714 default:
2715 cfg_unknown_name_tok(&line);
2716 break;
2717 }
2718 break;
2719
2720 //----------------------------------------
2721 // Parse logging::console context items.
2722 //
2723 case LOGGING_CONSOLE:
2724 switch (cfg_find_tok(line.name_tok, LOGGING_CONSOLE_OPTS, NUM_LOGGING_CONSOLE_OPTS)) {
2725 case CASE_LOG_CONSOLE_CONTEXT:
2726 if (0 != cf_fault_sink_addcontext(sink, line.val_tok_1, line.val_tok_2)) {
2727 cf_crash_nostack(AS_CFG, "line %d :: can't add logging console context %s %s", line_num, line.val_tok_1, line.val_tok_2);
2728 }
2729 break;
2730 case CASE_CONTEXT_END:
2731 sink = NULL;
2732 cfg_end_context(&state);
2733 break;
2734 case CASE_NOT_FOUND:
2735 default:
2736 cfg_unknown_name_tok(&line);
2737 break;
2738 }
2739 break;
2740
2741 //==================================================
2742 // Parse network context items.
2743 //
2744 case NETWORK:
2745 switch (cfg_find_tok(line.name_tok, NETWORK_OPTS, NUM_NETWORK_OPTS)) {
2746 case CASE_NETWORK_SERVICE_BEGIN:
2747 cfg_begin_context(&state, NETWORK_SERVICE);
2748 break;
2749 case CASE_NETWORK_HEARTBEAT_BEGIN:
2750 cfg_begin_context(&state, NETWORK_HEARTBEAT);
2751 break;
2752 case CASE_NETWORK_FABRIC_BEGIN:
2753 cfg_begin_context(&state, NETWORK_FABRIC);
2754 break;
2755 case CASE_NETWORK_INFO_BEGIN:
2756 cfg_begin_context(&state, NETWORK_INFO);
2757 break;
2758 case CASE_NETWORK_TLS_BEGIN:
2759 cfg_enterprise_only(&line);
2760 tls_spec = cfg_create_tls_spec(c, line.val_tok_1);
2761 cfg_begin_context(&state, NETWORK_TLS);
2762 break;
2763 case CASE_CONTEXT_END:
2764 cfg_end_context(&state);
2765 break;
2766 case CASE_NOT_FOUND:
2767 default:
2768 cfg_unknown_name_tok(&line);
2769 break;
2770 }
2771 break;
2772
2773 //----------------------------------------
2774 // Parse network::service context items.
2775 //
2776 case NETWORK_SERVICE:
2777 switch (cfg_find_tok(line.name_tok, NETWORK_SERVICE_OPTS, NUM_NETWORK_SERVICE_OPTS)) {
2778 case CASE_NETWORK_SERVICE_ADDRESS:
2779 cfg_add_addr_bind(line.val_tok_1, &c->service);
2780 break;
2781 case CASE_NETWORK_SERVICE_PORT:
2782 c->service.bind_port = cfg_port(&line);
2783 break;
2784 case CASE_NETWORK_SERVICE_EXTERNAL_ADDRESS:
2785 cfg_renamed_name_tok(&line, "access-address");
2786 // No break.
2787 case CASE_NETWORK_SERVICE_ACCESS_ADDRESS:
2788 cfg_add_addr_std(line.val_tok_1, &c->service);
2789 break;
2790 case CASE_NETWORK_SERVICE_ACCESS_PORT:
2791 c->service.std_port = cfg_port(&line);
2792 break;
2793 case CASE_NETWORK_SERVICE_ALTERNATE_ACCESS_ADDRESS:
2794 cfg_add_addr_alt(line.val_tok_1, &c->service);
2795 break;
2796 case CASE_NETWORK_SERVICE_ALTERNATE_ACCESS_PORT:
2797 c->service.alt_port = cfg_port(&line);
2798 break;
2799 case CASE_NETWORK_SERVICE_TLS_ACCESS_ADDRESS:
2800 cfg_enterprise_only(&line);
2801 cfg_add_addr_std(line.val_tok_1, &c->tls_service);
2802 break;
2803 case CASE_NETWORK_SERVICE_TLS_ACCESS_PORT:
2804 cfg_enterprise_only(&line);
2805 c->tls_service.std_port = cfg_port(&line);
2806 break;
2807 case CASE_NETWORK_SERVICE_TLS_ADDRESS:
2808 cfg_enterprise_only(&line);
2809 cfg_add_addr_bind(line.val_tok_1, &c->tls_service);
2810 break;
2811 case CASE_NETWORK_SERVICE_TLS_ALTERNATE_ACCESS_ADDRESS:
2812 cfg_enterprise_only(&line);
2813 cfg_add_addr_alt(line.val_tok_1, &c->tls_service);
2814 break;
2815 case CASE_NETWORK_SERVICE_TLS_ALTERNATE_ACCESS_PORT:
2816 cfg_enterprise_only(&line);
2817 c->tls_service.alt_port = cfg_port(&line);
2818 break;
2819 case CASE_NETWORK_SERVICE_TLS_AUTHENTICATE_CLIENT:
2820 cfg_enterprise_only(&line);
2821 add_tls_peer_name(line.val_tok_1, &c->tls_service);
2822 break;
2823 case CASE_NETWORK_SERVICE_TLS_NAME:
2824 cfg_enterprise_only(&line);
2825 c->tls_service.tls_our_name = cfg_strdup_no_checks(&line);
2826 break;
2827 case CASE_NETWORK_SERVICE_TLS_PORT:
2828 cfg_enterprise_only(&line);
2829 c->tls_service.bind_port = cfg_port(&line);
2830 break;
2831 case CASE_NETWORK_SERVICE_ALTERNATE_ADDRESS:
2832 cfg_obsolete(&line, "see Aerospike documentation http://www.aerospike.com/docs/operations/upgrade/network_to_3_10");
2833 break;
2834 case CASE_NETWORK_SERVICE_NETWORK_INTERFACE_NAME:
2835 cfg_obsolete(&line, "see Aerospike documentation http://www.aerospike.com/docs/operations/upgrade/network_to_3_10");
2836 break;
2837 case CASE_NETWORK_SERVICE_REUSE_ADDRESS:
2838 cfg_deprecated_name_tok(&line);
2839 break;
2840 case CASE_CONTEXT_END:
2841 cfg_end_context(&state);
2842 break;
2843 case CASE_NOT_FOUND:
2844 default:
2845 cfg_unknown_name_tok(&line);
2846 break;
2847 }
2848 break;
2849
2850 //----------------------------------------
2851 // Parse network::heartbeat context items.
2852 //
2853 case NETWORK_HEARTBEAT:
2854 switch (cfg_find_tok(line.name_tok, NETWORK_HEARTBEAT_OPTS, NUM_NETWORK_HEARTBEAT_OPTS)) {
2855 case CASE_NETWORK_HEARTBEAT_MODE:
2856 switch (cfg_find_tok(line.val_tok_1, NETWORK_HEARTBEAT_MODE_OPTS, NUM_NETWORK_HEARTBEAT_MODE_OPTS)) {
2857 case CASE_NETWORK_HEARTBEAT_MODE_MULTICAST:
2858 c->hb_config.mode = AS_HB_MODE_MULTICAST;
2859 break;
2860 case CASE_NETWORK_HEARTBEAT_MODE_MESH:
2861 c->hb_config.mode = AS_HB_MODE_MESH;
2862 break;
2863 case CASE_NOT_FOUND:
2864 default:
2865 cfg_unknown_val_tok_1(&line);
2866 break;
2867 }
2868 break;
2869 case CASE_NETWORK_HEARTBEAT_ADDRESS:
2870 cfg_add_addr_bind(line.val_tok_1, &c->hb_serv_spec);
2871 break;
2872 case CASE_NETWORK_HEARTBEAT_MULTICAST_GROUP:
2873 add_addr(line.val_tok_1, &c->hb_multicast_groups);
2874 break;
2875 case CASE_NETWORK_HEARTBEAT_PORT:
2876 c->hb_serv_spec.bind_port = cfg_port(&line);
2877 break;
2878 case CASE_NETWORK_HEARTBEAT_MESH_SEED_ADDRESS_PORT:
2879 cfg_add_mesh_seed_addr_port(cfg_strdup_no_checks(&line), cfg_port_val2(&line), false);
2880 break;
2881 case CASE_NETWORK_HEARTBEAT_INTERVAL:
2882 c->hb_config.tx_interval = cfg_u32(&line, AS_HB_TX_INTERVAL_MS_MIN, AS_HB_TX_INTERVAL_MS_MAX);
2883 break;
2884 case CASE_NETWORK_HEARTBEAT_TIMEOUT:
2885 c->hb_config.max_intervals_missed = cfg_u32(&line, AS_HB_MAX_INTERVALS_MISSED_MIN, UINT32_MAX);
2886 break;
2887 case CASE_NETWORK_HEARTBEAT_MTU:
2888 c->hb_config.override_mtu = cfg_u32_no_checks(&line);
2889 break;
2890 case CASE_NETWORK_HEARTBEAT_MCAST_TTL:
2891 cfg_renamed_name_tok(&line, "multicast-ttl");
2892 // No break.
2893 case CASE_NETWORK_HEARTBEAT_MULTICAST_TTL:
2894 c->hb_config.multicast_ttl = cfg_u8_no_checks(&line);
2895 break;
2896 case CASE_NETWORK_HEARTBEAT_PROTOCOL:
2897 switch (cfg_find_tok(line.val_tok_1, NETWORK_HEARTBEAT_PROTOCOL_OPTS, NUM_NETWORK_HEARTBEAT_PROTOCOL_OPTS)) {
2898 case CASE_NETWORK_HEARTBEAT_PROTOCOL_NONE:
2899 c->hb_config.protocol = AS_HB_PROTOCOL_NONE;
2900 break;
2901 case CASE_NETWORK_HEARTBEAT_PROTOCOL_V3:
2902 c->hb_config.protocol = AS_HB_PROTOCOL_V3;
2903 break;
2904 case CASE_NOT_FOUND:
2905 default:
2906 cfg_unknown_val_tok_1(&line);
2907 break;
2908 }
2909 break;
2910 case CASE_NETWORK_HEARTBEAT_TLS_ADDRESS:
2911 cfg_enterprise_only(&line);
2912 cfg_add_addr_bind(line.val_tok_1, &c->hb_tls_serv_spec);
2913 break;
2914 case CASE_NETWORK_HEARTBEAT_TLS_MESH_SEED_ADDRESS_PORT:
2915 cfg_add_mesh_seed_addr_port(cfg_strdup_no_checks(&line), cfg_port_val2(&line), true);
2916 break;
2917 case CASE_NETWORK_HEARTBEAT_TLS_NAME:
2918 cfg_enterprise_only(&line);
2919 c->hb_tls_serv_spec.tls_our_name = cfg_strdup_no_checks(&line);
2920 break;
2921 case CASE_NETWORK_HEARTBEAT_TLS_PORT:
2922 cfg_enterprise_only(&line);
2923 c->hb_tls_serv_spec.bind_port = cfg_port(&line);
2924 break;
2925 case CASE_NETWORK_HEARTBEAT_INTERFACE_ADDRESS:
2926 cfg_obsolete(&line, "see Aerospike documentation http://www.aerospike.com/docs/operations/upgrade/network_to_3_10");
2927 break;
2928 case CASE_CONTEXT_END:
2929 cfg_end_context(&state);
2930 break;
2931 case CASE_NOT_FOUND:
2932 default:
2933 cfg_unknown_name_tok(&line);
2934 break;
2935 }
2936 break;
2937
2938 //----------------------------------------
2939 // Parse network::fabric context items.
2940 //
2941 case NETWORK_FABRIC:
2942 switch (cfg_find_tok(line.name_tok, NETWORK_FABRIC_OPTS, NUM_NETWORK_FABRIC_OPTS)) {
2943 case CASE_NETWORK_FABRIC_ADDRESS:
2944 cfg_add_addr_bind(line.val_tok_1, &c->fabric);
2945 break;
2946 case CASE_NETWORK_FABRIC_PORT:
2947 c->fabric.bind_port = cfg_port(&line);
2948 break;
2949 case CASE_NETWORK_FABRIC_CHANNEL_BULK_FDS:
2950 c->n_fabric_channel_fds[AS_FABRIC_CHANNEL_BULK] = cfg_u32(&line, 1, MAX_FABRIC_CHANNEL_SOCKETS);
2951 break;
2952 case CASE_NETWORK_FABRIC_CHANNEL_BULK_RECV_THREADS:
2953 c->n_fabric_channel_recv_threads[AS_FABRIC_CHANNEL_BULK] = cfg_u32(&line, 1, MAX_FABRIC_CHANNEL_THREADS);
2954 break;
2955 case CASE_NETWORK_FABRIC_CHANNEL_CTRL_FDS:
2956 c->n_fabric_channel_fds[AS_FABRIC_CHANNEL_CTRL] = cfg_u32(&line, 1, MAX_FABRIC_CHANNEL_SOCKETS);
2957 break;
2958 case CASE_NETWORK_FABRIC_CHANNEL_CTRL_RECV_THREADS:
2959 c->n_fabric_channel_recv_threads[AS_FABRIC_CHANNEL_CTRL] = cfg_u32(&line, 1, MAX_FABRIC_CHANNEL_THREADS);
2960 break;
2961 case CASE_NETWORK_FABRIC_CHANNEL_META_FDS:
2962 c->n_fabric_channel_fds[AS_FABRIC_CHANNEL_META] = cfg_u32(&line, 1, MAX_FABRIC_CHANNEL_SOCKETS);
2963 break;
2964 case CASE_NETWORK_FABRIC_CHANNEL_META_RECV_THREADS:
2965 c->n_fabric_channel_recv_threads[AS_FABRIC_CHANNEL_META] = cfg_u32(&line, 1, MAX_FABRIC_CHANNEL_THREADS);
2966 break;
2967 case CASE_NETWORK_FABRIC_CHANNEL_RW_FDS:
2968 c->n_fabric_channel_fds[AS_FABRIC_CHANNEL_RW] = cfg_u32(&line, 1, MAX_FABRIC_CHANNEL_SOCKETS);
2969 break;
2970 case CASE_NETWORK_FABRIC_CHANNEL_RW_RECV_THREADS:
2971 c->n_fabric_channel_recv_threads[AS_FABRIC_CHANNEL_RW] = cfg_u32(&line, 1, MAX_FABRIC_CHANNEL_THREADS);
2972 break;
2973 case CASE_NETWORK_FABRIC_KEEPALIVE_ENABLED:
2974 c->fabric_keepalive_enabled = cfg_bool(&line);
2975 break;
2976 case CASE_NETWORK_FABRIC_KEEPALIVE_INTVL:
2977 c->fabric_keepalive_intvl = cfg_int_no_checks(&line);
2978 break;
2979 case CASE_NETWORK_FABRIC_KEEPALIVE_PROBES:
2980 c->fabric_keepalive_probes = cfg_int_no_checks(&line);
2981 break;
2982 case CASE_NETWORK_FABRIC_KEEPALIVE_TIME:
2983 c->fabric_keepalive_time = cfg_int_no_checks(&line);
2984 break;
2985 case CASE_NETWORK_FABRIC_LATENCY_MAX_MS:
2986 c->fabric_latency_max_ms = cfg_int(&line, 0, 1000);
2987 break;
2988 case CASE_NETWORK_FABRIC_RECV_REARM_THRESHOLD:
2989 c->fabric_recv_rearm_threshold = cfg_u32(&line, 0, 1024 * 1024);
2990 break;
2991 case CASE_NETWORK_FABRIC_SEND_THREADS:
2992 c->n_fabric_send_threads = cfg_u32(&line, 1, MAX_FABRIC_CHANNEL_THREADS);
2993 break;
2994 case CASE_NETWORK_FABRIC_TLS_ADDRESS:
2995 cfg_enterprise_only(&line);
2996 cfg_add_addr_bind(line.val_tok_1, &c->tls_fabric);
2997 break;
2998 case CASE_NETWORK_FABRIC_TLS_NAME:
2999 cfg_enterprise_only(&line);
3000 c->tls_fabric.tls_our_name = cfg_strdup_no_checks(&line);
3001 break;
3002 case CASE_NETWORK_FABRIC_TLS_PORT:
3003 cfg_enterprise_only(&line);
3004 c->tls_fabric.bind_port = cfg_port(&line);
3005 break;
3006 case CASE_CONTEXT_END:
3007 cfg_end_context(&state);
3008 break;
3009 case CASE_NOT_FOUND:
3010 default:
3011 cfg_unknown_name_tok(&line);
3012 break;
3013 }
3014 break;
3015
3016 //----------------------------------------
3017 // Parse network::info context items.
3018 //
3019 case NETWORK_INFO:
3020 switch (cfg_find_tok(line.name_tok, NETWORK_INFO_OPTS, NUM_NETWORK_INFO_OPTS)) {
3021 case CASE_NETWORK_INFO_ADDRESS:
3022 cfg_add_addr_bind(line.val_tok_1, &c->info);
3023 break;
3024 case CASE_NETWORK_INFO_PORT:
3025 c->info.bind_port = cfg_port(&line);
3026 break;
3027 case CASE_NETWORK_INFO_ENABLE_FASTPATH:
3028 cfg_deprecated_name_tok(&line);
3029 break;
3030 case CASE_CONTEXT_END:
3031 cfg_end_context(&state);
3032 break;
3033 case CASE_NOT_FOUND:
3034 default:
3035 cfg_unknown_name_tok(&line);
3036 break;
3037 }
3038 break;
3039
3040 //----------------------------------------
3041 // Parse network::tls context items.
3042 //
3043 case NETWORK_TLS:
3044 switch (cfg_find_tok(line.name_tok, NETWORK_TLS_OPTS, NUM_NETWORK_TLS_OPTS)) {
3045 case CASE_NETWORK_TLS_CA_FILE:
3046 tls_spec->ca_file = cfg_strdup_no_checks(&line);
3047 break;
3048 case CASE_NETWORK_TLS_CA_PATH:
3049 tls_spec->ca_path = cfg_strdup_no_checks(&line);
3050 break;
3051 case CASE_NETWORK_TLS_CERT_BLACKLIST:
3052 tls_spec->cert_blacklist = cfg_strdup_no_checks(&line);
3053 break;
3054 case CASE_NETWORK_TLS_CERT_FILE:
3055 tls_spec->cert_file = cfg_strdup_no_checks(&line);
3056 break;
3057 case CASE_NETWORK_TLS_CIPHER_SUITE:
3058 tls_spec->cipher_suite = cfg_strdup_no_checks(&line);
3059 break;
3060 case CASE_NETWORK_TLS_KEY_FILE:
3061 tls_spec->key_file = cfg_strdup_no_checks(&line);
3062 break;
3063 case CASE_NETWORK_TLS_KEY_FILE_PASSWORD:
3064 tls_spec->key_file_password = cfg_strdup_no_checks(&line);
3065 break;
3066 case CASE_NETWORK_TLS_PROTOCOLS:
3067 tls_spec->protocols = cfg_strdup_no_checks(&line);
3068 break;
3069 case CASE_CONTEXT_END:
3070 tls_spec = NULL;
3071 cfg_end_context(&state);
3072 break;
3073 case CASE_NOT_FOUND:
3074 default:
3075 cfg_unknown_name_tok(&line);
3076 break;
3077 }
3078 break;
3079
3080 //==================================================
3081 // Parse namespace items.
3082 //
3083 case NAMESPACE:
3084 switch (cfg_find_tok(line.name_tok, NAMESPACE_OPTS, NUM_NAMESPACE_OPTS)) {
3085 case CASE_NAMESPACE_REPLICATION_FACTOR:
3086 ns->cfg_replication_factor = cfg_u32(&line, 1, AS_CLUSTER_SZ);
3087 break;
3088 case CASE_NAMESPACE_LIMIT_SIZE:
3089 cfg_renamed_name_tok(&line, "memory-size");
3090 // No break.
3091 case CASE_NAMESPACE_MEMORY_SIZE:
3092 ns->memory_size = cfg_u64(&line, 1024 * 1024, UINT64_MAX);
3093 break;
3094 case CASE_NAMESPACE_DEFAULT_TTL:
3095 ns->default_ttl = cfg_seconds(&line, 0, MAX_ALLOWED_TTL);
3096 break;
3097 case CASE_NAMESPACE_STORAGE_ENGINE_BEGIN:
3098 switch (cfg_find_tok(line.val_tok_1, NAMESPACE_STORAGE_OPTS, NUM_NAMESPACE_STORAGE_OPTS)) {
3099 case CASE_NAMESPACE_STORAGE_MEMORY:
3100 ns->storage_type = AS_STORAGE_ENGINE_MEMORY;
3101 ns->storage_data_in_memory = true;
3102 break;
3103 case CASE_NAMESPACE_STORAGE_SSD:
3104 cfg_renamed_val_tok_1(&line, "device");
3105 // No break.
3106 case CASE_NAMESPACE_STORAGE_DEVICE:
3107 ns->storage_type = AS_STORAGE_ENGINE_SSD;
3108 ns->storage_data_in_memory = false;
3109 cfg_begin_context(&state, NAMESPACE_STORAGE_DEVICE);
3110 break;
3111 case CASE_NOT_FOUND:
3112 default:
3113 cfg_unknown_val_tok_1(&line);
3114 break;
3115 }
3116 break;
3117 case CASE_NAMESPACE_ENABLE_XDR:
3118 cfg_enterprise_only(&line);
3119 ns->enable_xdr = cfg_bool(&line);
3120 break;
3121 case CASE_NAMESPACE_SETS_ENABLE_XDR:
3122 ns->sets_enable_xdr = cfg_bool(&line);
3123 break;
3124 case CASE_NAMESPACE_FORWARD_XDR_WRITES:
3125 ns->ns_forward_xdr_writes = cfg_bool(&line);
3126 break;
3127 case CASE_NAMESPACE_XDR_REMOTE_DATACENTER:
3128 xdr_cfg_associate_datacenter(cfg_strdup(&line, true), ns->id);
3129 break;
3130 case CASE_NAMESPACE_ALLOW_NONXDR_WRITES:
3131 ns->ns_allow_nonxdr_writes = cfg_bool(&line);
3132 break;
3133 case CASE_NAMESPACE_ALLOW_XDR_WRITES:
3134 ns->ns_allow_xdr_writes = cfg_bool(&line);
3135 break;
3136 case CASE_NAMESPACE_BACKGROUND_SCAN_MAX_RPS:
3137 ns->background_scan_max_rps = cfg_u32(&line, 1, 1000000);
3138 break;
3139 case CASE_NAMESPACE_CONFLICT_RESOLUTION_POLICY:
3140 switch (cfg_find_tok(line.val_tok_1, NAMESPACE_CONFLICT_RESOLUTION_OPTS, NUM_NAMESPACE_CONFLICT_RESOLUTION_OPTS)) {
3141 case CASE_NAMESPACE_CONFLICT_RESOLUTION_GENERATION:
3142 ns->conflict_resolution_policy = AS_NAMESPACE_CONFLICT_RESOLUTION_POLICY_GENERATION;
3143 break;
3144 case CASE_NAMESPACE_CONFLICT_RESOLUTION_LAST_UPDATE_TIME:
3145 ns->conflict_resolution_policy = AS_NAMESPACE_CONFLICT_RESOLUTION_POLICY_LAST_UPDATE_TIME;
3146 break;
3147 case CASE_NOT_FOUND:
3148 default:
3149 cfg_unknown_val_tok_1(&line);
3150 break;
3151 }
3152 break;
3153 case CASE_NAMESPACE_DATA_IN_INDEX:
3154 ns->data_in_index = cfg_bool(&line);
3155 break;
3156 case CASE_NAMESPACE_DISABLE_COLD_START_EVICTION:
3157 ns->cold_start_eviction_disabled = cfg_bool(&line);
3158 break;
3159 case CASE_NAMESPACE_DISABLE_WRITE_DUP_RES:
3160 ns->write_dup_res_disabled = cfg_bool(&line);
3161 break;
3162 case CASE_NAMESPACE_DISALLOW_NULL_SETNAME:
3163 ns->disallow_null_setname = cfg_bool(&line);
3164 break;
3165 case CASE_NAMESPACE_ENABLE_BENCHMARKS_BATCH_SUB:
3166 ns->batch_sub_benchmarks_enabled = true;
3167 break;
3168 case CASE_NAMESPACE_ENABLE_BENCHMARKS_OPS_SUB:
3169 ns->ops_sub_benchmarks_enabled = true;
3170 break;
3171 case CASE_NAMESPACE_ENABLE_BENCHMARKS_READ:
3172 ns->read_benchmarks_enabled = true;
3173 break;
3174 case CASE_NAMESPACE_ENABLE_BENCHMARKS_UDF:
3175 ns->udf_benchmarks_enabled = true;
3176 break;
3177 case CASE_NAMESPACE_ENABLE_BENCHMARKS_UDF_SUB:
3178 ns->udf_sub_benchmarks_enabled = true;
3179 break;
3180 case CASE_NAMESPACE_ENABLE_BENCHMARKS_WRITE:
3181 ns->write_benchmarks_enabled = true;
3182 break;
3183 case CASE_NAMESPACE_ENABLE_HIST_PROXY:
3184 ns->proxy_hist_enabled = cfg_bool(&line);
3185 break;
3186 case CASE_NAMESPACE_EVICT_HIST_BUCKETS:
3187 ns->evict_hist_buckets = cfg_u32(&line, 100, 10000000);
3188 break;
3189 case CASE_NAMESPACE_EVICT_TENTHS_PCT:
3190 ns->evict_tenths_pct = cfg_u32_no_checks(&line);
3191 break;
3192 case CASE_NAMESPACE_HIGH_WATER_DISK_PCT:
3193 ns->hwm_disk_pct = cfg_u32(&line, 0, 100);
3194 break;
3195 case CASE_NAMESPACE_HIGH_WATER_MEMORY_PCT:
3196 ns->hwm_memory_pct = cfg_u32(&line, 0, 100);
3197 break;
3198 case CASE_NAMESPACE_INDEX_STAGE_SIZE:
3199 ns->index_stage_size = cfg_u64_power_of_2(&line, CF_ARENAX_MIN_STAGE_SIZE, CF_ARENAX_MAX_STAGE_SIZE);
3200 break;
3201 case CASE_NAMESPACE_INDEX_TYPE_BEGIN:
3202 cfg_enterprise_only(&line);
3203 switch (cfg_find_tok(line.val_tok_1, NAMESPACE_INDEX_TYPE_OPTS, NUM_NAMESPACE_INDEX_TYPE_OPTS)) {
3204 case CASE_NAMESPACE_INDEX_TYPE_SHMEM:
3205 ns->xmem_type = CF_XMEM_TYPE_SHMEM;
3206 break;
3207 case CASE_NAMESPACE_INDEX_TYPE_PMEM:
3208 ns->xmem_type = CF_XMEM_TYPE_PMEM;
3209 cfg_begin_context(&state, NAMESPACE_INDEX_TYPE_PMEM);
3210 break;
3211 case CASE_NAMESPACE_INDEX_TYPE_FLASH:
3212 ns->xmem_type = CF_XMEM_TYPE_FLASH;
3213 cfg_begin_context(&state, NAMESPACE_INDEX_TYPE_FLASH);
3214 break;
3215 case CASE_NOT_FOUND:
3216 default:
3217 cfg_unknown_val_tok_1(&line);
3218 break;
3219 }
3220 break;
3221 case CASE_NAMESPACE_MIGRATE_ORDER:
3222 ns->migrate_order = cfg_u32(&line, 1, 10);
3223 break;
3224 case CASE_NAMESPACE_MIGRATE_RETRANSMIT_MS:
3225 ns->migrate_retransmit_ms = cfg_u32_no_checks(&line);
3226 break;
3227 case CASE_NAMESPACE_MIGRATE_SLEEP:
3228 ns->migrate_sleep = cfg_u32_no_checks(&line);
3229 break;
3230 case CASE_NAMESPACE_NSUP_HIST_PERIOD:
3231 ns->nsup_hist_period = cfg_u32_no_checks(&line);
3232 break;
3233 case CASE_NAMESPACE_NSUP_PERIOD:
3234 ns->nsup_period = cfg_u32_no_checks(&line);
3235 break;
3236 case CASE_NAMESPACE_NSUP_THREADS:
3237 ns->n_nsup_threads = cfg_u32(&line, 1, 128);
3238 break;
3239 case CASE_NAMESPACE_PARTITION_TREE_SPRIGS:
3240 ns->tree_shared.n_sprigs = cfg_u32_power_of_2(&line, NUM_LOCK_PAIRS, 1 << NUM_SPRIG_BITS);
3241 break;
3242 case CASE_NAMESPACE_PREFER_UNIFORM_BALANCE:
3243 cfg_enterprise_only(&line);
3244 ns->cfg_prefer_uniform_balance = cfg_bool(&line);
3245 break;
3246 case CASE_NAMESPACE_RACK_ID:
3247 cfg_enterprise_only(&line);
3248 ns->rack_id = cfg_u32(&line, 0, MAX_RACK_ID);
3249 break;
3250 case CASE_NAMESPACE_READ_CONSISTENCY_LEVEL_OVERRIDE:
3251 switch (cfg_find_tok(line.val_tok_1, NAMESPACE_READ_CONSISTENCY_OPTS, NUM_NAMESPACE_READ_CONSISTENCY_OPTS)) {
3252 case CASE_NAMESPACE_READ_CONSISTENCY_ALL:
3253 ns->read_consistency_level = AS_READ_CONSISTENCY_LEVEL_ALL;
3254 break;
3255 case CASE_NAMESPACE_READ_CONSISTENCY_OFF:
3256 ns->read_consistency_level = AS_READ_CONSISTENCY_LEVEL_PROTO;
3257 break;
3258 case CASE_NAMESPACE_READ_CONSISTENCY_ONE:
3259 ns->read_consistency_level = AS_READ_CONSISTENCY_LEVEL_ONE;
3260 break;
3261 case CASE_NOT_FOUND:
3262 default:
3263 cfg_unknown_val_tok_1(&line);
3264 break;
3265 }
3266 break;
3267 case CASE_NAMESPACE_SET_BEGIN:
3268 p_set = cfg_add_set(ns);
3269 cfg_strcpy(&line, p_set->name, AS_SET_NAME_MAX_SIZE);
3270 cfg_begin_context(&state, NAMESPACE_SET);
3271 break;
3272 case CASE_NAMESPACE_SINDEX_BEGIN:
3273 cfg_begin_context(&state, NAMESPACE_SINDEX);
3274 break;
3275 case CASE_NAMESPACE_GEO2DSPHERE_WITHIN_BEGIN:
3276 cfg_begin_context(&state, NAMESPACE_GEO2DSPHERE_WITHIN);
3277 break;
3278 case CASE_NAMESPACE_SINGLE_BIN:
3279 ns->single_bin = cfg_bool(&line);
3280 break;
3281 case CASE_NAMESPACE_SINGLE_SCAN_THREADS:
3282 ns->n_single_scan_threads = cfg_u32(&line, 1, 128);
3283 break;
3284 case CASE_NAMESPACE_STOP_WRITES_PCT:
3285 ns->stop_writes_pct = cfg_u32(&line, 0, 100);
3286 break;
3287 case CASE_NAMESPACE_STRONG_CONSISTENCY:
3288 cfg_enterprise_only(&line);
3289 ns->cp = cfg_bool(&line);
3290 break;
3291 case CASE_NAMESPACE_STRONG_CONSISTENCY_ALLOW_EXPUNGE:
3292 cfg_enterprise_only(&line);
3293 ns->cp_allow_drops = cfg_bool(&line);
3294 break;
3295 case CASE_NAMESPACE_TOMB_RAIDER_ELIGIBLE_AGE:
3296 cfg_enterprise_only(&line);
3297 ns->tomb_raider_eligible_age = cfg_seconds_no_checks(&line);
3298 break;
3299 case CASE_NAMESPACE_TOMB_RAIDER_PERIOD:
3300 cfg_enterprise_only(&line);
3301 ns->tomb_raider_period = cfg_seconds_no_checks(&line);
3302 break;
3303 case CASE_NAMESPACE_TRANSACTION_PENDING_LIMIT:
3304 ns->transaction_pending_limit = cfg_u32_no_checks(&line);
3305 break;
3306 case CASE_NAMESPACE_TRUNCATE_THREADS:
3307 ns->n_truncate_threads = cfg_u32(&line, 1, MAX_TRUNCATE_THREADS);
3308 break;
3309 case CASE_NAMESPACE_WRITE_COMMIT_LEVEL_OVERRIDE:
3310 switch (cfg_find_tok(line.val_tok_1, NAMESPACE_WRITE_COMMIT_OPTS, NUM_NAMESPACE_WRITE_COMMIT_OPTS)) {
3311 case CASE_NAMESPACE_WRITE_COMMIT_ALL:
3312 ns->write_commit_level = AS_WRITE_COMMIT_LEVEL_ALL;
3313 break;
3314 case CASE_NAMESPACE_WRITE_COMMIT_MASTER:
3315 ns->write_commit_level = AS_WRITE_COMMIT_LEVEL_MASTER;
3316 break;
3317 case CASE_NAMESPACE_WRITE_COMMIT_OFF:
3318 ns->write_commit_level = AS_WRITE_COMMIT_LEVEL_PROTO;
3319 break;
3320 case CASE_NOT_FOUND:
3321 default:
3322 cfg_unknown_val_tok_1(&line);
3323 break;
3324 }
3325 break;
3326 case CASE_NAMESPACE_DISABLE_NSUP:
3327 cfg_obsolete(&line, "please set namespace-context 'nsup-period' to 0 to disable nsup");
3328 break;
3329 case CASE_NAMESPACE_ALLOW_VERSIONS:
3330 case CASE_NAMESPACE_COLD_START_EVICT_TTL:
3331 case CASE_NAMESPACE_DEMO_READ_MULTIPLIER:
3332 case CASE_NAMESPACE_DEMO_WRITE_MULTIPLIER:
3333 case CASE_NAMESPACE_HIGH_WATER_PCT:
3334 case CASE_NAMESPACE_LOW_WATER_PCT:
3335 case CASE_NAMESPACE_MAX_TTL:
3336 case CASE_NAMESPACE_OBJ_SIZE_HIST_MAX:
3337 case CASE_NAMESPACE_PARTITION_TREE_LOCKS:
3338 cfg_deprecated_name_tok(&line);
3339 break;
3340 case CASE_NAMESPACE_SI_BEGIN:
3341 cfg_deprecated_name_tok(&line);
3342 // Entire section is deprecated but needs to begin and end the
3343 // context to avoid crash.
3344 cfg_begin_context(&state, NAMESPACE_SI);
3345 break;
3346 case CASE_CONTEXT_END:
3347 if (ns->memory_size == 0) {
3348 cf_crash_nostack(AS_CFG, "{%s} must configure non-zero 'memory-size'", ns->name);
3349 }
3350 if (ns->data_in_index && ! (ns->single_bin && ns->storage_data_in_memory && ns->storage_type == AS_STORAGE_ENGINE_SSD)) {
3351 cf_crash_nostack(AS_CFG, "ns %s data-in-index can't be true unless storage-engine is device and both single-bin and data-in-memory are true", ns->name);
3352 }
3353 if (ns->storage_data_in_memory) {
3354 ns->storage_post_write_queue = 0; // override default (or configuration mistake)
3355 }
3356 if (ns->storage_data_in_memory &&
3357 ! ns->storage_commit_to_device) {
3358 c->n_namespaces_inlined++;
3359 }
3360 else {
3361 c->n_namespaces_not_inlined++;
3362 }
3363 ns = NULL;
3364 cfg_end_context(&state);
3365 break;
3366 case CASE_NOT_FOUND:
3367 default:
3368 cfg_unknown_name_tok(&line);
3369 break;
3370 }
3371 break;
3372
3373 //----------------------------------------
3374 // Parse namespace::index-type pmem context items.
3375 //
3376 case NAMESPACE_INDEX_TYPE_PMEM:
3377 switch (cfg_find_tok(line.name_tok, NAMESPACE_INDEX_TYPE_PMEM_OPTS, NUM_NAMESPACE_INDEX_TYPE_PMEM_OPTS)) {
3378 case CASE_NAMESPACE_INDEX_TYPE_PMEM_MOUNT:
3379 cfg_add_xmem_mount(ns, cfg_strdup(&line, true));
3380 break;
3381 case CASE_NAMESPACE_INDEX_TYPE_PMEM_MOUNTS_HIGH_WATER_PCT:
3382 ns->mounts_hwm_pct = cfg_u32(&line, 0, 100);
3383 break;
3384 case CASE_NAMESPACE_INDEX_TYPE_PMEM_MOUNTS_SIZE_LIMIT:
3385 ns->mounts_size_limit = cfg_u64(&line, 1024UL * 1024UL * 1024UL, UINT64_MAX);
3386 break;
3387 case CASE_CONTEXT_END:
3388 if (ns->mounts_size_limit == 0) {
3389 cf_crash_nostack(AS_CFG, "{%s} must configure 'mounts-size-limit'", ns->name);
3390 }
3391 cfg_end_context(&state);
3392 break;
3393 case CASE_NOT_FOUND:
3394 default:
3395 cfg_unknown_name_tok(&line);
3396 break;
3397 }
3398 break;
3399
3400 //----------------------------------------
3401 // Parse namespace::index-type flash context items.
3402 //
3403 case NAMESPACE_INDEX_TYPE_FLASH:
3404 switch (cfg_find_tok(line.name_tok, NAMESPACE_INDEX_TYPE_FLASH_OPTS, NUM_NAMESPACE_INDEX_TYPE_FLASH_OPTS)) {
3405 case CASE_NAMESPACE_INDEX_TYPE_FLASH_MOUNT:
3406 cfg_add_xmem_mount(ns, cfg_strdup(&line, true));
3407 break;
3408 case CASE_NAMESPACE_INDEX_TYPE_FLASH_MOUNTS_HIGH_WATER_PCT:
3409 ns->mounts_hwm_pct = cfg_u32(&line, 0, 100);
3410 break;
3411 case CASE_NAMESPACE_INDEX_TYPE_FLASH_MOUNTS_SIZE_LIMIT:
3412 ns->mounts_size_limit = cfg_u64(&line, 1024UL * 1024UL * 1024UL * 4UL, UINT64_MAX);
3413 break;
3414 case CASE_CONTEXT_END:
3415 if (ns->mounts_size_limit == 0) {
3416 cf_crash_nostack(AS_CFG, "{%s} must configure 'mounts-size-limit'", ns->name);
3417 }
3418 cfg_end_context(&state);
3419 // TODO - main() doesn't yet support initialization as root.
3420 cf_page_cache_dirty_limits();
3421 break;
3422 case CASE_NOT_FOUND:
3423 default:
3424 cfg_unknown_name_tok(&line);
3425 break;
3426 }
3427 break;
3428
3429 //----------------------------------------
3430 // Parse namespace::storage-engine device context items.
3431 //
3432 case NAMESPACE_STORAGE_DEVICE:
3433 switch (cfg_find_tok(line.name_tok, NAMESPACE_STORAGE_DEVICE_OPTS, NUM_NAMESPACE_STORAGE_DEVICE_OPTS)) {
3434 case CASE_NAMESPACE_STORAGE_DEVICE_DEVICE:
3435 cfg_add_storage_device(ns, cfg_strdup(&line, true), cfg_strdup_val2(&line, false));
3436 break;
3437 case CASE_NAMESPACE_STORAGE_DEVICE_FILE:
3438 cfg_add_storage_file(ns, cfg_strdup(&line, true), cfg_strdup_val2(&line, false));
3439 break;
3440 case CASE_NAMESPACE_STORAGE_DEVICE_FILESIZE:
3441 ns->storage_filesize = cfg_u64(&line, 1024 * 1024, AS_STORAGE_MAX_DEVICE_SIZE);
3442 break;
3443 case CASE_NAMESPACE_STORAGE_DEVICE_SCHEDULER_MODE:
3444 ns->storage_scheduler_mode = cfg_strdup_one_of(&line, DEVICE_SCHEDULER_MODES, NUM_DEVICE_SCHEDULER_MODES);
3445 break;
3446 case CASE_NAMESPACE_STORAGE_DEVICE_WRITE_BLOCK_SIZE:
3447 ns->storage_write_block_size = cfg_u32_power_of_2(&line, MIN_WRITE_BLOCK_SIZE, MAX_WRITE_BLOCK_SIZE);
3448 break;
3449 case CASE_NAMESPACE_STORAGE_DEVICE_MEMORY_ALL:
3450 cfg_renamed_name_tok(&line, "data-in-memory");
3451 // No break.
3452 case CASE_NAMESPACE_STORAGE_DEVICE_DATA_IN_MEMORY:
3453 ns->storage_data_in_memory = cfg_bool(&line);
3454 break;
3455 case CASE_NAMESPACE_STORAGE_DEVICE_COLD_START_EMPTY:
3456 ns->storage_cold_start_empty = cfg_bool(&line);
3457 break;
3458 case CASE_NAMESPACE_STORAGE_DEVICE_COMMIT_TO_DEVICE:
3459 cfg_enterprise_only(&line);
3460 ns->storage_commit_to_device = cfg_bool(&line);
3461 break;
3462 case CASE_NAMESPACE_STORAGE_DEVICE_COMMIT_MIN_SIZE:
3463 cfg_enterprise_only(&line);
3464 ns->storage_commit_min_size = cfg_u32_power_of_2(&line, 0, MAX_WRITE_BLOCK_SIZE);
3465 break;
3466 case CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION:
3467 cfg_enterprise_only(&line);
3468 switch (cfg_find_tok(line.val_tok_1, NAMESPACE_STORAGE_DEVICE_COMPRESSION_OPTS, NUM_NAMESPACE_STORAGE_DEVICE_COMPRESSION_OPTS)) {
3469 case CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_NONE:
3470 ns->storage_compression = AS_COMPRESSION_NONE;
3471 break;
3472 case CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_LZ4:
3473 ns->storage_compression = AS_COMPRESSION_LZ4;
3474 break;
3475 case CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_SNAPPY:
3476 ns->storage_compression = AS_COMPRESSION_SNAPPY;
3477 break;
3478 case CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_ZSTD:
3479 ns->storage_compression = AS_COMPRESSION_ZSTD;
3480 break;
3481 case CASE_NOT_FOUND:
3482 default:
3483 cfg_unknown_val_tok_1(&line);
3484 break;
3485 }
3486 break;
3487 case CASE_NAMESPACE_STORAGE_DEVICE_COMPRESSION_LEVEL:
3488 cfg_enterprise_only(&line);
3489 ns->storage_compression_level = cfg_u32(&line, 1, 9);
3490 break;
3491 case CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_LWM_PCT:
3492 ns->storage_defrag_lwm_pct = cfg_u32_no_checks(&line);
3493 break;
3494 case CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_QUEUE_MIN:
3495 ns->storage_defrag_queue_min = cfg_u32_no_checks(&line);
3496 break;
3497 case CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_SLEEP:
3498 ns->storage_defrag_sleep = cfg_u32_no_checks(&line);
3499 break;
3500 case CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_STARTUP_MINIMUM:
3501 ns->storage_defrag_startup_minimum = cfg_int(&line, 1, 99);
3502 break;
3503 case CASE_NAMESPACE_STORAGE_DEVICE_DIRECT_FILES:
3504 ns->storage_direct_files = cfg_bool(&line);
3505 break;
3506 case CASE_NAMESPACE_STORAGE_DEVICE_DISABLE_ODSYNC:
3507 ns->storage_disable_odsync = cfg_bool(&line);
3508 break;
3509 case CASE_NAMESPACE_STORAGE_DEVICE_ENABLE_BENCHMARKS_STORAGE:
3510 ns->storage_benchmarks_enabled = true;
3511 break;
3512 case CASE_NAMESPACE_STORAGE_DEVICE_ENCRYPTION:
3513 cfg_enterprise_only(&line);
3514 switch (cfg_find_tok(line.val_tok_1, NAMESPACE_STORAGE_DEVICE_ENCRYPTION_OPTS, NUM_NAMESPACE_STORAGE_DEVICE_ENCRYPTION_OPTS)) {
3515 case CASE_NAMESPACE_STORAGE_DEVICE_ENCRYPTION_AES_128:
3516 ns->storage_encryption = AS_ENCRYPTION_AES_128;
3517 break;
3518 case CASE_NAMESPACE_STORAGE_DEVICE_ENCRYPTION_AES_256:
3519 ns->storage_encryption = AS_ENCRYPTION_AES_256;
3520 break;
3521 case CASE_NOT_FOUND:
3522 default:
3523 cfg_unknown_val_tok_1(&line);
3524 break;
3525 }
3526 break;
3527 case CASE_NAMESPACE_STORAGE_DEVICE_ENCRYPTION_KEY_FILE:
3528 cfg_enterprise_only(&line);
3529 ns->storage_encryption_key_file = cfg_strdup(&line, true);
3530 break;
3531 case CASE_NAMESPACE_STORAGE_DEVICE_FLUSH_MAX_MS:
3532 ns->storage_flush_max_us = cfg_u64_no_checks(&line) * 1000;
3533 break;
3534 case CASE_NAMESPACE_STORAGE_DEVICE_MAX_WRITE_CACHE:
3535 ns->storage_max_write_cache = cfg_u64_no_checks(&line);
3536 break;
3537 case CASE_NAMESPACE_STORAGE_DEVICE_MIN_AVAIL_PCT:
3538 ns->storage_min_avail_pct = cfg_u32(&line, 0, 100);
3539 break;
3540 case CASE_NAMESPACE_STORAGE_DEVICE_POST_WRITE_QUEUE:
3541 ns->storage_post_write_queue = cfg_u32(&line, 0, 8 * 1024);
3542 break;
3543 case CASE_NAMESPACE_STORAGE_DEVICE_READ_PAGE_CACHE:
3544 ns->storage_read_page_cache = cfg_bool(&line);
3545 break;
3546 case CASE_NAMESPACE_STORAGE_DEVICE_SERIALIZE_TOMB_RAIDER:
3547 cfg_enterprise_only(&line);
3548 ns->storage_serialize_tomb_raider = cfg_bool(&line);
3549 break;
3550 case CASE_NAMESPACE_STORAGE_DEVICE_TOMB_RAIDER_SLEEP:
3551 cfg_enterprise_only(&line);
3552 ns->storage_tomb_raider_sleep = cfg_u32_no_checks(&line);
3553 break;
3554 case CASE_NAMESPACE_STORAGE_DEVICE_DISABLE_ODIRECT:
3555 cfg_obsolete(&line, "please use 'read-page-cache' instead");
3556 break;
3557 case CASE_NAMESPACE_STORAGE_DEVICE_FSYNC_MAX_SEC:
3558 cfg_obsolete(&line, "please use 'flush-files' instead");
3559 break;
3560 case CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_MAX_BLOCKS:
3561 case CASE_NAMESPACE_STORAGE_DEVICE_DEFRAG_PERIOD:
3562 case CASE_NAMESPACE_STORAGE_DEVICE_ENABLE_OSYNC:
3563 case CASE_NAMESPACE_STORAGE_DEVICE_LOAD_AT_STARTUP:
3564 case CASE_NAMESPACE_STORAGE_DEVICE_PERSIST:
3565 case CASE_NAMESPACE_STORAGE_DEVICE_READONLY:
3566 case CASE_NAMESPACE_STORAGE_DEVICE_SIGNATURE:
3567 case CASE_NAMESPACE_STORAGE_DEVICE_WRITE_SMOOTHING_PERIOD:
3568 case CASE_NAMESPACE_STORAGE_DEVICE_WRITE_THREADS:
3569 cfg_deprecated_name_tok(&line);
3570 break;
3571 case CASE_CONTEXT_END:
3572 if (ns->n_storage_devices == 0 && ns->n_storage_files == 0) {
3573 cf_crash_nostack(AS_CFG, "{%s} has no devices or files", ns->name);
3574 }
3575 if (ns->n_storage_files != 0 && ns->storage_filesize == 0) {
3576 cf_crash_nostack(AS_CFG, "{%s} must configure 'filesize' if using storage files", ns->name);
3577 }
3578 if (ns->storage_commit_to_device && ns->storage_disable_odsync) {
3579 cf_crash_nostack(AS_CFG, "{%s} can't configure both 'commit-to-device' and 'disable-odsync'", ns->name);
3580 }
3581 if (ns->storage_compression_level != 0 && ns->storage_compression != AS_COMPRESSION_ZSTD) {
3582 cf_crash_nostack(AS_CFG, "{%s} 'compression-level' is only relevant for 'compression zstd'", ns->name);
3583 }
3584 cfg_end_context(&state);
3585 break;
3586 case CASE_NOT_FOUND:
3587 default:
3588 cfg_unknown_name_tok(&line);
3589 break;
3590 }
3591 break;
3592
3593 //----------------------------------------
3594 // Parse namespace::set context items.
3595 //
3596 case NAMESPACE_SET:
3597 switch (cfg_find_tok(line.name_tok, NAMESPACE_SET_OPTS, NUM_NAMESPACE_SET_OPTS)) {
3598 case CASE_NAMESPACE_SET_DISABLE_EVICTION:
3599 DISABLE_SET_EVICTION(p_set, cfg_bool(&line));
3600 break;
3601 case CASE_NAMESPACE_SET_ENABLE_XDR:
3602 switch (cfg_find_tok(line.val_tok_1, NAMESPACE_SET_ENABLE_XDR_OPTS, NUM_NAMESPACE_SET_ENABLE_XDR_OPTS)) {
3603 case CASE_NAMESPACE_SET_ENABLE_XDR_USE_DEFAULT:
3604 p_set->enable_xdr = AS_SET_ENABLE_XDR_DEFAULT;
3605 break;
3606 case CASE_NAMESPACE_SET_ENABLE_XDR_FALSE:
3607 p_set->enable_xdr = AS_SET_ENABLE_XDR_FALSE;
3608 break;
3609 case CASE_NAMESPACE_SET_ENABLE_XDR_TRUE:
3610 p_set->enable_xdr = AS_SET_ENABLE_XDR_TRUE;
3611 break;
3612 case CASE_NOT_FOUND:
3613 default:
3614 cfg_unknown_val_tok_1(&line);
3615 break;
3616 }
3617 break;
3618 case CASE_NAMESPACE_SET_STOP_WRITES_COUNT:
3619 p_set->stop_writes_count = cfg_u64_no_checks(&line);
3620 break;
3621 case CASE_NAMESPACE_SET_EVICT_HWM_COUNT:
3622 case CASE_NAMESPACE_SET_EVICT_HWM_PCT:
3623 case CASE_NAMESPACE_SET_STOP_WRITE_COUNT:
3624 case CASE_NAMESPACE_SET_STOP_WRITE_PCT:
3625 cfg_deprecated_name_tok(&line);
3626 break;
3627 case CASE_CONTEXT_END:
3628 cfg_end_context(&state);
3629 break;
3630 case CASE_NOT_FOUND:
3631 default:
3632 cfg_unknown_name_tok(&line);
3633 break;
3634 }
3635 break;
3636
3637 //----------------------------------------
3638 // Parse namespace::si context items.
3639 //
3640 case NAMESPACE_SI:
3641 switch (cfg_find_tok(line.name_tok, NAMESPACE_SI_OPTS, NUM_NAMESPACE_SI_OPTS)) {
3642 case CASE_NAMESPACE_SI_GC_PERIOD:
3643 cfg_deprecated_name_tok(&line);
3644 break;
3645 case CASE_NAMESPACE_SI_GC_MAX_UNITS:
3646 cfg_deprecated_name_tok(&line);
3647 break;
3648 case CASE_NAMESPACE_SI_HISTOGRAM:
3649 cfg_deprecated_name_tok(&line);
3650 break;
3651 case CASE_NAMESPACE_SI_IGNORE_NOT_SYNC:
3652 cfg_deprecated_name_tok(&line);
3653 break;
3654 case CASE_CONTEXT_END:
3655 cfg_end_context(&state);
3656 break;
3657 case CASE_NOT_FOUND:
3658 default:
3659 cfg_unknown_val_tok_1(&line);
3660 break;
3661 }
3662 break;
3663
3664 //----------------------------------------
3665 // Parse namespace::sindex context items.
3666 //
3667 case NAMESPACE_SINDEX:
3668 switch (cfg_find_tok(line.name_tok, NAMESPACE_SINDEX_OPTS, NUM_NAMESPACE_SINDEX_OPTS)) {
3669 case CASE_NAMESPACE_SINDEX_NUM_PARTITIONS:
3670 ns->sindex_num_partitions = cfg_u32(&line, MIN_PARTITIONS_PER_INDEX, MAX_PARTITIONS_PER_INDEX);
3671 break;
3672 case CASE_CONTEXT_END:
3673 cfg_end_context(&state);
3674 break;
3675 case CASE_NOT_FOUND:
3676 default:
3677 cfg_unknown_name_tok(&line);
3678 break;
3679 }
3680 break;
3681
3682 //----------------------------------------
3683 // Parse namespace::2dsphere-within context items.
3684 //
3685 case NAMESPACE_GEO2DSPHERE_WITHIN:
3686 switch (cfg_find_tok(line.name_tok, NAMESPACE_GEO2DSPHERE_WITHIN_OPTS, NUM_NAMESPACE_GEO2DSPHERE_WITHIN_OPTS)) {
3687 case CASE_NAMESPACE_GEO2DSPHERE_WITHIN_STRICT:
3688 ns->geo2dsphere_within_strict = cfg_bool(&line);
3689 break;
3690 case CASE_NAMESPACE_GEO2DSPHERE_WITHIN_MIN_LEVEL:
3691 ns->geo2dsphere_within_min_level = cfg_u16(&line, 0, MAX_REGION_LEVELS);
3692 break;
3693 case CASE_NAMESPACE_GEO2DSPHERE_WITHIN_MAX_LEVEL:
3694 ns->geo2dsphere_within_max_level = cfg_u16(&line, 0, MAX_REGION_LEVELS);
3695 break;
3696 case CASE_NAMESPACE_GEO2DSPHERE_WITHIN_MAX_CELLS:
3697 ns->geo2dsphere_within_max_cells = cfg_u16(&line, 1, MAX_REGION_CELLS);
3698 break;
3699 case CASE_NAMESPACE_GEO2DSPHERE_WITHIN_LEVEL_MOD:
3700 ns->geo2dsphere_within_level_mod = cfg_u16(&line, 1, 3);
3701 break;
3702 case CASE_NAMESPACE_GEO2DSPHERE_WITHIN_EARTH_RADIUS_METERS:
3703 ns->geo2dsphere_within_earth_radius_meters = cfg_u32_no_checks(&line);
3704 break;
3705 case CASE_CONTEXT_END:
3706 cfg_end_context(&state);
3707 break;
3708 case CASE_NOT_FOUND:
3709 default:
3710 cfg_unknown_name_tok(&line);
3711 break;
3712 }
3713 break;
3714
3715 //==================================================
3716 // Parse mod-lua context items.
3717 //
3718 case MOD_LUA:
3719 switch (cfg_find_tok(line.name_tok, MOD_LUA_OPTS, NUM_MOD_LUA_OPTS)) {
3720 case CASE_MOD_LUA_CACHE_ENABLED:
3721 c->mod_lua.cache_enabled = cfg_bool(&line);
3722 break;
3723 case CASE_MOD_LUA_USER_PATH:
3724 cfg_strcpy(&line, c->mod_lua.user_path, sizeof(c->mod_lua.user_path));
3725 break;
3726 case CASE_MOD_LUA_SYSTEM_PATH:
3727 cfg_deprecated_name_tok(&line);
3728 break;
3729 case CASE_CONTEXT_END:
3730 cfg_end_context(&state);
3731 break;
3732 case CASE_NOT_FOUND:
3733 default:
3734 cfg_unknown_name_tok(&line);
3735 break;
3736 }
3737 break;
3738
3739 //==================================================
3740 // Parse security context items.
3741 //
3742 case SECURITY:
3743 switch (cfg_find_tok(line.name_tok, SECURITY_OPTS, NUM_SECURITY_OPTS)) {
3744 case CASE_SECURITY_ENABLE_LDAP:
3745 c->sec_cfg.ldap_enabled = cfg_bool(&line);
3746 break;
3747 case CASE_SECURITY_ENABLE_SECURITY:
3748 c->sec_cfg.security_enabled = cfg_bool(&line);
3749 break;
3750 case CASE_SECURITY_LDAP_LOGIN_THREADS:
3751 c->sec_cfg.n_ldap_login_threads = cfg_u32(&line, 1, 64);
3752 break;
3753 case CASE_SECURITY_PRIVILEGE_REFRESH_PERIOD:
3754 c->sec_cfg.privilege_refresh_period = cfg_u32(&line, PRIVILEGE_REFRESH_PERIOD_MIN, PRIVILEGE_REFRESH_PERIOD_MAX);
3755 break;
3756 case CASE_SECURITY_LDAP_BEGIN:
3757 cfg_begin_context(&state, SECURITY_LDAP);
3758 break;
3759 case CASE_SECURITY_LOG_BEGIN:
3760 cfg_begin_context(&state, SECURITY_LOG);
3761 break;
3762 case CASE_SECURITY_SYSLOG_BEGIN:
3763 cfg_begin_context(&state, SECURITY_SYSLOG);
3764 break;
3765 case CASE_CONTEXT_END:
3766 cfg_end_context(&state);
3767 break;
3768 case CASE_NOT_FOUND:
3769 default:
3770 cfg_unknown_name_tok(&line);
3771 break;
3772 }
3773 break;
3774
3775 //----------------------------------------
3776 // Parse security::ldap context items.
3777 //
3778 case SECURITY_LDAP:
3779 switch (cfg_find_tok(line.name_tok, SECURITY_LDAP_OPTS, NUM_SECURITY_LDAP_OPTS)) {
3780 case CASE_SECURITY_LDAP_DISABLE_TLS:
3781 c->sec_cfg.ldap_tls_disabled = cfg_bool(&line);
3782 break;
3783 case CASE_SECURITY_LDAP_POLLING_PERIOD:
3784 c->sec_cfg.ldap_polling_period = cfg_u32(&line, LDAP_POLLING_PERIOD_MIN, LDAP_POLLING_PERIOD_MAX);
3785 break;
3786 case CASE_SECURITY_LDAP_QUERY_BASE_DN:
3787 c->sec_cfg.ldap_query_base_dn = cfg_strdup(&line, true);
3788 break;
3789 case CASE_SECURITY_LDAP_QUERY_USER_DN:
3790 c->sec_cfg.ldap_query_user_dn = cfg_strdup(&line, true);
3791 break;
3792 case CASE_SECURITY_LDAP_QUERY_USER_PASSWORD_FILE:
3793 c->sec_cfg.ldap_query_user_password_file = cfg_strdup(&line, true);
3794 break;
3795 case CASE_SECURITY_LDAP_ROLE_QUERY_BASE_DN:
3796 c->sec_cfg.ldap_role_query_base_dn = cfg_strdup(&line, true);
3797 break;
3798 case CASE_SECURITY_LDAP_ROLE_QUERY_PATTERN:
3799 cfg_add_ldap_role_query_pattern(cfg_strdup(&line, true));
3800 break;
3801 case CASE_SECURITY_LDAP_ROLE_QUERY_SEARCH_OU:
3802 c->sec_cfg.ldap_role_query_search_ou = cfg_bool(&line);
3803 break;
3804 case CASE_SECURITY_LDAP_SERVER:
3805 c->sec_cfg.ldap_server = cfg_strdup(&line, true);
3806 break;
3807 case CASE_SECURITY_LDAP_SESSION_TTL:
3808 c->sec_cfg.ldap_session_ttl = cfg_u32(&line, LDAP_SESSION_TTL_MIN, LDAP_SESSION_TTL_MAX);
3809 break;
3810 case CASE_SECURITY_LDAP_TLS_CA_FILE:
3811 c->sec_cfg.ldap_tls_ca_file = cfg_strdup(&line, true);
3812 break;
3813 case CASE_SECURITY_LDAP_TOKEN_HASH_METHOD:
3814 switch (cfg_find_tok(line.val_tok_1, SECURITY_LDAP_TOKEN_HASH_METHOD_OPTS, NUM_SECURITY_LDAP_TOKEN_HASH_METHOD_OPTS)) {
3815 case CASE_SECURITY_LDAP_TOKEN_HASH_METHOD_SHA_256:
3816 c->sec_cfg.ldap_token_hash_method = AS_LDAP_EVP_SHA_256;
3817 break;
3818 case CASE_SECURITY_LDAP_TOKEN_HASH_METHOD_SHA_512:
3819 c->sec_cfg.ldap_token_hash_method = AS_LDAP_EVP_SHA_512;
3820 break;
3821 case CASE_NOT_FOUND:
3822 default:
3823 cfg_unknown_val_tok_1(&line);
3824 break;
3825 }
3826 break;
3827 case CASE_SECURITY_LDAP_USER_DN_PATTERN:
3828 c->sec_cfg.ldap_user_dn_pattern = cfg_strdup(&line, true);
3829 break;
3830 case CASE_SECURITY_LDAP_USER_QUERY_PATTERN:
3831 c->sec_cfg.ldap_user_query_pattern = cfg_strdup(&line, true);
3832 break;
3833 case CASE_CONTEXT_END:
3834 cfg_end_context(&state);
3835 break;
3836 case CASE_NOT_FOUND:
3837 default:
3838 cfg_unknown_name_tok(&line);
3839 break;
3840 }
3841 break;
3842
3843 //----------------------------------------
3844 // Parse security::log context items.
3845 //
3846 case SECURITY_LOG:
3847 switch (cfg_find_tok(line.name_tok, SECURITY_LOG_OPTS, NUM_SECURITY_LOG_OPTS)) {
3848 case CASE_SECURITY_LOG_REPORT_AUTHENTICATION:
3849 c->sec_cfg.report.authentication |= cfg_bool(&line) ? AS_SEC_SINK_LOG : 0;
3850 break;
3851 case CASE_SECURITY_LOG_REPORT_DATA_OP:
3852 as_security_config_log_scope(AS_SEC_SINK_LOG, line.val_tok_1, line.val_tok_2);
3853 break;
3854 case CASE_SECURITY_LOG_REPORT_SYS_ADMIN:
3855 c->sec_cfg.report.sys_admin |= cfg_bool(&line) ? AS_SEC_SINK_LOG : 0;
3856 break;
3857 case CASE_SECURITY_LOG_REPORT_USER_ADMIN:
3858 c->sec_cfg.report.user_admin |= cfg_bool(&line) ? AS_SEC_SINK_LOG : 0;
3859 break;
3860 case CASE_SECURITY_LOG_REPORT_VIOLATION:
3861 c->sec_cfg.report.violation |= cfg_bool(&line) ? AS_SEC_SINK_LOG : 0;
3862 break;
3863 case CASE_CONTEXT_END:
3864 cfg_end_context(&state);
3865 break;
3866 case CASE_NOT_FOUND:
3867 default:
3868 cfg_unknown_name_tok(&line);
3869 break;
3870 }
3871 break;
3872
3873 //----------------------------------------
3874 // Parse security::syslog context items.
3875 //
3876 case SECURITY_SYSLOG:
3877 switch (cfg_find_tok(line.name_tok, SECURITY_SYSLOG_OPTS, NUM_SECURITY_SYSLOG_OPTS)) {
3878 case CASE_SECURITY_SYSLOG_LOCAL:
3879 c->sec_cfg.syslog_local = (as_sec_syslog_local)cfg_int(&line, AS_SYSLOG_MIN, AS_SYSLOG_MAX);
3880 break;
3881 case CASE_SECURITY_SYSLOG_REPORT_AUTHENTICATION:
3882 c->sec_cfg.report.authentication |= cfg_bool(&line) ? AS_SEC_SINK_SYSLOG : 0;
3883 break;
3884 case CASE_SECURITY_SYSLOG_REPORT_DATA_OP:
3885 as_security_config_log_scope(AS_SEC_SINK_SYSLOG, line.val_tok_1, line.val_tok_2);
3886 break;
3887 case CASE_SECURITY_SYSLOG_REPORT_SYS_ADMIN:
3888 c->sec_cfg.report.sys_admin |= cfg_bool(&line) ? AS_SEC_SINK_SYSLOG : 0;
3889 break;
3890 case CASE_SECURITY_SYSLOG_REPORT_USER_ADMIN:
3891 c->sec_cfg.report.user_admin |= cfg_bool(&line) ? AS_SEC_SINK_SYSLOG : 0;
3892 break;
3893 case CASE_SECURITY_SYSLOG_REPORT_VIOLATION:
3894 c->sec_cfg.report.violation |= cfg_bool(&line) ? AS_SEC_SINK_SYSLOG : 0;
3895 break;
3896 case CASE_CONTEXT_END:
3897 cfg_end_context(&state);
3898 break;
3899 case CASE_NOT_FOUND:
3900 default:
3901 cfg_unknown_name_tok(&line);
3902 break;
3903 }
3904 break;
3905
3906 //==================================================
3907 // Parse xdr context items.
3908 //
3909 case XDR:
3910 switch (cfg_find_tok(line.name_tok, XDR_OPTS, NUM_XDR_OPTS)) {
3911 case CASE_CONTEXT_BEGIN:
3912 // Allow open brace on its own line to begin this context.
3913 break;
3914 case CASE_XDR_ENABLE_XDR:
3915 g_xcfg.xdr_global_enabled = cfg_bool(&line);
3916 break;
3917 case CASE_XDR_ENABLE_CHANGE_NOTIFICATION:
3918 g_xcfg.xdr_enable_change_notification = cfg_bool(&line);
3919 break;
3920 case CASE_XDR_DIGESTLOG_PATH:
3921 g_xcfg.xdr_digestlog_path = cfg_strdup(&line, true);
3922 g_xcfg.xdr_digestlog_file_size = cfg_u64_val2_no_checks(&line);
3923 break;
3924 case CASE_XDR_DATACENTER_BEGIN:
3925 cur_dest_cfg = xdr_cfg_add_datacenter(cfg_strdup(&line, true));
3926 cfg_begin_context(&state, XDR_DATACENTER);
3927 break;
3928 case CASE_XDR_CLIENT_THREADS:
3929 g_xcfg.xdr_client_threads = cfg_u32(&line, 1, XDR_MAX_CLIENT_THREADS);
3930 break;
3931 case CASE_XDR_COMPRESSION_THRESHOLD:
3932 g_xcfg.xdr_compression_threshold = cfg_u32_no_checks(&line);
3933 break;
3934 case CASE_XDR_DELETE_SHIPPING_ENABLED:
3935 g_xcfg.xdr_delete_shipping_enabled = cfg_bool(&line);
3936 break;
3937 case CASE_XDR_DIGESTLOG_IOWAIT_MS:
3938 g_xcfg.xdr_digestlog_iowait_ms = cfg_u32_no_checks(&line);
3939 break;
3940 case CASE_XDR_FORWARD_XDR_WRITES:
3941 g_xcfg.xdr_forward_xdrwrites = cfg_bool(&line);
3942 break;
3943 case CASE_XDR_HOTKEY_TIME_MS:
3944 g_xcfg.xdr_hotkey_time_ms = cfg_u32_no_checks(&line);
3945 break;
3946 case CASE_XDR_INFO_PORT:
3947 g_xcfg.xdr_info_port = cfg_port(&line);
3948 break;
3949 case CASE_XDR_INFO_TIMEOUT:
3950 g_xcfg.xdr_info_request_timeout_ms = cfg_u32_no_checks(&line);
3951 break;
3952 case CASE_XDR_MAX_SHIP_BANDWIDTH:
3953 g_xcfg.xdr_max_ship_bandwidth = cfg_u32_no_checks(&line);
3954 break;
3955 case CASE_XDR_MAX_SHIP_THROUGHPUT:
3956 g_xcfg.xdr_max_ship_throughput = cfg_u32_no_checks(&line);
3957 break;
3958 case CASE_XDR_MIN_DIGESTLOG_FREE_PCT:
3959 g_xcfg.xdr_min_dlog_free_pct = cfg_u32(&line, 0, 100);
3960 break;
3961 case CASE_XDR_NSUP_DELETES_ENABLED:
3962 g_xcfg.xdr_nsup_deletes_enabled = cfg_bool(&line);
3963 break;
3964 case CASE_XDR_READ_THREADS:
3965 g_xcfg.xdr_read_threads = cfg_u32_no_checks(&line);
3966 break;
3967 case CASE_XDR_SHIP_BINS:
3968 g_xcfg.xdr_ship_bins = cfg_bool(&line);
3969 break;
3970 case CASE_XDR_SHIP_DELAY:
3971 g_xcfg.xdr_internal_shipping_delay = cfg_u32_no_checks(&line);
3972 break;
3973 case CASE_XDR_SHIPPING_ENABLED:
3974 g_xcfg.xdr_shipping_enabled = cfg_bool(&line);
3975 break;
3976 case CASE_XDR_WRITE_TIMEOUT:
3977 g_xcfg.xdr_write_timeout = cfg_u32_no_checks(&line);
3978 break;
3979 case CASE_CONTEXT_END:
3980 cfg_end_context(&state);
3981 break;
3982 case CASE_NOT_FOUND:
3983 default:
3984 cfg_unknown_name_tok(&line);
3985 break;
3986 }
3987 break;
3988
3989 //----------------------------------------
3990 // Parse xdr::datacenter context items.
3991 //
3992 case XDR_DATACENTER:
3993 switch (cfg_find_tok(line.name_tok, XDR_DATACENTER_OPTS, NUM_XDR_DATACENTER_OPTS)) {
3994 case CASE_CONTEXT_BEGIN:
3995 // Allow open brace on its own line to begin this context.
3996 break;
3997 case CASE_XDR_DATACENTER_DC_TYPE:
3998 cur_dest_cfg->dc_type = cfg_strdup_one_of(&line, XDR_DESTINATION_TYPES, NUM_XDR_DESTINATION_TYPES);
3999 break;
4000 case CASE_XDR_DATACENTER_DC_NODE_ADDRESS_PORT:
4001 xdr_cfg_add_node_addr_port(cur_dest_cfg, cfg_strdup(&line, true), cfg_port_val2(&line));
4002 break;
4003 case CASE_XDR_DATACENTER_AUTH_MODE:
4004 switch (cfg_find_tok(line.val_tok_1, XDR_DATACENTER_AUTH_MODE_OPTS, NUM_XDR_DATACENTER_AUTH_MODE_OPTS)) {
4005 case CASE_XDR_DATACENTER_AUTH_MODE_INTERNAL:
4006 cur_dest_cfg->aero.auth_mode = XDR_AUTH_MODE_INTERNAL;
4007 break;
4008 case CASE_XDR_DATACENTER_AUTH_MODE_EXTERNAL:
4009 cur_dest_cfg->aero.auth_mode = XDR_AUTH_MODE_EXTERNAL;
4010 break;
4011 case CASE_XDR_DATACENTER_AUTH_MODE_EXTERNAL_INSECURE:
4012 cur_dest_cfg->aero.auth_mode = XDR_AUTH_MODE_EXTERNAL_INSECURE;
4013 break;
4014 case CASE_NOT_FOUND:
4015 default:
4016 cfg_unknown_val_tok_1(&line);
4017 break;
4018 }
4019 break;
4020 case CASE_XDR_DATACENTER_DC_CONNECTIONS:
4021 cur_dest_cfg->aero.dc_connections = cfg_u32_no_checks(&line);
4022 break;
4023 case CASE_XDR_DATACENTER_DC_CONNECTIONS_IDLE_MS:
4024 cur_dest_cfg->aero.dc_connections_idle_ms = cfg_u32_no_checks(&line);
4025 break;
4026 case CASE_XDR_DATACENTER_DC_INT_EXT_IPMAP:
4027 xdr_cfg_add_int_ext_mapping(&cur_dest_cfg->aero, cfg_strdup(&line, true), cfg_strdup_val2(&line, true));
4028 break;
4029 case CASE_XDR_DATACENTER_DC_SECURITY_CONFIG_FILE:
4030 cur_dest_cfg->dc_security_cfg.sec_config_file = cfg_strdup(&line, true);
4031 break;
4032 case CASE_XDR_DATACENTER_DC_SHIP_BINS:
4033 cur_dest_cfg->dc_ship_bins = cfg_bool(&line);
4034 break;
4035 case CASE_XDR_DATACENTER_DC_USE_ALTERNATE_SERVICES:
4036 cur_dest_cfg->aero.dc_use_alternate_services = cfg_bool(&line);
4037 break;
4038 case CASE_XDR_DATACENTER_HTTP_URL:
4039 xdr_cfg_add_http_url(cur_dest_cfg, cfg_strdup(&line, true));
4040 break;
4041 case CASE_XDR_DATACENTER_HTTP_VERSION:
4042 cur_dest_cfg->http.version_str = cfg_strdup_one_of(&line, XDR_HTTP_VERSION_TYPES, NUM_XDR_HTTP_VERSION_TYPES);
4043 break;
4044 case CASE_XDR_DATACENTER_TLS_NAME:
4045 cur_dest_cfg->dc_tls_spec_name = cfg_strdup_no_checks(&line);
4046 break;
4047 case CASE_XDR_DATACENTER_TLS_NODE:
4048 xdr_cfg_add_tls_node(cur_dest_cfg, cfg_strdup(&line, true), cfg_strdup_val2(&line, true), cfg_port_val3(&line));
4049 break;
4050 case CASE_CONTEXT_END:
4051 g_dc_count++;
4052 cfg_end_context(&state);
4053 break;
4054 case CASE_NOT_FOUND:
4055 default:
4056 cfg_unknown_name_tok(&line);
4057 break;
4058 }
4059 break;
4060
4061 //==================================================
4062 // Parser state is corrupt.
4063 //
4064 default:
4065 cf_crash_nostack(AS_CFG, "line %d :: invalid parser top-level state %d", line_num, state.current);
4066 break;
4067 }
4068 }
4069
4070 cfg_parser_done(&state);
4071
4072 fclose(FD);
4073
4074 return &g_config;
4075}
4076
4077
4078//==========================================================
4079// Public API - configuration-related tasks after parsing.
4080//
4081
4082void
4083as_config_post_process(as_config* c, const char* config_file)
4084{
4085 //--------------------------------------------
4086 // Re-read the configuration file and print it to the logs, line by line.
4087 // This will be the first thing to appear in the log file(s).
4088 //
4089
4090 FILE* FD;
4091
4092 if (NULL == (FD = fopen(config_file, "r"))) {
4093 cf_crash_nostack(AS_CFG, "couldn't re-open configuration file %s: %s", config_file, cf_strerror(errno));
4094 }
4095
4096 char iobuf[256];
4097
4098 while (fgets(iobuf, sizeof(iobuf), FD)) {
4099 char* p = iobuf;
4100 char* p_last = p + (strlen(p) - 1);
4101
4102 if ('\n' == *p_last) {
4103 *p_last-- = '\0';
4104 }
4105
4106 if (p_last >= p && '\r' == *p_last) {
4107 *p_last = '\0';
4108 }
4109
4110 cf_info(AS_CFG, "%s", p);
4111 }
4112
4113 fclose(FD);
4114
4115 //
4116 // Done echoing configuration file to log.
4117 //--------------------------------------------
4118
4119 if (g_config.n_namespaces == 0) {
4120 cf_crash_nostack(AS_CFG, "must configure at least one namespace");
4121 }
4122
4123 cf_alloc_set_debug(c->debug_allocations, c->indent_allocations);
4124
4125 // Configuration checks and special defaults that differ between CE and EE.
4126 cfg_post_process();
4127
4128 as_security_config_check();
4129
4130 // Check the configured file descriptor limit against the system limit.
4131 struct rlimit fd_limit;
4132
4133 getrlimit(RLIMIT_NOFILE, &fd_limit);
4134
4135 if ((rlim_t)c->n_proto_fd_max > fd_limit.rlim_cur) {
4136 cf_crash_nostack(AS_CFG, "%lu system file descriptors not enough, config specified %u", fd_limit.rlim_cur, c->n_proto_fd_max);
4137 }
4138
4139 cf_info(AS_CFG, "system file descriptor limit: %lu, proto-fd-max: %u", fd_limit.rlim_cur, c->n_proto_fd_max);
4140
4141 // Output NUMA topology information.
4142 cf_topo_info();
4143
4144 uint16_t n_cpus = cf_topo_count_cpus();
4145
4146 if (c->auto_pin != CF_TOPO_AUTO_PIN_NONE &&
4147 c->n_service_threads % n_cpus != 0) {
4148 cf_crash_nostack(AS_CFG, "with 'auto-pin', 'service-threads' must be a multiple of the number of CPUs (%hu)", n_cpus);
4149 }
4150
4151 if (c->n_service_threads == 0) {
4152 c->n_service_threads = c->n_namespaces_not_inlined != 0 ?
4153 n_cpus * 5 : n_cpus;
4154 }
4155
4156 // Setup performance metrics histograms.
4157 cfg_create_all_histograms();
4158
4159 // If node-id was not configured, generate one.
4160 if (c->self_node == 0) {
4161 cf_ip_port id_port = c->fabric.bind_port != 0 ? c->fabric.bind_port : c->tls_fabric.bind_port;
4162
4163 if (cf_node_id_get(id_port, c->node_id_interface, &c->self_node) < 0) {
4164 cf_crash_nostack(AS_CFG, "could not get node id");
4165 }
4166 }
4167 else if (c->node_id_interface) {
4168 cf_crash_nostack(AS_CFG, "may not configure both 'node-id' and ''node-id-interface");
4169 }
4170
4171 cf_info(AS_CFG, "node-id %lx", c->self_node);
4172
4173 // Resolve TLS names and read key file passwords for all TLS
4174 // configurations.
4175
4176 for (uint32_t i = 0; i < g_config.n_tls_specs; ++i) {
4177 cf_tls_spec *tspec = &g_config.tls_specs[i];
4178
4179 if (tspec->name == NULL) {
4180 cf_crash_nostack(AS_CFG, "nameless TLS configuration section");
4181 }
4182
4183 tspec->name = cfg_resolve_tls_name(tspec->name, g_config.cluster_name, NULL);
4184
4185 if (tspec->key_file_password == NULL) {
4186 continue;
4187 }
4188
4189 tspec->pw_string = tls_read_password(tspec->key_file_password);
4190 }
4191
4192 // Populate access ports from configuration.
4193
4194 g_access.service.port = g_config.service.std_port != 0 ?
4195 g_config.service.std_port : g_config.service.bind_port;
4196
4197 g_access.alt_service.port = g_config.service.alt_port != 0 ?
4198 g_config.service.alt_port : g_access.service.port;
4199
4200 g_access.tls_service.port = g_config.tls_service.std_port != 0 ?
4201 g_config.tls_service.std_port : g_config.tls_service.bind_port;
4202
4203 g_access.alt_tls_service.port = g_config.tls_service.alt_port != 0 ?
4204 g_config.tls_service.alt_port : g_access.tls_service.port;
4205
4206 // Populate access addresses from configuration.
4207
4208 cfg_serv_spec_std_to_access(&g_config.service, &g_access.service.addrs);
4209 cfg_serv_spec_alt_to_access(&g_config.service, &g_access.alt_service.addrs);
4210 cfg_serv_spec_std_to_access(&g_config.tls_service, &g_access.tls_service.addrs);
4211 cfg_serv_spec_alt_to_access(&g_config.tls_service, &g_access.alt_tls_service.addrs);
4212
4213 // By default, use bind addresses also as access addresses.
4214
4215 if (g_access.service.addrs.n_addrs == 0) {
4216 bind_to_access(&g_config.service, &g_access.service.addrs);
4217 }
4218
4219 if (g_access.tls_service.addrs.n_addrs == 0) {
4220 bind_to_access(&g_config.tls_service, &g_access.tls_service.addrs);
4221 }
4222
4223 // By default, use non-TLS access addresses also for TLS - and vice versa.
4224
4225 default_addrs(&g_access.service.addrs, &g_access.tls_service.addrs);
4226 default_addrs(&g_access.alt_service.addrs, &g_access.alt_tls_service.addrs);
4227
4228 cf_serv_cfg_init(&g_service_bind);
4229
4230 // Client service bind addresses.
4231
4232 if (g_config.service.bind_port != 0) {
4233 cfg_serv_spec_to_bind(&g_config.service, &g_config.tls_service, &g_service_bind,
4234 CF_SOCK_OWNER_SERVICE);
4235 }
4236
4237 // Client TLS service bind addresses.
4238
4239 if (g_config.tls_service.bind_port != 0) {
4240 cfg_serv_spec_to_bind(&g_config.tls_service, &g_config.service, &g_service_bind,
4241 CF_SOCK_OWNER_SERVICE_TLS);
4242
4243 cf_tls_spec* tls_spec = cfg_link_tls("service", &g_config.tls_service.tls_our_name);
4244
4245 uint32_t n_peer_names = g_config.tls_service.n_tls_peer_names;
4246 char **peer_names = g_config.tls_service.tls_peer_names;
4247
4248 bool has_any = false;
4249 bool has_false = false;
4250
4251 for (uint32_t i = 0; i < n_peer_names; ++i) {
4252 has_any = has_any || strcmp(peer_names[i], "any") == 0;
4253 has_false = has_false || strcmp(peer_names[i], "false") == 0;
4254 }
4255
4256 if ((has_any || has_false) && n_peer_names > 1) {
4257 cf_crash_nostack(AS_CFG, "\"any\" and \"false\" are incompatible with other tls-authenticate-client arguments");
4258 }
4259
4260 bool auth_client;
4261
4262 if (has_any || n_peer_names == 0) {
4263 auth_client = true;
4264 n_peer_names = 0;
4265 peer_names = NULL;
4266 }
4267 else if (has_false) {
4268 auth_client = false;
4269 n_peer_names = 0;
4270 peer_names = NULL;
4271 }
4272 else {
4273 auth_client = true;
4274 }
4275
4276 g_service_tls = tls_config_server_context(tls_spec, auth_client, n_peer_names, peer_names);
4277 }
4278
4279 if (g_service_bind.n_cfgs == 0) {
4280 cf_crash_nostack(AS_CFG, "no service ports configured");
4281 }
4282
4283 // Heartbeat service bind addresses.
4284
4285 cf_serv_cfg_init(&g_config.hb_config.bind_cfg);
4286
4287 if (c->hb_serv_spec.bind_port != 0) {
4288 cfg_serv_spec_to_bind(&c->hb_serv_spec, &c->hb_tls_serv_spec, &c->hb_config.bind_cfg,
4289 CF_SOCK_OWNER_HEARTBEAT);
4290 }
4291
4292 // Heartbeat TLS service bind addresses.
4293
4294 if (c->hb_tls_serv_spec.bind_port != 0) {
4295 if (c->hb_config.mode != AS_HB_MODE_MESH) {
4296 cf_crash_nostack(AS_CFG, "multicast heartbeats do not support TLS");
4297 }
4298
4299 cfg_serv_spec_to_bind(&c->hb_tls_serv_spec, &c->hb_serv_spec, &c->hb_config.bind_cfg,
4300 CF_SOCK_OWNER_HEARTBEAT_TLS);
4301
4302 cf_tls_spec* tls_spec = cfg_link_tls("heartbeat", &c->hb_tls_serv_spec.tls_our_name);
4303 c->hb_config.tls = tls_config_intra_context(tls_spec, "heartbeat");
4304 }
4305
4306 if (g_config.hb_config.bind_cfg.n_cfgs == 0) {
4307 cf_crash_nostack(AS_CFG, "no heartbeat ports configured");
4308 }
4309
4310 // Heartbeat multicast groups.
4311
4312 if (c->hb_multicast_groups.n_addrs > 0) {
4313 cfg_mserv_config_from_addrs(&c->hb_multicast_groups, &c->hb_serv_spec.bind,
4314 &g_config.hb_config.multicast_group_cfg, c->hb_serv_spec.bind_port,
4315 CF_SOCK_OWNER_HEARTBEAT, g_config.hb_config.multicast_ttl);
4316 }
4317
4318 // Fabric service bind addresses.
4319
4320 cf_serv_cfg_init(&g_fabric_bind);
4321
4322 if (g_config.fabric.bind_port != 0) {
4323 cfg_serv_spec_to_bind(&g_config.fabric, &g_config.tls_fabric, &g_fabric_bind,
4324 CF_SOCK_OWNER_FABRIC);
4325 }
4326
4327 // Fabric TLS service bind addresses.
4328
4329 if (g_config.tls_fabric.bind_port != 0) {
4330 cfg_serv_spec_to_bind(&g_config.tls_fabric, &g_config.fabric, &g_fabric_bind,
4331 CF_SOCK_OWNER_FABRIC_TLS);
4332
4333 cf_tls_spec* tls_spec = cfg_link_tls("fabric", &g_config.tls_fabric.tls_our_name);
4334 g_fabric_tls = tls_config_intra_context(tls_spec, "fabric");
4335 }
4336
4337 if (g_fabric_bind.n_cfgs == 0) {
4338 cf_crash_nostack(AS_CFG, "no fabric ports configured");
4339 }
4340
4341 // Info service port.
4342
4343 g_info_port = g_config.info.bind_port;
4344
4345 // Info service bind addresses.
4346
4347 cf_serv_cfg_init(&g_info_bind);
4348 cfg_serv_spec_to_bind(&g_config.info, NULL, &g_info_bind, CF_SOCK_OWNER_INFO);
4349
4350 // Validate heartbeat configuration.
4351 as_hb_config_validate();
4352
4353 //--------------------------------------------
4354 // Per-namespace config post-processing.
4355 //
4356
4357 for (int i = 0; i < g_config.n_namespaces; i++) {
4358 as_namespace* ns = g_config.namespaces[i];
4359
4360 client_replica_maps_create(ns);
4361
4362 uint32_t sprigs_offset = sizeof(as_lock_pair) * NUM_LOCK_PAIRS;
4363 uint32_t puddles_offset = 0;
4364
4365 if (ns->xmem_type == CF_XMEM_TYPE_FLASH) {
4366 puddles_offset = sprigs_offset + sizeof(as_sprig) * ns->tree_shared.n_sprigs;
4367 }
4368
4369 // Note - ns->tree_shared.arena is set later when it's allocated.
4370 ns->tree_shared.destructor = (as_index_value_destructor)as_record_destroy;
4371 ns->tree_shared.destructor_udata = (void*)ns;
4372 ns->tree_shared.locks_shift = NUM_SPRIG_BITS - cf_msb(NUM_LOCK_PAIRS);
4373 ns->tree_shared.sprigs_shift = NUM_SPRIG_BITS - cf_msb(ns->tree_shared.n_sprigs);
4374 ns->tree_shared.sprigs_offset = sprigs_offset;
4375 ns->tree_shared.puddles_offset = puddles_offset;
4376
4377 as_storage_cfg_init(ns);
4378
4379 char hist_name[HISTOGRAM_NAME_SIZE];
4380
4381 // One-way activated histograms (may be tracked histograms).
4382
4383 sprintf(hist_name, "{%s}-read", ns->name);
4384 create_and_check_hist_track(&ns->read_hist, hist_name, HIST_MILLISECONDS);
4385
4386 sprintf(hist_name, "{%s}-write", ns->name);
4387 create_and_check_hist_track(&ns->write_hist, hist_name, HIST_MILLISECONDS);
4388
4389 sprintf(hist_name, "{%s}-udf", ns->name);
4390 create_and_check_hist_track(&ns->udf_hist, hist_name, HIST_MILLISECONDS);
4391
4392 sprintf(hist_name, "{%s}-query", ns->name);
4393 create_and_check_hist_track(&ns->query_hist, hist_name, HIST_MILLISECONDS);
4394
4395 sprintf(hist_name, "{%s}-query-rec-count", ns->name);
4396 ns->query_rec_count_hist = histogram_create(hist_name, HIST_COUNT);
4397
4398 sprintf(hist_name, "{%s}-re-repl", ns->name);
4399 ns->re_repl_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4400
4401 // Activate-by-config histograms (can't be tracked histograms).
4402
4403 sprintf(hist_name, "{%s}-proxy", ns->name);
4404 ns->proxy_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4405
4406 sprintf(hist_name, "{%s}-read-start", ns->name);
4407 ns->read_start_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4408 sprintf(hist_name, "{%s}-read-restart", ns->name);
4409 ns->read_restart_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4410 sprintf(hist_name, "{%s}-read-dup-res", ns->name);
4411 ns->read_dup_res_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4412 sprintf(hist_name, "{%s}-read-repl-ping", ns->name);
4413 ns->read_repl_ping_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4414 sprintf(hist_name, "{%s}-read-local", ns->name);
4415 ns->read_local_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4416 sprintf(hist_name, "{%s}-read-response", ns->name);
4417 ns->read_response_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4418
4419 sprintf(hist_name, "{%s}-write-start", ns->name);
4420 ns->write_start_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4421 sprintf(hist_name, "{%s}-write-restart", ns->name);
4422 ns->write_restart_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4423 sprintf(hist_name, "{%s}-write-dup-res", ns->name);
4424 ns->write_dup_res_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4425 sprintf(hist_name, "{%s}-write-master", ns->name);
4426 ns->write_master_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4427 sprintf(hist_name, "{%s}-write-repl-write", ns->name);
4428 ns->write_repl_write_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4429 sprintf(hist_name, "{%s}-write-response", ns->name);
4430 ns->write_response_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4431
4432 sprintf(hist_name, "{%s}-udf-start", ns->name);
4433 ns->udf_start_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4434 sprintf(hist_name, "{%s}-udf-restart", ns->name);
4435 ns->udf_restart_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4436 sprintf(hist_name, "{%s}-udf-dup-res", ns->name);
4437 ns->udf_dup_res_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4438 sprintf(hist_name, "{%s}-udf-master", ns->name);
4439 ns->udf_master_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4440 sprintf(hist_name, "{%s}-udf-repl-write", ns->name);
4441 ns->udf_repl_write_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4442 sprintf(hist_name, "{%s}-udf-response", ns->name);
4443 ns->udf_response_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4444
4445 sprintf(hist_name, "{%s}-batch-sub-start", ns->name);
4446 ns->batch_sub_start_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4447 sprintf(hist_name, "{%s}-batch-sub-restart", ns->name);
4448 ns->batch_sub_restart_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4449 sprintf(hist_name, "{%s}-batch-sub-dup-res", ns->name);
4450 ns->batch_sub_dup_res_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4451 sprintf(hist_name, "{%s}-batch-sub-repl-ping", ns->name);
4452 ns->batch_sub_repl_ping_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4453 sprintf(hist_name, "{%s}-batch-sub-read-local", ns->name);
4454 ns->batch_sub_read_local_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4455 sprintf(hist_name, "{%s}-batch-sub-response", ns->name);
4456 ns->batch_sub_response_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4457
4458 sprintf(hist_name, "{%s}-udf-sub-start", ns->name);
4459 ns->udf_sub_start_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4460 sprintf(hist_name, "{%s}-udf-sub-restart", ns->name);
4461 ns->udf_sub_restart_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4462 sprintf(hist_name, "{%s}-udf-sub-dup-res", ns->name);
4463 ns->udf_sub_dup_res_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4464 sprintf(hist_name, "{%s}-udf-sub-master", ns->name);
4465 ns->udf_sub_master_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4466 sprintf(hist_name, "{%s}-udf-sub-repl-write", ns->name);
4467 ns->udf_sub_repl_write_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4468 sprintf(hist_name, "{%s}-udf-sub-response", ns->name);
4469 ns->udf_sub_response_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4470
4471 sprintf(hist_name, "{%s}-ops-sub-start", ns->name);
4472 ns->ops_sub_start_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4473 sprintf(hist_name, "{%s}-ops-sub-restart", ns->name);
4474 ns->ops_sub_restart_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4475 sprintf(hist_name, "{%s}-ops-sub-dup-res", ns->name);
4476 ns->ops_sub_dup_res_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4477 sprintf(hist_name, "{%s}-ops-sub-master", ns->name);
4478 ns->ops_sub_master_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4479 sprintf(hist_name, "{%s}-ops-sub-repl-write", ns->name);
4480 ns->ops_sub_repl_write_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4481 sprintf(hist_name, "{%s}-ops-sub-response", ns->name);
4482 ns->ops_sub_response_hist = histogram_create(hist_name, HIST_MILLISECONDS);
4483
4484 // 'nsup' histograms.
4485
4486 if (ns->storage_type == AS_STORAGE_ENGINE_SSD) {
4487 sprintf(hist_name, "{%s}-object-size-log2", ns->name);
4488 ns->obj_size_log_hist = histogram_create(hist_name, HIST_SIZE);
4489 sprintf(hist_name, "{%s}-object-size-linear", ns->name);
4490 ns->obj_size_lin_hist = linear_hist_create(hist_name, LINEAR_HIST_SIZE, 0, ns->storage_write_block_size, OBJ_SIZE_HIST_NUM_BUCKETS);
4491 }
4492
4493 sprintf(hist_name, "{%s}-evict", ns->name);
4494 ns->evict_hist = linear_hist_create(hist_name, LINEAR_HIST_SECONDS, 0, 0, ns->evict_hist_buckets);
4495
4496 sprintf(hist_name, "{%s}-ttl", ns->name);
4497 ns->ttl_hist = linear_hist_create(hist_name, LINEAR_HIST_SECONDS, 0, 0, TTL_HIST_NUM_BUCKETS);
4498 }
4499}
4500
4501
4502//==========================================================
4503// Public API - Cluster name.
4504//
4505
4506static cf_mutex g_config_lock = CF_MUTEX_INIT;
4507
4508void
4509as_config_cluster_name_get(char* cluster_name)
4510{
4511 cf_mutex_lock(&g_config_lock);
4512 strcpy(cluster_name, g_config.cluster_name);
4513 cf_mutex_unlock(&g_config_lock);
4514}
4515
4516bool
4517as_config_cluster_name_set(const char* cluster_name)
4518{
4519 if (cluster_name[0] == '\0') {
4520 cf_warning(AS_CFG, "cluster name '%s' is not allowed. Ignoring.", cluster_name);
4521 return false;
4522 }
4523
4524 if (strlen(cluster_name) >= AS_CLUSTER_NAME_SZ) {
4525 cf_warning(AS_CFG, "size of cluster name should not be greater than %d characters. Ignoring cluster name '%s'.",
4526 AS_CLUSTER_NAME_SZ - 1, cluster_name);
4527 return false;
4528 }
4529
4530 cf_mutex_lock(&g_config_lock);
4531
4532 if (strcmp(cluster_name,"null") == 0){
4533 // 'null' is a special value representing an unset cluster-name.
4534 strcpy(g_config.cluster_name, "");
4535 }
4536 else {
4537 strcpy(g_config.cluster_name, cluster_name);
4538 }
4539
4540 cf_mutex_unlock(&g_config_lock);
4541
4542 return true;
4543}
4544
4545bool
4546as_config_cluster_name_matches(const char* cluster_name)
4547{
4548 cf_mutex_lock(&g_config_lock);
4549 bool matches = strcmp(cluster_name, g_config.cluster_name) == 0;
4550 cf_mutex_unlock(&g_config_lock);
4551 return matches;
4552}
4553
4554
4555//==========================================================
4556// Public API - XDR.
4557//
4558
4559bool
4560xdr_read_security_configfile(xdr_security_config* sc)
4561{
4562 FILE* FD;
4563 char iobuf[256];
4564 int line_num = 0;
4565 cfg_parser_state state;
4566
4567 cfg_parser_state_init(&state);
4568
4569 // Initialize the XDR config values to the defaults.
4570 sc->username = NULL;
4571 sc->password = NULL;
4572 iobuf[0] = 0;
4573
4574 // Open the configuration file for reading. Dont crash if it fails as this
4575 // function can be called during runtime (when credentials file change)
4576 if (NULL == (FD = fopen(sc->sec_config_file, "r"))) {
4577 cf_warning(AS_XDR, "Couldn't open configuration file %s: %s",
4578 sc->sec_config_file, cf_strerror(errno));
4579 return false;
4580 }
4581
4582 // Parse the configuration file, line by line.
4583 while (fgets(iobuf, sizeof(iobuf), FD)) {
4584 line_num++;
4585
4586 // First chop the comment off, if there is one.
4587
4588 char* p_comment = strchr(iobuf, '#');
4589
4590 if (p_comment) {
4591 *p_comment = '\0';
4592 }
4593
4594 // Find (and null-terminate) up to three whitespace-delimited tokens in
4595 // the line, a 'name' token and up to two 'value' tokens.
4596
4597 cfg_line line = { line_num, NULL, NULL, NULL, NULL };
4598
4599 line.name_tok = strtok(iobuf, CFG_WHITESPACE);
4600
4601 // If there are no tokens, ignore this line, get the next line.
4602 if (! line.name_tok) {
4603 continue;
4604 }
4605
4606 line.val_tok_1 = strtok(NULL, CFG_WHITESPACE);
4607
4608 if (! line.val_tok_1) {
4609 line.val_tok_1 = ""; // in case it's used where NULL can't be used
4610 }
4611 else {
4612 line.val_tok_2 = strtok(NULL, CFG_WHITESPACE);
4613 }
4614
4615 if (! line.val_tok_2) {
4616 line.val_tok_2 = ""; // in case it's used where NULL can't be used
4617 }
4618 else {
4619 line.val_tok_3 = strtok(NULL, CFG_WHITESPACE);
4620 }
4621
4622 if (! line.val_tok_3) {
4623 line.val_tok_3 = ""; // in case it's used where NULL can't be used
4624 }
4625
4626 // Note that we can't see this output until a logging sink is specified.
4627 cf_detail(AS_CFG, "line %d :: %s %s %s %s", line_num, line.name_tok,
4628 line.val_tok_1, line.val_tok_2, line.val_tok_3);
4629
4630 // Parse the directive.
4631 switch (state.current) {
4632
4633 // Parse top-level items.
4634 case GLOBAL:
4635 switch (cfg_find_tok(line.name_tok, XDR_SEC_GLOBAL_OPTS, NUM_XDR_SEC_GLOBAL_OPTS)) {
4636 case XDR_SEC_CASE_CREDENTIALS_BEGIN:
4637 cfg_begin_context(&state, XDR_SEC_CREDENTIALS);
4638 break;
4639 case CASE_NOT_FOUND:
4640 default:
4641 cfg_unknown_name_tok(&line);
4642 break;
4643 }
4644 break;
4645
4646 // Parse xdr context items.
4647 case XDR_SEC_CREDENTIALS:
4648 switch (cfg_find_tok(line.name_tok, XDR_SEC_CREDENTIALS_OPTS, NUM_XDR_SEC_CREDENTIALS_OPTS)) {
4649 case CASE_CONTEXT_BEGIN:
4650 // Allow open brace on its own line to begin this context.
4651 break;
4652 case XDR_SEC_CASE_CREDENTIALS_USERNAME:
4653 sc->username = cfg_strdup(&line, true);
4654 break;
4655 case XDR_SEC_CASE_CREDENTIALS_PASSWORD:
4656 sc->password = cfg_strdup(&line, true);
4657 break;
4658 case CASE_CONTEXT_END:
4659 cfg_end_context(&state);
4660 break;
4661 case CASE_NOT_FOUND:
4662 default:
4663 cfg_unknown_name_tok(&line);
4664 break;
4665 }
4666 break;
4667
4668 // Parser state is corrupt.
4669 default:
4670 cf_warning(AS_XDR, "line %d :: invalid parser top-level state %d",
4671 line_num, state.current);
4672 break;
4673 }
4674 }
4675
4676 // Close the file.
4677 fclose(FD);
4678 return true;
4679}
4680
4681
4682//==========================================================
4683// Item-specific parsing utilities.
4684//
4685
4686void
4687init_addr_list(cf_addr_list* addrs)
4688{
4689 addrs->n_addrs = 0;
4690 memset(&addrs->addrs, '\0', sizeof(addrs->addrs));
4691}
4692
4693void
4694add_addr(const char* name, cf_addr_list* addrs)
4695{
4696 uint32_t n = addrs->n_addrs;
4697
4698 if (n >= CF_SOCK_CFG_MAX) {
4699 cf_crash_nostack(CF_SOCKET, "Too many addresses: %s", name);
4700 }
4701
4702 addrs->addrs[n] = cf_strdup(name);
4703 ++addrs->n_addrs;
4704}
4705
4706void
4707add_tls_peer_name(const char* name, cf_serv_spec* spec)
4708{
4709 uint32_t n = spec->n_tls_peer_names;
4710
4711 if (n >= CF_SOCK_CFG_MAX) {
4712 cf_crash_nostack(CF_SOCKET, "Too many TLS peer names: %s", name);
4713 }
4714
4715 spec->tls_peer_names[n] = cf_strdup(name);
4716 ++spec->n_tls_peer_names;
4717}
4718
4719void
4720copy_addrs(const cf_addr_list* from, cf_addr_list* to)
4721{
4722 for (uint32_t i = 0; i < from->n_addrs; ++i) {
4723 to->addrs[i] = from->addrs[i];
4724 }
4725
4726 to->n_addrs = from->n_addrs;
4727}
4728
4729void
4730default_addrs(cf_addr_list* one, cf_addr_list* two)
4731{
4732 if (one->n_addrs == 0) {
4733 copy_addrs(two, one);
4734 }
4735
4736 if (two->n_addrs == 0) {
4737 copy_addrs(one, two);
4738 }
4739}
4740
4741void
4742bind_to_access(const cf_serv_spec* from, cf_addr_list* to)
4743{
4744 cf_serv_spec spec;
4745 spec.bind_port = 0;
4746 init_addr_list(&spec.bind);
4747 spec.std_port = 0;
4748 init_addr_list(&spec.std);
4749 spec.alt_port = 0;
4750 init_addr_list(&spec.alt);
4751
4752 for (uint32_t i = 0; i < from->bind.n_addrs; ++i) {
4753 cf_ip_addr resol[CF_SOCK_CFG_MAX];
4754 uint32_t n_resol = CF_SOCK_CFG_MAX;
4755
4756 if (cf_ip_addr_from_string_multi(from->bind.addrs[i], resol, &n_resol) < 0) {
4757 cf_crash_nostack(AS_CFG, "Invalid default access address: %s", from->bind.addrs[i]);
4758 }
4759
4760 bool valid = true;
4761
4762 for (uint32_t k = 0; k < n_resol; ++k) {
4763 if (cf_ip_addr_is_any(&resol[k]) || cf_ip_addr_is_local(&resol[k])) {
4764 cf_debug(AS_CFG, "Skipping invalid default access address: %s",
4765 from->bind.addrs[i]);
4766 valid = false;
4767 break;
4768 }
4769 }
4770
4771 if (valid) {
4772 uint32_t n = spec.std.n_addrs;
4773 spec.std.addrs[n] = from->bind.addrs[i];
4774 ++spec.std.n_addrs;
4775 }
4776 }
4777
4778 cfg_serv_spec_std_to_access(&spec, to);
4779}
4780
4781void
4782cfg_add_addr_bind(const char* name, cf_serv_spec* spec)
4783{
4784 add_addr(name, &spec->bind);
4785}
4786
4787void
4788cfg_add_addr_std(const char* name, cf_serv_spec* spec)
4789{
4790 add_addr(name, &spec->std);
4791}
4792
4793void
4794cfg_add_addr_alt(const char* name, cf_serv_spec* spec)
4795{
4796 add_addr(name, &spec->alt);
4797}
4798
4799void
4800cfg_mserv_config_from_addrs(cf_addr_list* addrs, cf_addr_list* bind_addrs,
4801 cf_mserv_cfg* serv_cfg, cf_ip_port port, cf_sock_owner owner,
4802 uint8_t ttl)
4803{
4804 static cf_addr_list def_addrs = {
4805 .n_addrs = 1, .addrs = { "any" }
4806 };
4807
4808 if (bind_addrs->n_addrs == 0) {
4809 bind_addrs = &def_addrs;
4810 }
4811
4812 for (uint32_t i = 0; i < addrs->n_addrs; ++i) {
4813
4814 cf_ip_addr resol[CF_SOCK_CFG_MAX];
4815 uint32_t n_resol = CF_SOCK_CFG_MAX;
4816
4817 if (cf_ip_addr_from_string_multi(addrs->addrs[i], resol,
4818 &n_resol) < 0) {
4819 cf_crash_nostack(AS_CFG, "Invalid multicast group: %s",
4820 addrs->addrs[i]);
4821 }
4822
4823 for (uint32_t j = 0; j < bind_addrs->n_addrs; j++) {
4824
4825 cf_ip_addr bind_resol[CF_SOCK_CFG_MAX];
4826 uint32_t n_bind_resol = CF_SOCK_CFG_MAX;
4827
4828 if (cf_ip_addr_from_string_multi(bind_addrs->addrs[j],
4829 bind_resol,
4830 &n_bind_resol) < 0) {
4831 cf_crash_nostack(AS_CFG, "Invalid address: %s",
4832 bind_addrs->addrs[j]);
4833 }
4834
4835 for (int32_t k = 0; k < n_resol; ++k) {
4836 for (int32_t l = 0; l < n_bind_resol; ++l) {
4837 if (cf_mserv_cfg_add_combo(serv_cfg, owner, port,
4838 &resol[k], &bind_resol[l], ttl) < 0) {
4839 cf_crash_nostack(AS_CFG, "Too many IP addresses");
4840 }
4841 }
4842 }
4843 }
4844 }
4845}
4846
4847void
4848cfg_serv_spec_to_bind(const cf_serv_spec* spec, const cf_serv_spec* def_spec, cf_serv_cfg* bind,
4849 cf_sock_owner owner)
4850{
4851 static cf_addr_list def_addrs = {
4852 .n_addrs = 1, .addrs = { "any" }
4853 };
4854
4855 cf_sock_cfg cfg;
4856 cf_sock_cfg_init(&cfg, owner);
4857 cfg.port = spec->bind_port;
4858
4859 const cf_addr_list* addrs;
4860
4861 if (spec->bind.n_addrs != 0) {
4862 addrs = &spec->bind;
4863 }
4864 else if (def_spec != NULL && def_spec->bind.n_addrs != 0) {
4865 addrs = &def_spec->bind;
4866 }
4867 else {
4868 addrs = &def_addrs;
4869 }
4870
4871 for (uint32_t i = 0; i < addrs->n_addrs; ++i) {
4872 cf_ip_addr resol[CF_SOCK_CFG_MAX];
4873 uint32_t n_resol = CF_SOCK_CFG_MAX;
4874
4875 if (cf_ip_addr_from_string_multi(addrs->addrs[i], resol, &n_resol) < 0) {
4876 cf_crash_nostack(AS_CFG, "Invalid address: %s", addrs->addrs[i]);
4877 }
4878
4879 for (uint32_t k = 0; k < n_resol; ++k) {
4880 cf_ip_addr_copy(&resol[k], &cfg.addr);
4881
4882 if (cf_serv_cfg_add_sock_cfg(bind, &cfg) < 0) {
4883 cf_crash_nostack(AS_CFG, "Too many IP addresses: %s", addrs->addrs[i]);
4884 }
4885 }
4886 }
4887}
4888
4889static void
4890addrs_to_access(const cf_addr_list* addrs, cf_addr_list* access)
4891{
4892 for (uint32_t i = 0; i < addrs->n_addrs; ++i) {
4893 cf_ip_addr resol[CF_SOCK_CFG_MAX];
4894 uint32_t n_resol = CF_SOCK_CFG_MAX;
4895
4896 if (cf_ip_addr_from_string_multi(addrs->addrs[i], resol, &n_resol) < 0) {
4897 cf_crash_nostack(AS_CFG, "Invalid access address: %s", addrs->addrs[i]);
4898 }
4899
4900 for (uint32_t k = 0; k < n_resol; ++k) {
4901 if (cf_ip_addr_is_any(&resol[k])) {
4902 cf_crash_nostack(AS_CFG, "Invalid access address: %s", addrs->addrs[i]);
4903 }
4904 }
4905
4906 if (cf_ip_addr_is_dns_name(addrs->addrs[i])) {
4907 add_addr(addrs->addrs[i], access);
4908 }
4909 else {
4910 for (uint32_t k = 0; k < n_resol; ++k) {
4911 char tmp[250];
4912 cf_ip_addr_to_string_safe(&resol[k], tmp, sizeof(tmp));
4913 add_addr(tmp, access);
4914 }
4915 }
4916 }
4917}
4918
4919void
4920cfg_serv_spec_std_to_access(const cf_serv_spec* spec, cf_addr_list* access)
4921{
4922 addrs_to_access(&spec->std, access);
4923}
4924
4925void
4926cfg_serv_spec_alt_to_access(const cf_serv_spec* spec, cf_addr_list* access)
4927{
4928 addrs_to_access(&spec->alt, access);
4929}
4930
4931void
4932cfg_add_mesh_seed_addr_port(char* addr, cf_ip_port port, bool tls)
4933{
4934 int32_t i;
4935
4936 for (i = 0; i < AS_CLUSTER_SZ; i++) {
4937 if (g_config.hb_config.mesh_seed_addrs[i] == NULL) {
4938 g_config.hb_config.mesh_seed_addrs[i] = addr;
4939 g_config.hb_config.mesh_seed_ports[i] = port;
4940 g_config.hb_config.mesh_seed_tls[i] = tls;
4941 break;
4942 }
4943 }
4944
4945 if (i == AS_CLUSTER_SZ) {
4946 cf_crash_nostack(AS_CFG, "can't configure more than %d mesh-seed-address-port entries", AS_CLUSTER_SZ);
4947 }
4948}
4949
4950as_set*
4951cfg_add_set(as_namespace* ns)
4952{
4953 if (ns->sets_cfg_count >= AS_SET_MAX_COUNT) {
4954 cf_crash_nostack(AS_CFG, "{%s} too many sets", ns->name);
4955 }
4956
4957 // Lazily allocate temporary sets config array.
4958 if (! ns->sets_cfg_array) {
4959 size_t array_size = AS_SET_MAX_COUNT * sizeof(as_set);
4960
4961 ns->sets_cfg_array = (as_set*)cf_malloc(array_size);
4962 memset(ns->sets_cfg_array, 0, array_size);
4963 }
4964
4965 return &ns->sets_cfg_array[ns->sets_cfg_count++];
4966}
4967
4968void
4969cfg_add_xmem_mount(as_namespace* ns, const char* mount)
4970{
4971 if (ns->n_xmem_mounts == CF_XMEM_MAX_MOUNTS) {
4972 cf_crash_nostack(AS_CFG, "{%s} too many mounts", ns->name);
4973 }
4974
4975 for (uint32_t i = 0; i < ns->n_xmem_mounts; i++) {
4976 if (strcmp(mount, ns->xmem_mounts[i]) == 0) {
4977 cf_crash_nostack(AS_CFG, "{%s} duplicate mount %s", ns->name, mount);
4978 }
4979 }
4980
4981 ns->xmem_mounts[ns->n_xmem_mounts++] = mount;
4982}
4983
4984void
4985cfg_add_storage_file(as_namespace* ns, const char* file_name,
4986 const char* shadow_name)
4987{
4988 if (ns->n_storage_devices != 0) {
4989 cf_crash_nostack(AS_CFG, "{%s} mixture of storage files and devices", ns->name);
4990 }
4991
4992 if (ns->n_storage_files == AS_STORAGE_MAX_DEVICES) {
4993 cf_crash_nostack(AS_CFG, "{%s} too many storage files", ns->name);
4994 }
4995
4996 for (uint32_t i = 0; i < ns->n_storage_files; i++) {
4997 if (strcmp(file_name, ns->storage_devices[i]) == 0) {
4998 cf_crash_nostack(AS_CFG, "{%s} duplicate storage file %s", ns->name, file_name);
4999 }
5000
5001 if (shadow_name && ns->storage_shadows[i] &&
5002 strcmp(shadow_name, ns->storage_shadows[i]) == 0) {
5003 cf_crash_nostack(AS_CFG, "{%s} duplicate storage shadow file %s", ns->name, shadow_name);
5004 }
5005 }
5006
5007 if (shadow_name) {
5008 ns->storage_shadows[ns->n_storage_shadows++] = shadow_name;
5009 }
5010
5011 ns->storage_devices[ns->n_storage_files++] = file_name;
5012
5013 if (ns->n_storage_shadows != 0 &&
5014 ns->n_storage_shadows != ns->n_storage_files) {
5015 cf_crash_nostack(AS_CFG, "{%s} no shadow for file %s", ns->name, file_name);
5016 }
5017}
5018
5019void
5020cfg_add_storage_device(as_namespace* ns, const char* device_name,
5021 const char* shadow_name)
5022{
5023 if (ns->n_storage_files != 0) {
5024 cf_crash_nostack(AS_CFG, "{%s} mixture of storage files and devices", ns->name);
5025 }
5026
5027 if (ns->n_storage_devices == AS_STORAGE_MAX_DEVICES) {
5028 cf_crash_nostack(AS_CFG, "{%s} too many storage devices", ns->name);
5029 }
5030
5031 for (uint32_t i = 0; i < ns->n_storage_devices; i++) {
5032 if (strcmp(device_name, ns->storage_devices[i]) == 0) {
5033 cf_crash_nostack(AS_CFG, "{%s} duplicate storage device %s", ns->name, device_name);
5034 }
5035
5036 if (shadow_name && ns->storage_shadows[i] &&
5037 strcmp(shadow_name, ns->storage_shadows[i]) == 0) {
5038 cf_crash_nostack(AS_CFG, "{%s} duplicate storage shadow device %s", ns->name, shadow_name);
5039 }
5040 }
5041
5042 if (shadow_name) {
5043 ns->storage_shadows[ns->n_storage_shadows++] = shadow_name;
5044 }
5045
5046 ns->storage_devices[ns->n_storage_devices++] = device_name;
5047
5048 if (ns->n_storage_shadows != 0 &&
5049 ns->n_storage_shadows != ns->n_storage_devices) {
5050 cf_crash_nostack(AS_CFG, "{%s} no shadow for device %s", ns->name, device_name);
5051 }
5052}
5053
5054void
5055cfg_set_cluster_name(char* cluster_name){
5056 if(!as_config_cluster_name_set(cluster_name)){
5057 cf_crash_nostack(AS_CFG, "cluster name '%s' is not allowed", cluster_name);
5058 }
5059}
5060
5061void
5062cfg_add_ldap_role_query_pattern(char* pattern)
5063{
5064 int i;
5065
5066 for (i = 0; i < MAX_ROLE_QUERY_PATTERNS; i++) {
5067 if (g_config.sec_cfg.ldap_role_query_patterns[i] == NULL) {
5068 g_config.sec_cfg.ldap_role_query_patterns[i] = pattern;
5069 break;
5070 }
5071 }
5072
5073 if (i == MAX_ROLE_QUERY_PATTERNS) {
5074 cf_crash_nostack(AS_CFG, "too many ldap role query patterns");
5075 }
5076}
5077
5078
5079//==========================================================
5080// Other (non-item-specific) utilities.
5081//
5082
5083void
5084create_and_check_hist_track(cf_hist_track** h, const char* name,
5085 histogram_scale scale)
5086{
5087 *h = cf_hist_track_create(name, scale);
5088
5089 as_config* c = &g_config;
5090
5091 if (c->hist_track_back != 0 &&
5092 ! cf_hist_track_start(*h, c->hist_track_back, c->hist_track_slice, c->hist_track_thresholds)) {
5093 cf_crash_nostack(AS_AS, "couldn't enable histogram tracking: %s", name);
5094 }
5095}
5096
5097// TODO - not really a config method any more, reorg needed.
5098void
5099cfg_create_all_histograms()
5100{
5101 g_stats.batch_index_hist = histogram_create("batch-index", HIST_MILLISECONDS);
5102 g_stats.info_hist = histogram_create("info", HIST_MILLISECONDS);
5103 g_stats.svc_demarshal_hist = histogram_create("svc-demarshal", HIST_MILLISECONDS);
5104 g_stats.svc_queue_hist = histogram_create("svc-queue", HIST_MILLISECONDS);
5105
5106 g_stats.fabric_send_init_hists[AS_FABRIC_CHANNEL_BULK] = histogram_create("fabric-bulk-send-init", HIST_MILLISECONDS);
5107 g_stats.fabric_send_fragment_hists[AS_FABRIC_CHANNEL_BULK] = histogram_create("fabric-bulk-send-fragment", HIST_MILLISECONDS);
5108 g_stats.fabric_recv_fragment_hists[AS_FABRIC_CHANNEL_BULK] = histogram_create("fabric-bulk-recv-fragment", HIST_MILLISECONDS);
5109 g_stats.fabric_recv_cb_hists[AS_FABRIC_CHANNEL_BULK] = histogram_create("fabric-bulk-recv-cb", HIST_MILLISECONDS);
5110 g_stats.fabric_send_init_hists[AS_FABRIC_CHANNEL_CTRL] = histogram_create("fabric-ctrl-send-init", HIST_MILLISECONDS);
5111 g_stats.fabric_send_fragment_hists[AS_FABRIC_CHANNEL_CTRL] = histogram_create("fabric-ctrl-send-fragment", HIST_MILLISECONDS);
5112 g_stats.fabric_recv_fragment_hists[AS_FABRIC_CHANNEL_CTRL] = histogram_create("fabric-ctrl-recv-fragment", HIST_MILLISECONDS);
5113 g_stats.fabric_recv_cb_hists[AS_FABRIC_CHANNEL_CTRL] = histogram_create("fabric-ctrl-recv-cb", HIST_MILLISECONDS);
5114 g_stats.fabric_send_init_hists[AS_FABRIC_CHANNEL_META] = histogram_create("fabric-meta-send-init", HIST_MILLISECONDS);
5115 g_stats.fabric_send_fragment_hists[AS_FABRIC_CHANNEL_META] = histogram_create("fabric-meta-send-fragment", HIST_MILLISECONDS);
5116 g_stats.fabric_recv_fragment_hists[AS_FABRIC_CHANNEL_META] = histogram_create("fabric-meta-recv-fragment", HIST_MILLISECONDS);
5117 g_stats.fabric_recv_cb_hists[AS_FABRIC_CHANNEL_META] = histogram_create("fabric-meta-recv-cb", HIST_MILLISECONDS);
5118 g_stats.fabric_send_init_hists[AS_FABRIC_CHANNEL_RW] = histogram_create("fabric-rw-send-init", HIST_MILLISECONDS);
5119 g_stats.fabric_send_fragment_hists[AS_FABRIC_CHANNEL_RW] = histogram_create("fabric-rw-send-fragment", HIST_MILLISECONDS);
5120 g_stats.fabric_recv_fragment_hists[AS_FABRIC_CHANNEL_RW] = histogram_create("fabric-rw-recv-fragment", HIST_MILLISECONDS);
5121 g_stats.fabric_recv_cb_hists[AS_FABRIC_CHANNEL_RW] = histogram_create("fabric-rw-recv-cb", HIST_MILLISECONDS);
5122}
5123
5124void
5125cfg_init_serv_spec(cf_serv_spec* spec_p)
5126{
5127 spec_p->bind_port = 0;
5128 init_addr_list(&spec_p->bind);
5129 spec_p->std_port = 0;
5130 init_addr_list(&spec_p->std);
5131 spec_p->alt_port = 0;
5132 init_addr_list(&spec_p->alt);
5133 spec_p->tls_our_name = NULL;
5134 spec_p->n_tls_peer_names = 0;
5135 memset(spec_p->tls_peer_names, 0, sizeof(spec_p->tls_peer_names));
5136}
5137
5138cf_tls_spec*
5139cfg_create_tls_spec(as_config* cfg, char* name)
5140{
5141 uint32_t ind = cfg->n_tls_specs++;
5142
5143 if (ind >= MAX_TLS_SPECS) {
5144 cf_crash_nostack(AS_CFG, "too many TLS configuration sections");
5145 }
5146
5147 cf_tls_spec* tls_spec = cfg->tls_specs + ind;
5148 tls_spec->name = cf_strdup(name);
5149 tls_spec->protocols = "TLSv1.2";
5150 return tls_spec;
5151}
5152
5153char*
5154cfg_resolve_tls_name(char* tls_name, const char* cluster_name, const char* which)
5155{
5156 bool expanded = false;
5157
5158 if (strcmp(tls_name, "<hostname>") == 0) {
5159 char hostname[1024];
5160 int rv = gethostname(hostname, sizeof(hostname));
5161 if (rv != 0) {
5162 cf_crash_nostack(AS_CFG,
5163 "trouble resolving hostname for tls-name: %s", cf_strerror(errno));
5164 }
5165 hostname[sizeof(hostname)-1] = '\0'; // POSIX.1-2001
5166 cf_free(tls_name);
5167 tls_name = cf_strdup(hostname);
5168 expanded = true;
5169 }
5170 else if (strcmp(tls_name, "<cluster-name>") == 0) {
5171 if (strlen(cluster_name) == 0) {
5172 cf_crash_nostack
5173 (AS_CFG, "can't resolve tls-name to non-existent cluster-name");
5174 }
5175 cf_free(tls_name);
5176 tls_name = cf_strdup(cluster_name);
5177 expanded = true;
5178 }
5179
5180 if (expanded && which != NULL) {
5181 cf_info(AS_CFG, "%s tls-name %s", which, tls_name);
5182 }
5183
5184 return tls_name;
5185}
5186
5187cf_tls_spec*
5188cfg_link_tls(const char* which, char** our_name)
5189{
5190 if (*our_name == NULL) {
5191 cf_crash_nostack(AS_CFG, "%s TLS configuration requires tls-name", which);
5192 }
5193
5194 *our_name = cfg_resolve_tls_name(*our_name, g_config.cluster_name, which);
5195 cf_tls_spec* tls_spec = NULL;
5196
5197 for (uint32_t i = 0; i < g_config.n_tls_specs; ++i) {
5198 if (strcmp(*our_name, g_config.tls_specs[i].name) == 0) {
5199 tls_spec = g_config.tls_specs + i;
5200 break;
5201 }
5202 }
5203
5204 if (tls_spec == NULL) {
5205 cf_crash_nostack(AS_CFG, "invalid tls-name in TLS configuration: %s",
5206 *our_name);
5207 }
5208
5209 return tls_spec;
5210}
5211
5212void
5213cfg_keep_cap(bool keep, bool* what, int32_t cap)
5214{
5215 *what = keep;
5216
5217 if (keep) {
5218 cf_process_add_runtime_cap(cap);
5219 }
5220}
5221
5222
5223//==========================================================
5224// XDR utilities.
5225//
5226
5227xdr_dest_config*
5228xdr_cfg_add_datacenter(char* name)
5229{
5230 if (g_dc_count == DC_MAX_NUM) {
5231 cf_crash_nostack(AS_CFG, "Cannot have more than %d datacenters", DC_MAX_NUM);
5232 }
5233
5234 xdr_dest_config* dest_cfg = &g_dest_xcfg_opt[g_dc_count];
5235
5236 dest_cfg->name = name;
5237 dest_cfg->id = g_dc_count;
5238 xdr_config_dest_defaults(dest_cfg);
5239
5240 return dest_cfg;
5241}
5242
5243void
5244xdr_cfg_associate_datacenter(char* dc, uint32_t nsid)
5245{
5246 cf_vector* v = &g_config.namespaces[nsid-1]->xdr_dclist_v;
5247
5248 // Crash if datacenter with same name already exists.
5249 for (uint32_t index = 0; index < cf_vector_size(v); index++) {
5250 if (strcmp((char *)cf_vector_pointer_get(v, index), dc) == 0) {
5251 cf_crash_nostack(AS_XDR, "datacenter %s already exists for namespace %s - please remove duplicate entries from config file",
5252 dc, g_config.namespaces[nsid-1]->name);
5253 }
5254 }
5255
5256 // Add the string pointer (of the datacenter name) to the vector.
5257 cf_vector_pointer_append(v, dc);
5258}
5259
5260void
5261xdr_cfg_add_http_url(xdr_dest_config* dest_cfg, char* url)
5262{
5263 // Remember that we are only putting pointer in the vector
5264 cf_vector_append(&dest_cfg->http.urls, &url);
5265}
5266
5267void
5268xdr_cfg_add_node_addr_port(xdr_dest_config* dest_cfg, char* addr, int port)
5269{
5270 xdr_cfg_add_tls_node(dest_cfg, addr, NULL, port);
5271}
5272
5273void
5274xdr_cfg_add_tls_node(xdr_dest_config* dest_cfg, char* addr, char* tls_name, int port)
5275{
5276 // Add the element to the vector.
5277 node_addr_port* nap = (node_addr_port*)cf_malloc(sizeof(node_addr_port));
5278
5279 nap->addr = addr;
5280 nap->tls_name = tls_name;
5281 nap->port = port;
5282
5283 cf_vector_pointer_append(&dest_cfg->aero.dc_nodes, nap);
5284}
5285