Commit | Line | Data |
---|---|---|
d7e09d03 PT |
1 | /* |
2 | * GPL HEADER START | |
3 | * | |
4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 only, | |
8 | * as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * General Public License version 2 for more details (a copy is included | |
14 | * in the LICENSE file that accompanied this code). | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * version 2 along with this program; If not, see | |
18 | * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf | |
19 | * | |
20 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
21 | * CA 95054 USA or visit www.sun.com if you need additional information or | |
22 | * have any questions. | |
23 | * | |
24 | * GPL HEADER END | |
25 | */ | |
26 | /* | |
27 | * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. | |
28 | * Use is subject to license terms. | |
29 | * | |
30 | * Copyright (c) 2012, Intel Corporation. | |
31 | */ | |
32 | /* | |
33 | * This file is part of Lustre, http://www.lustre.org/ | |
34 | * Lustre is a trademark of Sun Microsystems, Inc. | |
35 | */ | |
36 | ||
37 | #ifndef _LUSTRE_CFG_H | |
38 | #define _LUSTRE_CFG_H | |
39 | ||
40 | /** \defgroup cfg cfg | |
41 | * | |
42 | * @{ | |
43 | */ | |
44 | ||
45 | /* | |
46 | * 1cf6 | |
47 | * lcfG | |
48 | */ | |
49 | #define LUSTRE_CFG_VERSION 0x1cf60001 | |
50 | #define LUSTRE_CFG_MAX_BUFCOUNT 8 | |
51 | ||
52 | #define LCFG_HDR_SIZE(count) \ | |
53 | cfs_size_round(offsetof (struct lustre_cfg, lcfg_buflens[(count)])) | |
54 | ||
55 | /** If the LCFG_REQUIRED bit is set in a configuration command, | |
56 | * then the client is required to understand this parameter | |
57 | * in order to mount the filesystem. If it does not understand | |
58 | * a REQUIRED command the client mount will fail. */ | |
59 | #define LCFG_REQUIRED 0x0001000 | |
60 | ||
61 | enum lcfg_command_type { | |
62 | LCFG_ATTACH = 0x00cf001, /**< create a new obd instance */ | |
63 | LCFG_DETACH = 0x00cf002, /**< destroy obd instance */ | |
64 | LCFG_SETUP = 0x00cf003, /**< call type-specific setup */ | |
65 | LCFG_CLEANUP = 0x00cf004, /**< call type-specific cleanup */ | |
66 | LCFG_ADD_UUID = 0x00cf005, /**< add a nid to a niduuid */ | |
67 | LCFG_DEL_UUID = 0x00cf006, /**< remove a nid from a niduuid */ | |
68 | LCFG_MOUNTOPT = 0x00cf007, /**< create a profile (mdc, osc) */ | |
69 | LCFG_DEL_MOUNTOPT = 0x00cf008, /**< destroy a profile */ | |
70 | LCFG_SET_TIMEOUT = 0x00cf009, /**< set obd_timeout */ | |
71 | LCFG_SET_UPCALL = 0x00cf00a, /**< deprecated */ | |
72 | LCFG_ADD_CONN = 0x00cf00b, /**< add a failover niduuid to an obd */ | |
73 | LCFG_DEL_CONN = 0x00cf00c, /**< remove a failover niduuid */ | |
74 | LCFG_LOV_ADD_OBD = 0x00cf00d, /**< add an osc to a lov */ | |
75 | LCFG_LOV_DEL_OBD = 0x00cf00e, /**< remove an osc from a lov */ | |
76 | LCFG_PARAM = 0x00cf00f, /**< set a proc parameter */ | |
77 | LCFG_MARKER = 0x00cf010, /**< metadata about next cfg rec */ | |
78 | LCFG_LOG_START = 0x00ce011, /**< mgc only, process a cfg log */ | |
79 | LCFG_LOG_END = 0x00ce012, /**< stop processing updates */ | |
80 | LCFG_LOV_ADD_INA = 0x00ce013, /**< like LOV_ADD_OBD, inactive */ | |
81 | LCFG_ADD_MDC = 0x00cf014, /**< add an mdc to a lmv */ | |
82 | LCFG_DEL_MDC = 0x00cf015, /**< remove an mdc from a lmv */ | |
83 | LCFG_SPTLRPC_CONF = 0x00ce016, /**< security */ | |
84 | LCFG_POOL_NEW = 0x00ce020, /**< create an ost pool name */ | |
85 | LCFG_POOL_ADD = 0x00ce021, /**< add an ost to a pool */ | |
86 | LCFG_POOL_REM = 0x00ce022, /**< remove an ost from a pool */ | |
87 | LCFG_POOL_DEL = 0x00ce023, /**< destroy an ost pool name */ | |
88 | LCFG_SET_LDLM_TIMEOUT = 0x00ce030, /**< set ldlm_timeout */ | |
89 | LCFG_PRE_CLEANUP = 0x00cf031, /**< call type-specific pre | |
90 | * cleanup cleanup */ | |
7d4bae45 AB |
91 | LCFG_SET_PARAM = 0x00ce032, /**< use set_param syntax to set |
92 | *a proc parameters */ | |
d7e09d03 PT |
93 | }; |
94 | ||
95 | struct lustre_cfg_bufs { | |
96 | void *lcfg_buf[LUSTRE_CFG_MAX_BUFCOUNT]; | |
97 | __u32 lcfg_buflen[LUSTRE_CFG_MAX_BUFCOUNT]; | |
98 | __u32 lcfg_bufcount; | |
99 | }; | |
100 | ||
101 | struct lustre_cfg { | |
102 | __u32 lcfg_version; | |
103 | __u32 lcfg_command; | |
104 | ||
105 | __u32 lcfg_num; | |
106 | __u32 lcfg_flags; | |
107 | __u64 lcfg_nid; | |
108 | __u32 lcfg_nal; /* not used any more */ | |
109 | ||
110 | __u32 lcfg_bufcount; | |
111 | __u32 lcfg_buflens[0]; | |
112 | }; | |
113 | ||
114 | enum cfg_record_type { | |
115 | PORTALS_CFG_TYPE = 1, | |
116 | LUSTRE_CFG_TYPE = 123, | |
117 | }; | |
118 | ||
119 | #define LUSTRE_CFG_BUFLEN(lcfg, idx) \ | |
120 | ((lcfg)->lcfg_bufcount <= (idx) \ | |
121 | ? 0 \ | |
122 | : (lcfg)->lcfg_buflens[(idx)]) | |
123 | ||
124 | static inline void lustre_cfg_bufs_set(struct lustre_cfg_bufs *bufs, | |
125 | __u32 index, | |
126 | void *buf, | |
127 | __u32 buflen) | |
128 | { | |
129 | if (index >= LUSTRE_CFG_MAX_BUFCOUNT) | |
130 | return; | |
131 | if (bufs == NULL) | |
132 | return; | |
133 | ||
134 | if (bufs->lcfg_bufcount <= index) | |
135 | bufs->lcfg_bufcount = index + 1; | |
136 | ||
137 | bufs->lcfg_buf[index] = buf; | |
138 | bufs->lcfg_buflen[index] = buflen; | |
139 | } | |
140 | ||
141 | static inline void lustre_cfg_bufs_set_string(struct lustre_cfg_bufs *bufs, | |
142 | __u32 index, | |
143 | char *str) | |
144 | { | |
145 | lustre_cfg_bufs_set(bufs, index, str, str ? strlen(str) + 1 : 0); | |
146 | } | |
147 | ||
148 | static inline void lustre_cfg_bufs_reset(struct lustre_cfg_bufs *bufs, char *name) | |
149 | { | |
150 | memset((bufs), 0, sizeof(*bufs)); | |
151 | if (name) | |
152 | lustre_cfg_bufs_set_string(bufs, 0, name); | |
153 | } | |
154 | ||
155 | static inline void *lustre_cfg_buf(struct lustre_cfg *lcfg, int index) | |
156 | { | |
157 | int i; | |
158 | int offset; | |
159 | int bufcount; | |
160 | LASSERT (lcfg != NULL); | |
161 | LASSERT (index >= 0); | |
162 | ||
163 | bufcount = lcfg->lcfg_bufcount; | |
164 | if (index >= bufcount) | |
165 | return NULL; | |
166 | ||
167 | offset = LCFG_HDR_SIZE(lcfg->lcfg_bufcount); | |
168 | for (i = 0; i < index; i++) | |
169 | offset += cfs_size_round(lcfg->lcfg_buflens[i]); | |
170 | return (char *)lcfg + offset; | |
171 | } | |
172 | ||
173 | static inline void lustre_cfg_bufs_init(struct lustre_cfg_bufs *bufs, | |
174 | struct lustre_cfg *lcfg) | |
175 | { | |
176 | int i; | |
177 | bufs->lcfg_bufcount = lcfg->lcfg_bufcount; | |
178 | for (i = 0; i < bufs->lcfg_bufcount; i++) { | |
179 | bufs->lcfg_buflen[i] = lcfg->lcfg_buflens[i]; | |
180 | bufs->lcfg_buf[i] = lustre_cfg_buf(lcfg, i); | |
181 | } | |
182 | } | |
183 | ||
184 | static inline char *lustre_cfg_string(struct lustre_cfg *lcfg, int index) | |
185 | { | |
186 | char *s; | |
187 | ||
188 | if (lcfg->lcfg_buflens[index] == 0) | |
189 | return NULL; | |
190 | ||
191 | s = lustre_cfg_buf(lcfg, index); | |
192 | if (s == NULL) | |
193 | return NULL; | |
194 | ||
195 | /* | |
196 | * make sure it's NULL terminated, even if this kills a char | |
197 | * of data. Try to use the padding first though. | |
198 | */ | |
199 | if (s[lcfg->lcfg_buflens[index] - 1] != '\0') { | |
200 | int last = min((int)lcfg->lcfg_buflens[index], | |
201 | cfs_size_round(lcfg->lcfg_buflens[index]) - 1); | |
202 | char lost = s[last]; | |
203 | s[last] = '\0'; | |
204 | if (lost != '\0') { | |
205 | CWARN("Truncated buf %d to '%s' (lost '%c'...)\n", | |
206 | index, s, lost); | |
207 | } | |
208 | } | |
209 | return s; | |
210 | } | |
211 | ||
212 | static inline int lustre_cfg_len(__u32 bufcount, __u32 *buflens) | |
213 | { | |
214 | int i; | |
215 | int len; | |
d7e09d03 PT |
216 | |
217 | len = LCFG_HDR_SIZE(bufcount); | |
218 | for (i = 0; i < bufcount; i++) | |
219 | len += cfs_size_round(buflens[i]); | |
220 | ||
0a3bdb00 | 221 | return cfs_size_round(len); |
d7e09d03 PT |
222 | } |
223 | ||
224 | ||
1accaadf | 225 | #include "obd_support.h" |
d7e09d03 PT |
226 | |
227 | static inline struct lustre_cfg *lustre_cfg_new(int cmd, | |
228 | struct lustre_cfg_bufs *bufs) | |
229 | { | |
230 | struct lustre_cfg *lcfg; | |
231 | char *ptr; | |
232 | int i; | |
233 | ||
d7e09d03 PT |
234 | OBD_ALLOC(lcfg, lustre_cfg_len(bufs->lcfg_bufcount, |
235 | bufs->lcfg_buflen)); | |
236 | if (!lcfg) | |
0a3bdb00 | 237 | return ERR_PTR(-ENOMEM); |
d7e09d03 PT |
238 | |
239 | lcfg->lcfg_version = LUSTRE_CFG_VERSION; | |
240 | lcfg->lcfg_command = cmd; | |
241 | lcfg->lcfg_bufcount = bufs->lcfg_bufcount; | |
242 | ||
243 | ptr = (char *)lcfg + LCFG_HDR_SIZE(lcfg->lcfg_bufcount); | |
244 | for (i = 0; i < lcfg->lcfg_bufcount; i++) { | |
245 | lcfg->lcfg_buflens[i] = bufs->lcfg_buflen[i]; | |
246 | LOGL((char *)bufs->lcfg_buf[i], bufs->lcfg_buflen[i], ptr); | |
247 | } | |
0a3bdb00 | 248 | return lcfg; |
d7e09d03 PT |
249 | } |
250 | ||
251 | static inline void lustre_cfg_free(struct lustre_cfg *lcfg) | |
252 | { | |
253 | int len; | |
254 | ||
255 | len = lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens); | |
256 | ||
257 | OBD_FREE(lcfg, len); | |
d7e09d03 PT |
258 | return; |
259 | } | |
260 | ||
261 | static inline int lustre_cfg_sanity_check(void *buf, int len) | |
262 | { | |
263 | struct lustre_cfg *lcfg = (struct lustre_cfg *)buf; | |
29aaf496 | 264 | |
d7e09d03 | 265 | if (!lcfg) |
0a3bdb00 | 266 | return -EINVAL; |
d7e09d03 PT |
267 | |
268 | /* check that the first bits of the struct are valid */ | |
269 | if (len < LCFG_HDR_SIZE(0)) | |
0a3bdb00 | 270 | return -EINVAL; |
d7e09d03 PT |
271 | |
272 | if (lcfg->lcfg_version != LUSTRE_CFG_VERSION) | |
0a3bdb00 | 273 | return -EINVAL; |
d7e09d03 PT |
274 | |
275 | if (lcfg->lcfg_bufcount >= LUSTRE_CFG_MAX_BUFCOUNT) | |
0a3bdb00 | 276 | return -EINVAL; |
d7e09d03 PT |
277 | |
278 | /* check that the buflens are valid */ | |
279 | if (len < LCFG_HDR_SIZE(lcfg->lcfg_bufcount)) | |
0a3bdb00 | 280 | return -EINVAL; |
d7e09d03 PT |
281 | |
282 | /* make sure all the pointers point inside the data */ | |
283 | if (len < lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens)) | |
0a3bdb00 | 284 | return -EINVAL; |
d7e09d03 | 285 | |
0a3bdb00 | 286 | return 0; |
d7e09d03 PT |
287 | } |
288 | ||
1accaadf | 289 | #include "lustre/lustre_user.h" |
d7e09d03 | 290 | |
d7e09d03 PT |
291 | /** @} cfg */ |
292 | ||
293 | #endif // _LUSTRE_CFG_H |