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
|
// -*- 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) 2017 John Spray <john.spray@redhat.com>
*
* 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.
*/
#pragma once
#include <string>
#include "include/encoding.h"
struct MonCommand {
std::string cmdstring;
std::string helpstring;
std::string module;
std::string req_perms;
uint64_t flags;
// MonCommand flags
static const uint64_t FLAG_NONE = 0;
static const uint64_t FLAG_NOFORWARD = 1 << 0;
static const uint64_t FLAG_OBSOLETE = 1 << 1;
static const uint64_t FLAG_DEPRECATED = 1 << 2;
static const uint64_t FLAG_MGR = 1 << 3;
static const uint64_t FLAG_POLL = 1 << 4;
static const uint64_t FLAG_HIDDEN = 1 << 5;
// asok and tell commands are not forwarded, and they should not be listed
// in --help output.
static const uint64_t FLAG_TELL = (FLAG_NOFORWARD | FLAG_HIDDEN);
bool has_flag(uint64_t flag) const { return (flags & flag) == flag; }
void set_flag(uint64_t flag) { flags |= flag; }
void unset_flag(uint64_t flag) { flags &= ~flag; }
void encode(ceph::buffer::list &bl) const {
ENCODE_START(1, 1, bl);
encode_bare(bl);
encode(flags, bl);
ENCODE_FINISH(bl);
}
void decode(ceph::buffer::list::const_iterator &bl) {
DECODE_START(1, bl);
decode_bare(bl);
decode(flags, bl);
DECODE_FINISH(bl);
}
/**
* Unversioned encoding for use within encode_array.
*/
void encode_bare(ceph::buffer::list &bl) const {
using ceph::encode;
encode(cmdstring, bl);
encode(helpstring, bl);
encode(module, bl);
encode(req_perms, bl);
std::string availability = "cli,rest"; // Removed field, for backward compat
encode(availability, bl);
}
void decode_bare(ceph::buffer::list::const_iterator &bl) {
using ceph::decode;
decode(cmdstring, bl);
decode(helpstring, bl);
decode(module, bl);
decode(req_perms, bl);
std::string availability; // Removed field, for backward compat
decode(availability, bl);
}
bool is_compat(const MonCommand* o) const {
return cmdstring == o->cmdstring &&
module == o->module && req_perms == o->req_perms;
}
bool is_tell() const {
return has_flag(MonCommand::FLAG_TELL);
}
bool is_noforward() const {
return has_flag(MonCommand::FLAG_NOFORWARD);
}
bool is_obsolete() const {
return has_flag(MonCommand::FLAG_OBSOLETE);
}
bool is_deprecated() const {
return has_flag(MonCommand::FLAG_DEPRECATED);
}
bool is_mgr() const {
return has_flag(MonCommand::FLAG_MGR);
}
bool is_hidden() const {
return has_flag(MonCommand::FLAG_HIDDEN);
}
static void encode_array(const MonCommand *cmds, int size, ceph::buffer::list &bl) {
ENCODE_START(2, 1, bl);
uint16_t s = size;
encode(s, bl);
for (int i = 0; i < size; ++i) {
cmds[i].encode_bare(bl);
}
for (int i = 0; i < size; i++) {
encode(cmds[i].flags, bl);
}
ENCODE_FINISH(bl);
}
static void decode_array(MonCommand **cmds, int *size,
ceph::buffer::list::const_iterator &bl) {
DECODE_START(2, bl);
uint16_t s = 0;
decode(s, bl);
*size = s;
*cmds = new MonCommand[*size];
for (int i = 0; i < *size; ++i) {
(*cmds)[i].decode_bare(bl);
}
if (struct_v >= 2) {
for (int i = 0; i < *size; i++)
decode((*cmds)[i].flags, bl);
} else {
for (int i = 0; i < *size; i++)
(*cmds)[i].flags = 0;
}
DECODE_FINISH(bl);
}
// this uses a u16 for the count, so we need a special encoder/decoder.
static void encode_vector(const std::vector<MonCommand>& cmds,
ceph::buffer::list &bl) {
ENCODE_START(2, 1, bl);
uint16_t s = cmds.size();
encode(s, bl);
for (unsigned i = 0; i < s; ++i) {
cmds[i].encode_bare(bl);
}
for (unsigned i = 0; i < s; i++) {
encode(cmds[i].flags, bl);
}
ENCODE_FINISH(bl);
}
static void decode_vector(std::vector<MonCommand> &cmds,
ceph::buffer::list::const_iterator &bl) {
DECODE_START(2, bl);
uint16_t s = 0;
decode(s, bl);
cmds.resize(s);
for (unsigned i = 0; i < s; ++i) {
cmds[i].decode_bare(bl);
}
if (struct_v >= 2) {
for (unsigned i = 0; i < s; i++)
decode(cmds[i].flags, bl);
} else {
for (unsigned i = 0; i < s; i++)
cmds[i].flags = 0;
}
DECODE_FINISH(bl);
}
bool requires_perm(char p) const {
return (req_perms.find(p) != std::string::npos);
}
};
WRITE_CLASS_ENCODER(MonCommand)
|