summaryrefslogtreecommitdiff
path: root/src/mon/MonCommands.h
blob: a961574179c8fa8a1a07454c9618d1bfdcefa46b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2013 Inktank Storage, Inc. 
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software 
 * Foundation.  See file COPYING.
 * 
 */

/* no guard; may be included multiple times */

/*
 * Define commands that are reported by the monitor's
 * "get_command_descriptions" command, and parsed by the Python
 * frontend 'ceph' (and perhaps by other frontends, such as a RESTful
 * server). The format is:
 *
 * COMMAND(signature, helpstring, modulename, req perms, availability)
 * where:
 * signature:  describes the command and its parameters (more below)
 * helpstring: displays in CLI help, API help (nice if it refers to
 *             parameter names from signature, 40-a few hundred chars)
 * modulename: the monitor module or daemon this applies to:
 *             mds, osd, pg (osd), mon, auth, log, config-key
 * req perms:  required permission in that modulename space to execute command
 *             this also controls what type of REST command is accepted
 * availability: cli, rest, or both
 *
 * The commands describe themselves completely enough for the separate
 * frontend(s) to be able to accept user input and validate it against
 * the command descriptions, and generate a JSON object that contains
 * key:value mappings of parameter names to validated parameter values.
 *
 * 'signature' is a space-separated list of individual command descriptors;
 * each descriptor is either a literal string, which can contain no spaces or
 * '=' signs (for instance, in "pg stat", both "pg" and "stat" are literal
 * strings representing one descriptor each), or a list of key=val[,key=val...]
 * which also includes no spaces.  
 *
 * The key=val form describes a non-literal parameter.  Each will have at
 * least a name= and type=, and each type can have its own type-specific
 * parameters.  The parser is the arbiter of these types and their 
 * interpretation.  A few more non-type-specific key=val pairs exist:
 *
 *    req=false marks an optional parameter (default for req is 'true')
 *    n=<n> is a repeat count for how many of this argument must be supplied.
 *          n=1 is the default.
 *          n=N is a special case that means "1 or more".
 *
 * A perhaps-incomplete list of types:
 *
 * CephInt: Optional: range=min[|max]
 * CephFloat: Optional range
 * CephString: optional badchars
 * CephSocketpath: validation involves "is it S_ISSOCK"
 * CephIPAddr: v4 or v6 addr with optional port, syntax validated
 * CephEntityAddr: CephIPAddr + optional '/nonce'
 * CephPoolname: Plainold string
 * CephObjectname: Another plainold string
 * CephPgid: n.xxx where n is an int > 0, xxx is a hex number > 0
 * CephName: daemon name, '*' or '<type>.<id>' (id must be int for type osd)
 * CephOsdName: osd name, '*' or '<id> or 'osd.<id>' (id must be int)
 * CephChoices: strings="foo|bar" means this param can be either
 * CephFilepath: openable file
 * CephFragment: cephfs 'fragID': val/bits, val in hex 0xnnn, bits in dec
 * CephUUID: uuid in text matching Python uuid.UUID()
 * CephPrefix: special type assigned to literals
 *
 * Example:
 *
 * COMMAND("auth add " \
 *   	   "name=entity,type=CephString " \
 *   	   "name=caps,type=CephString,n=N,req=false", \
 *   	   "add auth info for <name> from input file, or random key " \
 *   	   "if no input given, and/or any caps specified in the command")
 *
 * defines a command "auth add" that takes a required argument "entity"
 * of type "CephString", and from 1 to N arguments named "caps" of type
 * CephString, at least one of which is required.  The front end will
 * validate user input against this description.  Let's say the user
 * enters auth add client.admin 'mon rwx' 'osd *'.  The result will be a
 * JSON object like {"prefix":"auth add", "entity":"client.admin",
 * "caps":["mon rwx", "osd *"]}.
 * Note that 
 * 	- string literals are accumulated into 'prefix'
 * 	- n=1 descriptors are given normal string or int object values
 * 	- n=N descriptors are given array values
 *
 * NOTE: be careful with spaces.  Each descriptor must be separated by
 * one space, no other characters, so if you split lines as above, be
 * sure to close and reopen the quotes, and be careful to include the '
 * separating spaces in the quoted string.
 *
 * The monitor marshals this JSON into a std::map<string, cmd_vartype>
* where cmd_vartype is a boost::variant type-enforcing discriminated
* type, so the monitor is expected to know the type of each argument.
* See cmdparse.cc/h for more details.
*/

/*
 * pg commands PgMonitor.cc
 */

COMMAND("pg stat", "show placement group status.", "pg", "r", "cli,rest")
COMMAND("pg getmap", "get binary pg map to -o/stdout", "pg", "r", "cli,rest")
COMMAND("pg send_pg_creates", "trigger pg creates to be issued",\
	"pg", "rw", "cli,rest")
COMMAND("pg dump " \
	"name=dumpcontents,type=CephChoices,strings=all|summary|sum|delta|pools|osds|pgs|pgs_brief,n=N,req=false", \
	"show human-readable versions of pg map", "pg", "r", "cli,rest")
COMMAND("pg dump_json " \
	"name=dumpcontents,type=CephChoices,strings=all|summary|sum|pools|osds|pgs,n=N,req=false", \
	"show human-readable version of pg map in json only",\
	"pg", "r", "cli,rest")
COMMAND("pg dump_pools_json", "show pg pools info in json only",\
	"pg", "r", "cli,rest")
COMMAND("pg dump_stuck " \
	"name=stuckops,type=CephChoices,strings=inactive|unclean|stale,n=N,req=false " \
	"name=threshold,type=CephInt,req=false",
	"show information about stuck pgs",\
	"pg", "r", "cli,rest")
COMMAND("pg map name=pgid,type=CephPgid", "show mapping of pg to osds", \
	"pg", "r", "cli,rest")
COMMAND("pg scrub name=pgid,type=CephPgid", "start scrub on <pgid>", \
	"pg", "rw", "cli,rest")
COMMAND("pg deep-scrub name=pgid,type=CephPgid", "start deep-scrub on <pgid>", \
	"pg", "rw", "cli,rest")
COMMAND("pg repair name=pgid,type=CephPgid", "start repair on <pgid>", \
	"pg", "rw", "cli,rest")
COMMAND("pg debug " \
	"name=debugop,type=CephChoices,strings=unfound_objects_exist|degraded_pgs_exist", \
	"show debug info about pgs", "pg", "r", "cli,rest")
COMMAND("pg force_create_pg name=pgid,type=CephPgid", \
	"force creation of pg <pgid>", "pg", "rw", "cli,rest")
COMMAND("pg set_full_ratio name=ratio,type=CephFloat,range=0.0|1.0", \
	"set ratio at which pgs are considered full", "pg", "rw", "cli,rest")
COMMAND("pg set_nearfull_ratio name=ratio,type=CephFloat,range=0.0|1.0", \
	"set ratio at which pgs are considered nearly full", \
	"pg", "rw", "cli,rest")

/*
 * auth commands AuthMonitor.cc
 */

COMMAND("auth export name=entity,type=CephString,req=false", \
       	"write keyring for requested entity, or master keyring if none given", \
	"auth", "r", "cli,rest")
COMMAND("auth get name=entity,type=CephString", \
	"write keyring file with requested key", "auth", "r", "cli,rest")
COMMAND("auth get-key name=entity,type=CephString", "display requested key", \
	"auth", "r", "cli,rest")
COMMAND("auth print-key name=entity,type=CephString", "display requested key", \
	"auth", "r", "cli,rest")
COMMAND("auth print_key name=entity,type=CephString", "display requested key", \
	"auth", "r", "cli,rest")
COMMAND("auth list", "list authentication state", "auth", "r", "cli,rest")
COMMAND("auth import", "auth import: read keyring file from -i <file>", \
	"auth", "rw", "cli,rest")
COMMAND("auth add " \
	"name=entity,type=CephString " \
	"name=caps,type=CephString,n=N,req=false", \
	"add auth info for <entity> from input file, or random key if no input given, and/or any caps specified in the command",
	"auth", "rw", "cli,rest")
COMMAND("auth get-or-create-key " \
	"name=entity,type=CephString " \
	"name=caps,type=CephString,n=N,req=false", \
	"get, or add, key for <name> from system/caps pairs specified in the command.  If key already exists, any given caps must match the existing caps for that key.", \
	"auth", "rw", "cli,rest")
COMMAND("auth get-or-create " \
	"name=entity,type=CephString " \
	"name=caps,type=CephString,n=N,req=false", \
	"add auth info for <entity> from input file, or random key if no input given, and/or any caps specified in the command", \
	"auth", "rw", "cli,rest")
COMMAND("auth caps " \
	"name=entity,type=CephString " \
	"name=caps,type=CephString,n=N", \
	"update caps for <name> from caps specified in the command", \
	"auth", "rw", "cli,rest")
COMMAND("auth del " \
	"name=entity,type=CephString", \
	"delete all caps for <name>", \
	"auth", "rw", "cli,rest")

/*
 * Monitor commands (Monitor.cc)
 */
COMMAND("compact", "cause compaction of monitor's leveldb storage", \
	"mon", "rw", "cli,rest")
COMMAND("scrub", "scrub the monitor stores", "mon", "rw", "cli,rest")
COMMAND("fsid", "show cluster FSID/UUID", "mon", "r", "cli,rest")
COMMAND("log name=logtext,type=CephString,n=N", \
	"log supplied text to the monitor log", "mon", "rw", "cli,rest")
COMMAND("injectargs " \
	"name=injected_args,type=CephString,n=N", \
	"inject config arguments into monitor", "mon", "rw", "cli,rest")
COMMAND("status", "show cluster status", "mon", "r", "cli,rest")
COMMAND("health name=detail,type=CephChoices,strings=detail,req=false", \
	"show cluster health", "mon", "r", "cli,rest")
COMMAND("df name=detail,type=CephChoices,strings=detail,req=false", \
	"show cluster free space stats", "mon", "r", "cli,rest")
COMMAND("report name=tags,type=CephString,n=N,req=false", \
	"report full status of cluster, optional title tag strings", \
	"mon", "r", "cli,rest")
COMMAND("quorum_status", "report status of monitor quorum", \
	"mon", "r", "cli,rest")
COMMAND("mon_status", "report status of monitors", "mon", "r", "cli,rest")
COMMAND("sync force " \
	"name=validate1,type=CephChoices,strings=--yes-i-really-mean-it,req=false " \
	"name=validate2,type=CephChoices,strings=--i-know-what-i-am-doing,req=false", \
	"force sync of and clear monitor store", "mon", "rw", "cli,rest")
COMMAND("heap " \
	"name=heapcmd,type=CephChoices,strings=dump|start_profiler|stop_profiler|release|stats", \
	"show heap usage info (available only if compiled with tcmalloc)", \
	"mon", "rw", "cli,rest")
COMMAND("quorum name=quorumcmd,type=CephChoices,strings=enter|exit,n=1", \
	"enter or exit quorum", "mon", "rw", "cli,rest")
COMMAND("tell " \
	"name=target,type=CephName " \
	"name=args,type=CephString,n=N", \
	"send a command to a specific daemon", "mon", "rw", "cli,rest")

/*
 * MDS commands (MDSMonitor.cc)
 */

COMMAND("mds stat", "show MDS status", "mds", "r", "cli,rest")
COMMAND("mds dump " 
	"name=epoch,type=CephInt,req=false,range=0", \
	"dump info, optionally from epoch", "mds", "r", "cli,rest")
COMMAND("mds getmap " \
	"name=epoch,type=CephInt,req=false,range=0", \
	"get MDS map, optionally from epoch", "mds", "r", "cli,rest")
COMMAND("mds tell " \
	"name=who,type=CephString " \
	"name=args,type=CephString,n=N", \
	"send command to particular mds", "mds", "rw", "cli,rest")
COMMAND("mds compat show", "show mds compatibility settings", \
	"mds", "r", "cli,rest")
COMMAND("mds stop name=who,type=CephString", "stop mds", \
	"mds", "rw", "cli,rest")
COMMAND("mds deactivate name=who,type=CephString", "stop mds", \
	"mds", "rw", "cli,rest")
COMMAND("mds set_max_mds " \
	"name=maxmds,type=CephInt,range=0", \
	"set max MDS index", "mds", "rw", "cli,rest")
COMMAND("mds setmap " \
	"name=epoch,type=CephInt,range=0", \
	"set mds map; must supply correct epoch number", "mds", "rw", "cli,rest")
// arbitrary limit 0-20 below; worth standing on head to make it
// relate to actual state definitions?
// #include "include/ceph_fs.h"
COMMAND("mds set_state " \
	"name=gid,type=CephInt,range=0 " \
	"name=state,type=CephInt,range=0|20", \
	"set mds state of <gid> to <numeric-state>", "mds", "rw", "cli,rest")
COMMAND("mds fail name=who,type=CephString", \
	"force mds to status failed", "mds", "rw", "cli,rest")
COMMAND("mds rm " \
	"name=gid,type=CephInt,range=0 " \
	"name=who,type=CephName", \
	"remove nonactive mds", "mds", "rw", "cli,rest")
COMMAND("mds rmfailed name=who,type=CephInt,range=0", "remove failed mds", \
	"mds", "rw", "cli,rest")
COMMAND("mds cluster_down", "take MDS cluster down", "mds", "rw", "cli,rest")
COMMAND("mds cluster_up", "bring MDS cluster up", "mds", "rw", "cli,rest")
COMMAND("mds compat rm_compat " \
	"name=feature,type=CephInt,range=0", \
	"remove compatible feature", "mds", "rw", "cli,rest")
COMMAND("mds compat rm_incompat " \
	"name=feature,type=CephInt,range=0", \
	"remove incompatible feature", "mds", "rw", "cli,rest")
COMMAND("mds set " \
        "name=key,type=CephChoices,strings=allow_new_snaps " \
        "name=sure,type=CephString,req=false", \
        "set <key>", \
        "mds", "w", "cli,rest")
COMMAND("mds unset " \
        "name=key,type=CephChoices,strings=allow_new_snaps " \
        "name=sure,type=CephString,req=false", \
        "unset <key>", "mds", "w", "cli,rest")
COMMAND("mds add_data_pool " \
	"name=pool,type=CephString", \
	"add data pool <pool>", "mds", "rw", "cli,rest")
COMMAND("mds remove_data_pool " \
	"name=pool,type=CephString", \
	"remove data pool <pool>", "mds", "rw", "cli,rest")
COMMAND("mds newfs " \
	"name=metadata,type=CephInt,range=0 " \
	"name=data,type=CephInt,range=0 " \
	"name=sure,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \
	"make new filesystom using pools <metadata> and <data>", \
	"mds", "rw", "cli,rest")
/*
 * Monmap commands
 */
COMMAND("mon dump " \
	"name=epoch,type=CephInt,range=0,req=false", \
	"dump formatted monmap (optionally from epoch)", \
	"mon", "r", "cli,rest")
COMMAND("mon stat", "summarize monitor status", "mon", "r", "cli,rest")
COMMAND("mon getmap " \
	"name=epoch,type=CephInt,range=0,req=false", \
	"get monmap", "mon", "r", "cli,rest")
COMMAND("mon add " \
	"name=name,type=CephString " \
	"name=addr,type=CephIPAddr", \
	"add new monitor named <name> at <addr>", "mon", "rw", "cli,rest")
COMMAND("mon remove " \
	"name=name,type=CephString", \
	"remove monitor named <name>", "mon", "rw", "cli,rest")


/*
 * OSD commands
 */
COMMAND("osd stat", "print summary of OSD map", "osd", "r", "cli,rest")
COMMAND("osd dump " \
	"name=epoch,type=CephInt,range=0,req=false",
	"print summary of OSD map", "osd", "r", "cli,rest")
COMMAND("osd tree " \
	"name=epoch,type=CephInt,range=0,req=false", \
	"print OSD tree", "osd", "r", "cli,rest")
COMMAND("osd ls " \
	"name=epoch,type=CephInt,range=0,req=false", \
	"show all OSD ids", "osd", "r", "cli,rest")
COMMAND("osd getmap " \
	"name=epoch,type=CephInt,range=0,req=false", \
	"get OSD map", "osd", "r", "cli,rest")
COMMAND("osd getcrushmap " \
	"name=epoch,type=CephInt,range=0,req=false", \
	"get CRUSH map", "osd", "r", "cli,rest")
COMMAND("osd perf", \
        "print dump of OSD perf summary stats", \
        "osd", \
        "r", \
        "cli,rest")
COMMAND("osd getmaxosd", "show largest OSD id", "osd", "r", "cli,rest")
COMMAND("osd find " \
	"name=id,type=CephInt,range=0", \
	"find osd <id> in the CRUSH map and show its location", \
	"osd", "r", "cli,rest")
COMMAND("osd map " \
	"name=pool,type=CephPoolname " \
	"name=object,type=CephObjectname", \
	"find pg for <object> in <pool>", "osd", "r", "cli,rest")
COMMAND("osd scrub " \
	"name=who,type=CephString", \
	"initiate scrub on osd <who>", "osd", "rw", "cli,rest")
COMMAND("osd deep-scrub " \
	"name=who,type=CephString", \
	"initiate deep scrub on osd <who>", "osd", "rw", "cli,rest")
COMMAND("osd repair " \
	"name=who,type=CephString", \
	"initiate repair on osd <who>", "osd", "rw", "cli,rest")
COMMAND("osd lspools " \
	"name=auid,type=CephInt,req=false", \
	"list pools", "osd", "r", "cli,rest")
COMMAND("osd blacklist ls", "show blacklisted clients", "osd", "r", "cli,rest")
COMMAND("osd crush rule list", "list crush rules", "osd", "r", "cli,rest")
COMMAND("osd crush rule ls", "list crush rules", "osd", "r", "cli,rest")
COMMAND("osd crush rule dump", "dump crush rules", "osd", "r", "cli,rest")
COMMAND("osd crush dump", "dump crush map", "osd", "r", "cli,rest")
COMMAND("osd setcrushmap", "set crush map from input file", \
	"osd", "rw", "cli,rest")
COMMAND("osd crush set", "set crush map from input file", \
	"osd", "rw", "cli,rest")
COMMAND("osd crush add-bucket " \
	"name=name,type=CephString,goodchars=[A-Za-z0-9-_.] " \
	"name=type,type=CephString", \
	"add no-parent (probably root) crush bucket <name> of type <type>", \
	"osd", "rw", "cli,rest")
COMMAND("osd crush set " \
	"name=id,type=CephOsdName " \
	"name=weight,type=CephFloat,range=0.0 " \
	"name=args,type=CephString,n=N,goodchars=[A-Za-z0-9-_.=]", \
	"update crushmap position and weight for <name> to <weight> with location <args>", \
	"osd", "rw", "cli,rest")
COMMAND("osd crush add " \
	"name=id,type=CephOsdName " \
	"name=weight,type=CephFloat,range=0.0 " \
	"name=args,type=CephString,n=N,goodchars=[A-Za-z0-9-_.=]", \
	"add or update crushmap position and weight for <name> with <weight> and location <args>", \
	"osd", "rw", "cli,rest")
COMMAND("osd crush create-or-move " \
	"name=id,type=CephOsdName " \
	"name=weight,type=CephFloat,range=0.0 " \
	"name=args,type=CephString,n=N,goodchars=[A-Za-z0-9-_.=]", \
	"create entry or move existing entry for <name> <weight> at/to location <args>", \
	"osd", "rw", "cli,rest")
COMMAND("osd crush move " \
	"name=name,type=CephString,goodchars=[A-Za-z0-9-_.] " \
	"name=args,type=CephString,n=N,goodchars=[A-Za-z0-9-_.=]", \
	"move existing entry for <name> to location <args>", \
	"osd", "rw", "cli,rest")
COMMAND("osd crush link " \
	"name=name,type=CephString " \
	"name=args,type=CephString,n=N,goodchars=[A-Za-z0-9-_.=]", \
	"link existing entry for <name> under location <args>", \
	"osd", "rw", "cli,rest")
COMMAND("osd crush rm " \
	"name=name,type=CephString,goodchars=[A-Za-z0-9-_.] " \
	"name=ancestor,type=CephString,req=false,goodchars=[A-Za-z0-9-_.]", \
	"remove <name> from crush map (everywhere, or just at <ancestor>",\
	"osd", "rw", "cli,rest")
COMMAND("osd crush remove " \
	"name=name,type=CephString,goodchars=[A-Za-z0-9-_.] " \
	"name=ancestor,type=CephString,req=false,goodchars=[A-Za-z0-9-_.]", \
	"remove <name> from crush map (everywhere, or just at <ancestor>", \
	"osd", "rw", "cli,rest")
COMMAND("osd crush unlink " \
	"name=name,type=CephString,goodchars=[A-Za-z0-9-_.] " \
	"name=ancestor,type=CephString,req=false,goodchars=[A-Za-z0-9-_.]", \
	"unlink <name> from crush map (everywhere, or just at <ancestor>", \
	"osd", "rw", "cli,rest")
COMMAND("osd crush reweight " \
	"name=name,type=CephString,goodchars=[A-Za-z0-9-_.] " \
	"name=weight,type=CephFloat,range=0.0", \
	"change <name>'s weight to <weight> in crush map", \
	"osd", "rw", "cli,rest")
COMMAND("osd crush tunables " \
	"name=profile,type=CephChoices,strings=legacy|argonaut|bobtail|optimal|default", \
	"set crush tunables values to <profile>", "osd", "rw", "cli,rest")
COMMAND("osd crush rule create-simple " \
	"name=name,type=CephString,goodchars=[A-Za-z0-9-_.] " \
	"name=root,type=CephString,goodchars=[A-Za-z0-9-_.] " \
	"name=type,type=CephString,goodchars=[A-Za-z0-9-_.]",
	"create crush rule <name> in <root> of type <type>", \
	"osd", "rw", "cli,rest")
COMMAND("osd crush rule rm " \
	"name=name,type=CephString,goodchars=[A-Za-z0-9-_.] ",	\
	"remove crush rule <name>", "osd", "rw", "cli,rest")
COMMAND("osd setmaxosd " \
	"name=newmax,type=CephInt,range=0", \
	"set new maximum osd value", "osd", "rw", "cli,rest")
COMMAND("osd pause", "pause osd", "osd", "rw", "cli,rest")
COMMAND("osd unpause", "unpause osd", "osd", "rw", "cli,rest")
COMMAND("osd set " \
	"name=key,type=CephChoices,strings=pause|noup|nodown|noout|noin|nobackfill|norecover|noscrub|nodeep-scrub", \
	"set <key>", "osd", "rw", "cli,rest")
COMMAND("osd unset " \
	"name=key,type=CephChoices,strings=pause|noup|nodown|noout|noin|nobackfill|norecover|noscrub|nodeep-scrub", \
	"unset <key>", "osd", "rw", "cli,rest")
COMMAND("osd cluster_snap", "take cluster snapshot (disabled)", \
	"osd", "r", "")
COMMAND("osd down " \
	"type=CephString,name=ids,n=N", \
	"set osd(s) <id> [<id>...] down", "osd", "rw", "cli,rest")
COMMAND("osd out " \
	"name=ids,type=CephString,n=N", \
	"set osd(s) <id> [<id>...] out", "osd", "rw", "cli,rest")
COMMAND("osd in " \
	"name=ids,type=CephString,n=N", \
	"set osd(s) <id> [<id>...] in", "osd", "rw", "cli,rest")
COMMAND("osd rm " \
	"name=ids,type=CephString,n=N", \
	"remove osd(s) <id> [<id>...] in", "osd", "rw", "cli,rest")
COMMAND("osd reweight " \
	"name=id,type=CephInt,range=0 " \
	"type=CephFloat,name=weight,range=0.0|1.0", \
	"reweight osd to 0.0 < <weight> < 1.0", "osd", "rw", "cli,rest")
COMMAND("osd lost " \
	"name=id,type=CephInt,range=0 " \
	"name=sure,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \
	"mark osd as permanently lost. THIS DESTROYS DATA IF NO MORE REPLICAS EXIST, BE CAREFUL", \
	"osd", "rw", "cli,rest")
COMMAND("osd create " \
	"name=uuid,type=CephUUID,req=false", \
	"create new osd (with optional UUID)", "osd", "rw", "cli,rest")
COMMAND("osd blacklist " \
	"name=blacklistop,type=CephChoices,strings=add|rm " \
	"name=addr,type=CephEntityAddr " \
	"name=expire,type=CephFloat,range=0.0,req=false", \
	"add (optionally until <expire> seconds from now) or remove <addr> from blacklist", \
	"osd", "rw", "cli,rest")
COMMAND("osd pool mksnap " \
	"name=pool,type=CephPoolname " \
	"name=snap,type=CephString", \
	"make snapshot <snap> in <pool>", "osd", "rw", "cli,rest")
COMMAND("osd pool rmsnap " \
	"name=pool,type=CephPoolname " \
	"name=snap,type=CephString", \
	"remove snapshot <snap> from <pool>", "osd", "rw", "cli,rest")
COMMAND("osd pool create " \
	"name=pool,type=CephPoolname " \
	"name=pg_num,type=CephInt,range=0 " \
	"name=pgp_num,type=CephInt,range=0,req=false " \
	"name=properties,type=CephString,n=N,req=false,goodchars=[A-Za-z0-9-_.=]", \
	"create pool", "osd", "rw", "cli,rest")
COMMAND("osd pool delete " \
	"name=pool,type=CephPoolname " \
	"name=pool2,type=CephPoolname,req=false " \
	"name=sure,type=CephChoices,strings=--yes-i-really-really-mean-it,req=false", \
	"delete pool", \
	"osd", "rw", "cli,rest")
COMMAND("osd pool rename " \
	"name=srcpool,type=CephPoolname " \
	"name=destpool,type=CephPoolname", \
	"rename <srcpool> to <destpool>", "osd", "rw", "cli,rest")
COMMAND("osd pool get " \
	"name=pool,type=CephPoolname " \
	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset", \
	"get pool parameter <var>", "osd", "r", "cli,rest")
COMMAND("osd pool set " \
	"name=pool,type=CephPoolname " \
	"name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset " \
	"name=val,type=CephInt", \
	"set pool parameter <var> to <val>", "osd", "rw", "cli,rest")
// 'val' is a CephString because it can include a unit.  Perhaps
// there should be a Python type for validation/conversion of strings
// with units.
COMMAND("osd pool set-quota " \
	"name=pool,type=CephPoolname " \
	"name=field,type=CephChoices,strings=max_objects|max_bytes " \
	"name=val,type=CephString",
	"set object or byte limit on pool", "osd", "rw", "cli,rest")
COMMAND("osd reweight-by-utilization " \
	"name=oload,type=CephInt,range=100,req=false", \
	"reweight OSDs by utilization [overload-percentage-for-consideration, default 120]", \
	"osd", "rw", "cli,rest")
COMMAND("osd thrash " \
	"name=num_epochs,type=CephInt,range=0", \
	"thrash OSDs for <num_epochs>", "osd", "rw", "cli,rest")

// tiering
COMMAND("osd tier add " \
	"name=pool,type=CephPoolname " \
	"name=tierpool,type=CephPoolname",
	"add the tier <tierpool> to base pool <pool>", "osd", "rw", "cli,rest")
COMMAND("osd tier remove " \
	"name=pool,type=CephPoolname " \
	"name=tierpool,type=CephPoolname",
	"remove the tier <tierpool> from base pool <pool>", "osd", "rw", "cli,rest")
COMMAND("osd tier cache-mode " \
	"name=pool,type=CephPoolname " \
	"name=mode,type=CephChoices,strings=none|writeback|invalidate+forward|readonly", \
	"specify the caching mode for cache tier <pool>", "osd", "rw", "cli,rest")
COMMAND("osd tier set-overlay " \
	"name=pool,type=CephPoolname " \
	"name=overlaypool,type=CephPoolname", \
	"set the overlay pool for base pool <pool> to be <overlaypool>", "osd", "rw", "cli,rest")
COMMAND("osd tier remove-overlay " \
	"name=pool,type=CephPoolname ", \
	"remove the overlay pool for base pool <pool>", "osd", "rw", "cli,rest")

/*
 * mon/ConfigKeyService.cc
 */

COMMAND("config-key get " \
	"name=key,type=CephString", \
	"get <key>", "config-key", "r", "cli,rest")
COMMAND("config-key put " \
	"name=key,type=CephString " \
	"name=val,type=CephString,req=false", \
	"put <key>, value <val>", "config-key", "rw", "cli,rest")
COMMAND("config-key del " \
	"name=key,type=CephString", \
	"delete <key>", "config-key", "rw", "cli,rest")
COMMAND("config-key exists " \
	"name=key,type=CephString", \
	"check for <key>'s existence", "config-key", "r", "cli,rest")
COMMAND("config-key list ", "list keys", "config-key", "r", "cli,rest")