File: | xlators/mgmt/glusterd/src/glusterd-quota.c |
Location: | line 325, column 9 |
Description: | Value stored to 'j' is never read |
1 | /* |
2 | Copyright (c) 2011-2012 Red Hat, Inc. <http://www.redhat.com> |
3 | This file is part of GlusterFS. |
4 | |
5 | This file is licensed to you under your choice of the GNU Lesser |
6 | General Public License, version 3 or any later version (LGPLv3 or |
7 | later), or the GNU General Public License, version 2 (GPLv2), in all |
8 | cases as published by the Free Software Foundation. |
9 | */ |
10 | #ifndef _CONFIG_H |
11 | #define _CONFIG_H |
12 | #include "config.h" |
13 | #endif |
14 | |
15 | #include "common-utils.h" |
16 | #include "cli1-xdr.h" |
17 | #include "xdr-generic.h" |
18 | #include "glusterd.h" |
19 | #include "glusterd-op-sm.h" |
20 | #include "glusterd-store.h" |
21 | #include "glusterd-utils.h" |
22 | #include "glusterd-volgen.h" |
23 | #include "run.h" |
24 | |
25 | #include <sys/wait.h> |
26 | |
27 | int |
28 | __glusterd_handle_quota (rpcsvc_request_t *req) |
29 | { |
30 | int32_t ret = -1; |
31 | gf_cli_req cli_req = {{0,}}; |
32 | dict_t *dict = NULL((void*)0); |
33 | glusterd_op_t cli_op = GD_OP_QUOTA; |
34 | char operation[256] = {0, }; |
35 | char *volname = NULL((void*)0); |
36 | int32_t type = 0; |
37 | char msg[2048] = {0,}; |
38 | xlator_t *this = NULL((void*)0); |
39 | |
40 | GF_ASSERT (req)do { if (!(req)) { do { do { if (0) printf ("Assertion failed: " "req"); } while (0); _gf_log_callingfn ("", "glusterd-quota.c" , __FUNCTION__, 40, GF_LOG_ERROR, "Assertion failed: " "req") ; } while (0); } } while (0); |
41 | this = THIS(*__glusterfs_this_location()); |
42 | GF_ASSERT (this)do { if (!(this)) { do { do { if (0) printf ("Assertion failed: " "this"); } while (0); _gf_log_callingfn ("", "glusterd-quota.c" , __FUNCTION__, 42, GF_LOG_ERROR, "Assertion failed: " "this" ); } while (0); } } while (0); |
43 | |
44 | ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); |
45 | if (ret < 0) { |
46 | //failed to decode msg; |
47 | req->rpc_err = GARBAGE_ARGS; |
48 | goto out; |
49 | } |
50 | |
51 | if (cli_req.dict.dict_len) { |
52 | /* Unserialize the dictionary */ |
53 | dict = dict_new (); |
54 | |
55 | ret = dict_unserialize (cli_req.dict.dict_val, |
56 | cli_req.dict.dict_len, |
57 | &dict); |
58 | if (ret < 0) { |
59 | gf_log (this->name, GF_LOG_ERROR, "failed to "do { do { if (0) printf ("failed to " "unserialize req-buffer to dictionary" ); } while (0); _gf_log (this->name, "glusterd-quota.c", __FUNCTION__ , 60, GF_LOG_ERROR, "failed to " "unserialize req-buffer to dictionary" ); } while (0) |
60 | "unserialize req-buffer to dictionary")do { do { if (0) printf ("failed to " "unserialize req-buffer to dictionary" ); } while (0); _gf_log (this->name, "glusterd-quota.c", __FUNCTION__ , 60, GF_LOG_ERROR, "failed to " "unserialize req-buffer to dictionary" ); } while (0); |
61 | snprintf (msg, sizeof (msg), "Unable to decode the " |
62 | "command"); |
63 | goto out; |
64 | } else { |
65 | dict->extra_stdfree = cli_req.dict.dict_val; |
66 | } |
67 | } |
68 | |
69 | ret = dict_get_str (dict, "volname", &volname); |
70 | if (ret) { |
71 | snprintf (msg, sizeof (msg), "Unable to get volume name"); |
72 | gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name, "do { do { if (0) printf ("Unable to get volume name, " "while handling quota command" ); } while (0); _gf_log (this->name, "glusterd-quota.c", __FUNCTION__ , 73, GF_LOG_ERROR, "Unable to get volume name, " "while handling quota command" ); } while (0) |
73 | "while handling quota command")do { do { if (0) printf ("Unable to get volume name, " "while handling quota command" ); } while (0); _gf_log (this->name, "glusterd-quota.c", __FUNCTION__ , 73, GF_LOG_ERROR, "Unable to get volume name, " "while handling quota command" ); } while (0); |
74 | goto out; |
75 | } |
76 | |
77 | ret = dict_get_int32 (dict, "type", &type); |
78 | if (ret) { |
79 | snprintf (msg, sizeof (msg), "Unable to get type of command"); |
80 | gf_log (this->name, GF_LOG_ERROR, "Unable to get type of cmd, "do { do { if (0) printf ("Unable to get type of cmd, " "while handling quota command" ); } while (0); _gf_log (this->name, "glusterd-quota.c", __FUNCTION__ , 81, GF_LOG_ERROR, "Unable to get type of cmd, " "while handling quota command" ); } while (0) |
81 | "while handling quota command")do { do { if (0) printf ("Unable to get type of cmd, " "while handling quota command" ); } while (0); _gf_log (this->name, "glusterd-quota.c", __FUNCTION__ , 81, GF_LOG_ERROR, "Unable to get type of cmd, " "while handling quota command" ); } while (0); |
82 | goto out; |
83 | } |
84 | |
85 | switch (type) { |
86 | case GF_QUOTA_OPTION_TYPE_ENABLE: |
87 | strncpy (operation, "enable", sizeof (operation)); |
88 | break; |
89 | |
90 | case GF_QUOTA_OPTION_TYPE_DISABLE: |
91 | strncpy (operation, "disable", sizeof (operation)); |
92 | break; |
93 | |
94 | case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE: |
95 | strncpy (operation, "limit-usage", sizeof (operation)); |
96 | break; |
97 | |
98 | case GF_QUOTA_OPTION_TYPE_REMOVE: |
99 | strncpy (operation, "remove", sizeof (operation)); |
100 | break; |
101 | } |
102 | ret = glusterd_op_begin_synctask (req, GD_OP_QUOTA, dict); |
103 | |
104 | out: |
105 | if (ret) { |
106 | if (msg[0] == '\0') |
107 | snprintf (msg, sizeof (msg), "Operation failed"); |
108 | ret = glusterd_op_send_cli_response (cli_op, ret, 0, req, |
109 | dict, msg); |
110 | } |
111 | |
112 | return ret; |
113 | } |
114 | |
115 | int |
116 | glusterd_handle_quota (rpcsvc_request_t *req) |
117 | { |
118 | return glusterd_big_locked_handler (req, __glusterd_handle_quota); |
119 | } |
120 | |
121 | int32_t |
122 | glusterd_check_if_quota_trans_enabled (glusterd_volinfo_t *volinfo) |
123 | { |
124 | int32_t ret = 0; |
125 | int flag = _gf_false; |
126 | |
127 | flag = glusterd_volinfo_get_boolean (volinfo, VKEY_FEATURES_QUOTA"features.quota"); |
128 | if (flag == -1) { |
129 | gf_log ("", GF_LOG_ERROR, "failed to get the quota status")do { do { if (0) printf ("failed to get the quota status"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 129 , GF_LOG_ERROR, "failed to get the quota status"); } while (0 ); |
130 | ret = -1; |
131 | goto out; |
132 | } |
133 | |
134 | if (flag == _gf_false) { |
135 | gf_log ("", GF_LOG_ERROR, "first enable the quota translator")do { do { if (0) printf ("first enable the quota translator") ; } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 135, GF_LOG_ERROR, "first enable the quota translator"); } while (0); |
136 | ret = -1; |
137 | goto out; |
138 | } |
139 | ret = 0; |
140 | out: |
141 | return ret; |
142 | } |
143 | |
144 | /* At the end of the function, the variable found will be set |
145 | * to true if the path to be removed was present in the limit-list, |
146 | * else will be false. |
147 | */ |
148 | int32_t |
149 | _glusterd_quota_remove_limits (char **quota_limits, char *path, |
150 | gf_boolean_t *found) |
151 | { |
152 | int ret = 0; |
153 | int i = 0; |
154 | int size = 0; |
155 | int len = 0; |
156 | int pathlen = 0; |
157 | int skiplen = 0; |
158 | int flag = 0; |
159 | char *limits = NULL((void*)0); |
160 | char *qlimits = NULL((void*)0); |
161 | |
162 | if (found != NULL((void*)0)) |
163 | *found = _gf_false; |
164 | |
165 | if (*quota_limits == NULL((void*)0)) |
166 | return -1; |
167 | |
168 | qlimits = *quota_limits; |
169 | |
170 | pathlen = strlen (path); |
171 | |
172 | len = strlen (qlimits); |
173 | |
174 | limits = GF_CALLOC (len + 1, sizeof (char), gf_gld_mt_char)__gf_calloc (len + 1, sizeof (char), gf_gld_mt_char); |
175 | if (!limits) |
176 | return -1; |
177 | |
178 | while (i < len) { |
179 | if (!memcmp ((void *) &qlimits [i], (void *)path, pathlen)) |
180 | if (qlimits [i + pathlen] == ':') { |
181 | flag = 1; |
182 | if (found != NULL((void*)0)) |
183 | *found = _gf_true; |
184 | } |
185 | |
186 | while (qlimits [i + size] != ',' && |
187 | qlimits [i + size] != '\0') |
188 | size++; |
189 | |
190 | if (!flag) { |
191 | memcpy ((void *) &limits [i], (void *) &qlimits [i], size + 1); |
192 | } else { |
193 | skiplen = size + 1; |
194 | size = len - i - size; |
195 | memcpy ((void *) &limits [i], (void *) &qlimits [i + skiplen], size); |
196 | break; |
197 | } |
198 | |
199 | i += size + 1; |
200 | size = 0; |
201 | } |
202 | |
203 | if (!flag) { |
204 | ret = 1; |
205 | } else { |
206 | len = strlen (limits); |
207 | |
208 | if (len == 0) { |
209 | GF_FREE (qlimits)__gf_free (qlimits); |
210 | |
211 | *quota_limits = NULL((void*)0); |
212 | |
213 | goto out; |
214 | } |
215 | |
216 | if (limits[len - 1] == ',') { |
217 | limits[len - 1] = '\0'; |
218 | len --; |
219 | } |
220 | |
221 | GF_FREE (qlimits)__gf_free (qlimits); |
222 | |
223 | qlimits = GF_CALLOC (len + 1, sizeof (char), gf_gld_mt_char)__gf_calloc (len + 1, sizeof (char), gf_gld_mt_char); |
224 | |
225 | if (!qlimits) { |
226 | ret = -1; |
227 | goto out; |
228 | } |
229 | |
230 | memcpy ((void *) qlimits, (void *) limits, len + 1); |
231 | |
232 | *quota_limits = qlimits; |
233 | |
234 | ret = 0; |
235 | } |
236 | |
237 | out: |
238 | GF_FREE (limits)__gf_free (limits); |
239 | |
240 | return ret; |
241 | } |
242 | |
243 | int32_t |
244 | glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname) |
245 | { |
246 | pid_t pid; |
247 | int32_t ret = 0; |
248 | int status = 0; |
249 | char mountdir[] = "/tmp/mntXXXXXX"; |
250 | runner_t runner = {0}; |
251 | |
252 | if (mkdtemp (mountdir) == NULL((void*)0)) { |
253 | gf_log ("glusterd", GF_LOG_DEBUG,do { do { if (0) printf ("failed to create a temporary mount directory" ); } while (0); _gf_log ("glusterd", "glusterd-quota.c", __FUNCTION__ , 254, GF_LOG_DEBUG, "failed to create a temporary mount directory" ); } while (0) |
254 | "failed to create a temporary mount directory")do { do { if (0) printf ("failed to create a temporary mount directory" ); } while (0); _gf_log ("glusterd", "glusterd-quota.c", __FUNCTION__ , 254, GF_LOG_DEBUG, "failed to create a temporary mount directory" ); } while (0); |
255 | ret = -1; |
256 | goto out; |
257 | } |
258 | |
259 | runinit (&runner); |
260 | runner_add_args (&runner, SBIN_DIR"/usr/local/sbin""/glusterfs", |
261 | "-s", "localhost", |
262 | "--volfile-id", volname, |
263 | "-l", DEFAULT_LOG_FILE_DIRECTORY"/usr/local/var" "/log/glusterfs""/quota-crawl.log", |
264 | mountdir, NULL((void*)0)); |
265 | |
266 | synclock_unlock (&priv->big_lock); |
267 | ret = runner_run_reuse (&runner); |
268 | synclock_lock (&priv->big_lock); |
269 | if (ret == -1) { |
270 | runner_log (&runner, "glusterd", GF_LOG_DEBUG, "command failed"); |
271 | runner_end (&runner); |
272 | goto out; |
273 | } |
274 | runner_end (&runner); |
275 | |
276 | if ((pid = fork ()) < 0) { |
277 | gf_log ("glusterd", GF_LOG_WARNING, "fork from parent failed")do { do { if (0) printf ("fork from parent failed"); } while ( 0); _gf_log ("glusterd", "glusterd-quota.c", __FUNCTION__, 277 , GF_LOG_WARNING, "fork from parent failed"); } while (0); |
278 | ret = -1; |
279 | goto out; |
280 | } else if (pid == 0) {//first child |
281 | /* fork one more to not hold back main process on |
282 | * blocking call below |
283 | */ |
284 | pid = fork (); |
285 | if (pid) |
286 | _exit (pid > 0 ? EXIT_SUCCESS0 : EXIT_FAILURE1); |
287 | |
288 | ret = chdir (mountdir); |
289 | if (ret == -1) { |
290 | gf_log ("glusterd", GF_LOG_WARNING, "chdir %s failed, "do { do { if (0) printf ("chdir %s failed, " "reason: %s", mountdir , strerror ((*__errno_location ()))); } while (0); _gf_log ("glusterd" , "glusterd-quota.c", __FUNCTION__, 291, GF_LOG_WARNING, "chdir %s failed, " "reason: %s", mountdir, strerror ((*__errno_location ()))); } while (0) |
291 | "reason: %s", mountdir, strerror (errno))do { do { if (0) printf ("chdir %s failed, " "reason: %s", mountdir , strerror ((*__errno_location ()))); } while (0); _gf_log ("glusterd" , "glusterd-quota.c", __FUNCTION__, 291, GF_LOG_WARNING, "chdir %s failed, " "reason: %s", mountdir, strerror ((*__errno_location ()))); } while (0); |
292 | exit (EXIT_FAILURE1); |
293 | } |
294 | runinit (&runner); |
295 | runner_add_args (&runner, "/usr/bin/find", "find", ".", NULL((void*)0)); |
296 | if (runner_start (&runner) == -1) |
297 | _exit (EXIT_FAILURE1); |
298 | |
299 | #ifndef GF_LINUX_HOST_OS1 |
300 | runner_end (&runner); /* blocks in waitpid */ |
301 | runcmd ("umount", mountdir, NULL((void*)0)); |
302 | #else |
303 | runcmd ("umount", "-l", mountdir, NULL((void*)0)); |
304 | #endif |
305 | rmdir (mountdir); |
306 | _exit (EXIT_SUCCESS0); |
307 | } |
308 | ret = (waitpid (pid, &status, 0) == pid && |
309 | WIFEXITED (status)((((__extension__ (((union { __typeof(status) __in; int __i; } ) { .__in = (status) }).__i))) & 0x7f) == 0) && WEXITSTATUS (status)((((__extension__ (((union { __typeof(status) __in; int __i; } ) { .__in = (status) }).__i))) & 0xff00) >> 8) == EXIT_SUCCESS0) ? 0 : -1; |
310 | |
311 | out: |
312 | return ret; |
313 | } |
314 | |
315 | char * |
316 | glusterd_quota_get_limit_value (char *quota_limits, char *path) |
317 | { |
318 | int32_t i, j, k, l, len; |
319 | int32_t pat_len, diff; |
320 | char *ret_str = NULL((void*)0); |
321 | |
322 | len = strlen (quota_limits); |
323 | pat_len = strlen (path); |
324 | i = 0; |
325 | j = 0; |
Value stored to 'j' is never read | |
326 | |
327 | while (i < len) { |
328 | j = i; |
329 | k = 0; |
330 | while (path [k] == quota_limits [j]) { |
331 | j++; |
332 | k++; |
333 | } |
334 | |
335 | l = j; |
336 | |
337 | while (quota_limits [j] != ',' && |
338 | quota_limits [j] != '\0') |
339 | j++; |
340 | |
341 | if (quota_limits [l] == ':' && pat_len == (l - i)) { |
342 | diff = j - i; |
343 | ret_str = GF_CALLOC (diff + 1, sizeof (char),__gf_calloc (diff + 1, sizeof (char), gf_gld_mt_char) |
344 | gf_gld_mt_char)__gf_calloc (diff + 1, sizeof (char), gf_gld_mt_char); |
345 | |
346 | strncpy (ret_str, "a_limits [i], diff); |
347 | |
348 | break; |
349 | } |
350 | i = ++j; //skip ',' |
351 | } |
352 | |
353 | return ret_str; |
354 | } |
355 | |
356 | char* |
357 | _glusterd_quota_get_limit_usages (glusterd_volinfo_t *volinfo, |
358 | char *path, char **op_errstr) |
359 | { |
360 | int32_t ret = 0; |
361 | char *quota_limits = NULL((void*)0); |
362 | char *ret_str = NULL((void*)0); |
363 | |
364 | if (volinfo == NULL((void*)0)) |
365 | return NULL((void*)0); |
366 | |
367 | ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE"features.limit-usage", |
368 | "a_limits); |
369 | if (ret) |
370 | return NULL((void*)0); |
371 | if (quota_limits == NULL((void*)0)) { |
372 | ret_str = NULL((void*)0); |
373 | *op_errstr = gf_strdup ("Limit not set on any directory"); |
374 | } else if (path == NULL((void*)0)) |
375 | ret_str = gf_strdup (quota_limits); |
376 | else |
377 | ret_str = glusterd_quota_get_limit_value (quota_limits, path); |
378 | |
379 | return ret_str; |
380 | } |
381 | |
382 | int32_t |
383 | glusterd_quota_get_limit_usages (glusterd_conf_t *priv, |
384 | glusterd_volinfo_t *volinfo, |
385 | char *volname, |
386 | dict_t *dict, |
387 | char **op_errstr, |
388 | dict_t *rsp_dict) |
389 | { |
390 | int32_t i = 0; |
391 | int32_t ret = 0; |
392 | int32_t count = 0; |
393 | char *path = NULL((void*)0); |
394 | char cmd_str [1024] = {0, }; |
395 | char *ret_str = NULL((void*)0); |
396 | |
397 | if (rsp_dict == NULL((void*)0)) |
398 | return 0; |
399 | |
400 | ret = dict_get_int32 (dict, "count", &count); |
401 | if (ret < 0) |
402 | goto out; |
403 | |
404 | if (count == 0) { |
405 | ret_str = _glusterd_quota_get_limit_usages (volinfo, NULL((void*)0), |
406 | op_errstr); |
407 | } else { |
408 | i = 0; |
409 | while (count--) { |
410 | snprintf (cmd_str, 1024, "path%d", i++); |
411 | |
412 | ret = dict_get_str (dict, cmd_str, &path); |
413 | if (ret < 0) |
414 | goto out; |
415 | |
416 | ret_str = _glusterd_quota_get_limit_usages (volinfo, path, op_errstr); |
417 | } |
418 | } |
419 | |
420 | if (ret_str) { |
421 | ret = dict_set_dynstr (rsp_dict, "limit_list", ret_str); |
422 | } |
423 | out: |
424 | return ret; |
425 | } |
426 | |
427 | int32_t |
428 | glusterd_quota_enable (glusterd_volinfo_t *volinfo, char **op_errstr, |
429 | gf_boolean_t *crawl) |
430 | { |
431 | int32_t ret = -1; |
432 | char *quota_status = NULL((void*)0); |
433 | |
434 | GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out)do { if (!volinfo) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "volinfo"); } while (0); _gf_log_callingfn ("glusterd", "glusterd-quota.c", __FUNCTION__, 434, GF_LOG_ERROR , "invalid argument: " "volinfo"); } while (0); goto out; } } while (0); |
435 | GF_VALIDATE_OR_GOTO ("glusterd", crawl, out)do { if (!crawl) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "crawl"); } while (0); _gf_log_callingfn ("glusterd", "glusterd-quota.c", __FUNCTION__, 435, GF_LOG_ERROR , "invalid argument: " "crawl"); } while (0); goto out; } } while (0); |
436 | GF_VALIDATE_OR_GOTO ("glusterd", op_errstr, out)do { if (!op_errstr) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "op_errstr"); } while (0 ); _gf_log_callingfn ("glusterd", "glusterd-quota.c", __FUNCTION__ , 436, GF_LOG_ERROR, "invalid argument: " "op_errstr"); } while (0); goto out; } } while (0); |
437 | |
438 | if (glusterd_is_volume_started (volinfo) == 0) { |
439 | *op_errstr = gf_strdup ("Volume is stopped, start volume " |
440 | "to enable quota."); |
441 | goto out; |
442 | } |
443 | |
444 | ret = glusterd_check_if_quota_trans_enabled (volinfo); |
445 | if (ret == 0) { |
446 | *op_errstr = gf_strdup ("Quota is already enabled"); |
447 | goto out; |
448 | } |
449 | |
450 | quota_status = gf_strdup ("on"); |
451 | if (!quota_status) { |
452 | gf_log ("", GF_LOG_ERROR, "memory allocation failed")do { do { if (0) printf ("memory allocation failed"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 452, GF_LOG_ERROR , "memory allocation failed"); } while (0); |
453 | *op_errstr = gf_strdup ("Enabling quota has been unsuccessful"); |
454 | goto out; |
455 | } |
456 | |
457 | ret = dict_set_dynstr (volinfo->dict, VKEY_FEATURES_QUOTA"features.quota", quota_status); |
458 | if (ret) { |
459 | gf_log ("", GF_LOG_ERROR, "dict set failed")do { do { if (0) printf ("dict set failed"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 459, GF_LOG_ERROR, "dict set failed" ); } while (0); |
460 | *op_errstr = gf_strdup ("Enabling quota has been unsuccessful"); |
461 | goto out; |
462 | } |
463 | |
464 | *op_errstr = gf_strdup ("Enabling quota has been successful"); |
465 | |
466 | *crawl = _gf_true; |
467 | |
468 | ret = 0; |
469 | out: |
470 | return ret; |
471 | } |
472 | |
473 | int32_t |
474 | glusterd_quota_disable (glusterd_volinfo_t *volinfo, char **op_errstr) |
475 | { |
476 | int32_t ret = -1; |
477 | char *quota_status = NULL((void*)0), *quota_limits = NULL((void*)0); |
478 | |
479 | GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out)do { if (!volinfo) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "volinfo"); } while (0); _gf_log_callingfn ("glusterd", "glusterd-quota.c", __FUNCTION__, 479, GF_LOG_ERROR , "invalid argument: " "volinfo"); } while (0); goto out; } } while (0); |
480 | GF_VALIDATE_OR_GOTO ("glusterd", op_errstr, out)do { if (!op_errstr) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "op_errstr"); } while (0 ); _gf_log_callingfn ("glusterd", "glusterd-quota.c", __FUNCTION__ , 480, GF_LOG_ERROR, "invalid argument: " "op_errstr"); } while (0); goto out; } } while (0); |
481 | |
482 | ret = glusterd_check_if_quota_trans_enabled (volinfo); |
483 | if (ret == -1) { |
484 | *op_errstr = gf_strdup ("Quota is already disabled"); |
485 | goto out; |
486 | } |
487 | |
488 | quota_status = gf_strdup ("off"); |
489 | if (!quota_status) { |
490 | gf_log ("", GF_LOG_ERROR, "memory allocation failed")do { do { if (0) printf ("memory allocation failed"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 490, GF_LOG_ERROR , "memory allocation failed"); } while (0); |
491 | *op_errstr = gf_strdup ("Disabling quota has been unsuccessful"); |
492 | goto out; |
493 | } |
494 | |
495 | ret = dict_set_dynstr (volinfo->dict, VKEY_FEATURES_QUOTA"features.quota", quota_status); |
496 | if (ret) { |
497 | gf_log ("", GF_LOG_ERROR, "dict set failed")do { do { if (0) printf ("dict set failed"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 497, GF_LOG_ERROR, "dict set failed" ); } while (0); |
498 | *op_errstr = gf_strdup ("Disabling quota has been unsuccessful"); |
499 | goto out; |
500 | } |
501 | |
502 | *op_errstr = gf_strdup ("Disabling quota has been successful"); |
503 | |
504 | ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE"features.limit-usage", |
505 | "a_limits); |
506 | if (ret) { |
507 | gf_log ("", GF_LOG_WARNING, "failed to get the quota limits")do { do { if (0) printf ("failed to get the quota limits"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 507 , GF_LOG_WARNING, "failed to get the quota limits"); } while ( 0); |
508 | } else { |
509 | GF_FREE (quota_limits)__gf_free (quota_limits); |
510 | } |
511 | |
512 | dict_del (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE"features.limit-usage"); |
513 | |
514 | out: |
515 | return ret; |
516 | } |
517 | |
518 | int32_t |
519 | glusterd_quota_limit_usage (glusterd_volinfo_t *volinfo, dict_t *dict, char **op_errstr) |
520 | { |
521 | int32_t ret = -1; |
522 | char *path = NULL((void*)0); |
523 | char *limit = NULL((void*)0); |
524 | char *value = NULL((void*)0); |
525 | char msg [1024] = {0,}; |
526 | char *quota_limits = NULL((void*)0); |
527 | |
528 | GF_VALIDATE_OR_GOTO ("glusterd", dict, out)do { if (!dict) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "dict"); } while (0); _gf_log_callingfn ("glusterd", "glusterd-quota.c", __FUNCTION__, 528, GF_LOG_ERROR , "invalid argument: " "dict"); } while (0); goto out; } } while (0); |
529 | GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out)do { if (!volinfo) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "volinfo"); } while (0); _gf_log_callingfn ("glusterd", "glusterd-quota.c", __FUNCTION__, 529, GF_LOG_ERROR , "invalid argument: " "volinfo"); } while (0); goto out; } } while (0); |
530 | GF_VALIDATE_OR_GOTO ("glusterd", op_errstr, out)do { if (!op_errstr) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "op_errstr"); } while (0 ); _gf_log_callingfn ("glusterd", "glusterd-quota.c", __FUNCTION__ , 530, GF_LOG_ERROR, "invalid argument: " "op_errstr"); } while (0); goto out; } } while (0); |
531 | |
532 | ret = glusterd_check_if_quota_trans_enabled (volinfo); |
533 | if (ret == -1) { |
534 | *op_errstr = gf_strdup ("Quota is disabled, please enable " |
535 | "quota"); |
536 | goto out; |
537 | } |
538 | |
539 | ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE"features.limit-usage", |
540 | "a_limits); |
541 | if (ret) { |
542 | gf_log ("", GF_LOG_ERROR, "failed to get the quota limits")do { do { if (0) printf ("failed to get the quota limits"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 542 , GF_LOG_ERROR, "failed to get the quota limits"); } while (0 ); |
543 | *op_errstr = gf_strdup ("failed to set limit"); |
544 | goto out; |
545 | } |
546 | |
547 | ret = dict_get_str (dict, "path", &path); |
548 | if (ret) { |
549 | gf_log ("", GF_LOG_ERROR, "Unable to fetch quota limits" )do { do { if (0) printf ("Unable to fetch quota limits"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 549, GF_LOG_ERROR , "Unable to fetch quota limits"); } while (0); |
550 | *op_errstr = gf_strdup ("failed to set limit"); |
551 | goto out; |
552 | } |
553 | |
554 | ret = dict_get_str (dict, "limit", &limit); |
555 | if (ret) { |
556 | gf_log ("", GF_LOG_ERROR, "Unable to fetch quota limits" )do { do { if (0) printf ("Unable to fetch quota limits"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 556, GF_LOG_ERROR , "Unable to fetch quota limits"); } while (0); |
557 | *op_errstr = gf_strdup ("failed to set limit"); |
558 | goto out; |
559 | } |
560 | |
561 | if (quota_limits) { |
562 | ret = _glusterd_quota_remove_limits ("a_limits, path, NULL((void*)0)); |
563 | if (ret == -1) { |
564 | gf_log ("", GF_LOG_ERROR, "Unable to allocate memory")do { do { if (0) printf ("Unable to allocate memory"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 564, GF_LOG_ERROR , "Unable to allocate memory"); } while (0); |
565 | *op_errstr = gf_strdup ("failed to set limit"); |
566 | goto out; |
567 | } |
568 | } |
569 | |
570 | if (quota_limits == NULL((void*)0)) { |
571 | ret = gf_asprintf (&value, "%s:%s", path, limit); |
572 | if (ret == -1) { |
573 | gf_log ("", GF_LOG_ERROR, "Unable to allocate memory")do { do { if (0) printf ("Unable to allocate memory"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 573, GF_LOG_ERROR , "Unable to allocate memory"); } while (0); |
574 | *op_errstr = gf_strdup ("failed to set limit"); |
575 | goto out; |
576 | } |
577 | } else { |
578 | ret = gf_asprintf (&value, "%s,%s:%s", |
579 | quota_limits, path, limit); |
580 | if (ret == -1) { |
581 | gf_log ("", GF_LOG_ERROR, "Unable to allocate memory")do { do { if (0) printf ("Unable to allocate memory"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 581, GF_LOG_ERROR , "Unable to allocate memory"); } while (0); |
582 | *op_errstr = gf_strdup ("failed to set limit"); |
583 | goto out; |
584 | } |
585 | |
586 | GF_FREE (quota_limits)__gf_free (quota_limits); |
587 | } |
588 | |
589 | quota_limits = value; |
590 | |
591 | ret = dict_set_str (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE"features.limit-usage", |
592 | quota_limits); |
593 | if (ret) { |
594 | gf_log ("", GF_LOG_ERROR, "Unable to set quota limits" )do { do { if (0) printf ("Unable to set quota limits"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 594, GF_LOG_ERROR , "Unable to set quota limits"); } while (0); |
595 | *op_errstr = gf_strdup ("failed to set limit"); |
596 | goto out; |
597 | } |
598 | snprintf (msg, 1024, "limit set on %s", path); |
599 | *op_errstr = gf_strdup (msg); |
600 | |
601 | ret = 0; |
602 | out: |
603 | return ret; |
604 | } |
605 | |
606 | int32_t |
607 | glusterd_quota_remove_limits (glusterd_volinfo_t *volinfo, dict_t *dict, char **op_errstr) |
608 | { |
609 | int32_t ret = -1; |
610 | char str [PATH_MAX4096 + 1024] = {0,}; |
611 | char *quota_limits = NULL((void*)0); |
612 | char *path = NULL((void*)0); |
613 | gf_boolean_t flag = _gf_false; |
614 | |
615 | GF_VALIDATE_OR_GOTO ("glusterd", dict, out)do { if (!dict) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "dict"); } while (0); _gf_log_callingfn ("glusterd", "glusterd-quota.c", __FUNCTION__, 615, GF_LOG_ERROR , "invalid argument: " "dict"); } while (0); goto out; } } while (0); |
616 | GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out)do { if (!volinfo) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "volinfo"); } while (0); _gf_log_callingfn ("glusterd", "glusterd-quota.c", __FUNCTION__, 616, GF_LOG_ERROR , "invalid argument: " "volinfo"); } while (0); goto out; } } while (0); |
617 | GF_VALIDATE_OR_GOTO ("glusterd", op_errstr, out)do { if (!op_errstr) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "op_errstr"); } while (0 ); _gf_log_callingfn ("glusterd", "glusterd-quota.c", __FUNCTION__ , 617, GF_LOG_ERROR, "invalid argument: " "op_errstr"); } while (0); goto out; } } while (0); |
618 | |
619 | ret = glusterd_check_if_quota_trans_enabled (volinfo); |
620 | if (ret == -1) { |
621 | *op_errstr = gf_strdup ("Quota is disabled, please enable quota"); |
622 | goto out; |
623 | } |
624 | |
625 | ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE"features.limit-usage", |
626 | "a_limits); |
627 | if (ret) { |
628 | gf_log ("", GF_LOG_ERROR, "failed to get the quota limits")do { do { if (0) printf ("failed to get the quota limits"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 628 , GF_LOG_ERROR, "failed to get the quota limits"); } while (0 ); |
629 | goto out; |
630 | } |
631 | |
632 | ret = dict_get_str (dict, "path", &path); |
633 | if (ret) { |
634 | gf_log ("", GF_LOG_ERROR, "Unable to fetch quota limits" )do { do { if (0) printf ("Unable to fetch quota limits"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 634, GF_LOG_ERROR , "Unable to fetch quota limits"); } while (0); |
635 | goto out; |
636 | } |
637 | |
638 | ret = _glusterd_quota_remove_limits ("a_limits, path, &flag); |
639 | if (ret == -1) { |
640 | if (flag == _gf_true) |
641 | snprintf (str, sizeof (str), "Removing limit on %s has " |
642 | "been unsuccessful", path); |
643 | else |
644 | snprintf (str, sizeof (str), "%s has no limit set", path); |
645 | *op_errstr = gf_strdup (str); |
646 | goto out; |
647 | } else { |
648 | if (flag == _gf_true) |
649 | snprintf (str, sizeof (str), "Removed quota limit on " |
650 | "%s", path); |
651 | else |
652 | snprintf (str, sizeof (str), "no limit set on %s", |
653 | path); |
654 | *op_errstr = gf_strdup (str); |
655 | } |
656 | |
657 | if (quota_limits) { |
658 | ret = dict_set_str (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE"features.limit-usage", |
659 | quota_limits); |
660 | if (ret) { |
661 | gf_log ("", GF_LOG_ERROR, "Unable to set quota limits" )do { do { if (0) printf ("Unable to set quota limits"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 661, GF_LOG_ERROR , "Unable to set quota limits"); } while (0); |
662 | goto out; |
663 | } |
664 | } else { |
665 | dict_del (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE"features.limit-usage"); |
666 | } |
667 | |
668 | ret = 0; |
669 | |
670 | out: |
671 | return ret; |
672 | } |
673 | |
674 | |
675 | int |
676 | glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) |
677 | { |
678 | glusterd_volinfo_t *volinfo = NULL((void*)0); |
679 | int32_t ret = -1; |
680 | char *volname = NULL((void*)0); |
681 | int type = -1; |
682 | gf_boolean_t start_crawl = _gf_false; |
683 | glusterd_conf_t *priv = NULL((void*)0); |
684 | |
685 | GF_ASSERT (dict)do { if (!(dict)) { do { do { if (0) printf ("Assertion failed: " "dict"); } while (0); _gf_log_callingfn ("", "glusterd-quota.c" , __FUNCTION__, 685, GF_LOG_ERROR, "Assertion failed: " "dict" ); } while (0); } } while (0); |
686 | GF_ASSERT (op_errstr)do { if (!(op_errstr)) { do { do { if (0) printf ("Assertion failed: " "op_errstr"); } while (0); _gf_log_callingfn ("", "glusterd-quota.c" , __FUNCTION__, 686, GF_LOG_ERROR, "Assertion failed: " "op_errstr" ); } while (0); } } while (0); |
687 | |
688 | priv = THIS(*__glusterfs_this_location())->private; |
689 | |
690 | ret = dict_get_str (dict, "volname", &volname); |
691 | if (ret) { |
692 | gf_log ("", GF_LOG_ERROR, "Unable to get volume name " )do { do { if (0) printf ("Unable to get volume name "); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 692, GF_LOG_ERROR , "Unable to get volume name "); } while (0); |
693 | goto out; |
694 | } |
695 | |
696 | ret = glusterd_volinfo_find (volname, &volinfo); |
697 | if (ret) { |
698 | gf_log ("", GF_LOG_ERROR, "Unable to allocate memory")do { do { if (0) printf ("Unable to allocate memory"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 698, GF_LOG_ERROR , "Unable to allocate memory"); } while (0); |
699 | goto out; |
700 | } |
701 | |
702 | ret = dict_get_int32 (dict, "type", &type); |
703 | |
704 | if (type == GF_QUOTA_OPTION_TYPE_ENABLE) { |
705 | ret = glusterd_quota_enable (volinfo, op_errstr, &start_crawl); |
706 | if (ret < 0) |
707 | goto out; |
708 | |
709 | goto create_vol; |
710 | } |
711 | |
712 | if (type == GF_QUOTA_OPTION_TYPE_DISABLE) { |
713 | ret = glusterd_quota_disable (volinfo, op_errstr); |
714 | if (ret < 0) |
715 | goto out; |
716 | |
717 | goto create_vol; |
718 | } |
719 | |
720 | if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE) { |
721 | ret = glusterd_quota_limit_usage (volinfo, dict, op_errstr); |
722 | if (ret < 0) |
723 | goto out; |
724 | |
725 | goto create_vol; |
726 | } |
727 | |
728 | if (type == GF_QUOTA_OPTION_TYPE_REMOVE) { |
729 | ret = glusterd_quota_remove_limits (volinfo, dict, op_errstr); |
730 | if (ret < 0) |
731 | goto out; |
732 | |
733 | goto create_vol; |
734 | } |
735 | |
736 | if (type == GF_QUOTA_OPTION_TYPE_LIST) { |
737 | ret = glusterd_check_if_quota_trans_enabled (volinfo); |
738 | if (ret == -1) { |
739 | *op_errstr = gf_strdup ("cannot list the limits, " |
740 | "quota is disabled"); |
741 | goto out; |
742 | } |
743 | |
744 | ret = glusterd_quota_get_limit_usages (priv, volinfo, volname, |
745 | dict, op_errstr, rsp_dict); |
746 | |
747 | goto out; |
748 | } |
749 | create_vol: |
750 | ret = glusterd_create_volfiles_and_notify_services (volinfo); |
751 | if (ret) { |
752 | gf_log ("", GF_LOG_ERROR, "Unable to re-create volfile for"do { do { if (0) printf ("Unable to re-create volfile for" " 'quota'" ); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__ , 753, GF_LOG_ERROR, "Unable to re-create volfile for" " 'quota'" ); } while (0) |
753 | " 'quota'")do { do { if (0) printf ("Unable to re-create volfile for" " 'quota'" ); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__ , 753, GF_LOG_ERROR, "Unable to re-create volfile for" " 'quota'" ); } while (0); |
754 | ret = -1; |
755 | goto out; |
756 | } |
757 | |
758 | ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT); |
759 | if (ret) |
760 | goto out; |
761 | |
762 | if (GLUSTERD_STATUS_STARTED == volinfo->status) |
763 | ret = glusterd_check_generate_start_nfs (); |
764 | |
765 | ret = 0; |
766 | |
767 | out: |
768 | if (rsp_dict && start_crawl == _gf_true) |
769 | glusterd_quota_initiate_fs_crawl (priv, volname); |
770 | |
771 | if (rsp_dict && *op_errstr) { |
772 | ret = dict_set_dynstr (rsp_dict, "errstr", *op_errstr); |
773 | if (ret) { |
774 | GF_FREE (*op_errstr)__gf_free (*op_errstr); |
775 | gf_log ("", GF_LOG_DEBUG,do { do { if (0) printf ("failed to set error message in ctx" ); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__ , 776, GF_LOG_DEBUG, "failed to set error message in ctx"); } while (0) |
776 | "failed to set error message in ctx")do { do { if (0) printf ("failed to set error message in ctx" ); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__ , 776, GF_LOG_DEBUG, "failed to set error message in ctx"); } while (0); |
777 | } |
778 | *op_errstr = NULL((void*)0); |
779 | } |
780 | |
781 | return ret; |
782 | } |
783 | |
784 | int |
785 | glusterd_op_stage_quota (dict_t *dict, char **op_errstr) |
786 | { |
787 | int ret = 0; |
788 | char *volname = NULL((void*)0); |
789 | gf_boolean_t exists = _gf_false; |
790 | int type = 0; |
791 | dict_t *ctx = NULL((void*)0); |
792 | |
793 | GF_ASSERT (dict)do { if (!(dict)) { do { do { if (0) printf ("Assertion failed: " "dict"); } while (0); _gf_log_callingfn ("", "glusterd-quota.c" , __FUNCTION__, 793, GF_LOG_ERROR, "Assertion failed: " "dict" ); } while (0); } } while (0); |
794 | GF_ASSERT (op_errstr)do { if (!(op_errstr)) { do { do { if (0) printf ("Assertion failed: " "op_errstr"); } while (0); _gf_log_callingfn ("", "glusterd-quota.c" , __FUNCTION__, 794, GF_LOG_ERROR, "Assertion failed: " "op_errstr" ); } while (0); } } while (0); |
795 | |
796 | ret = dict_get_str (dict, "volname", &volname); |
797 | if (ret) { |
798 | gf_log ("", GF_LOG_ERROR, "Unable to get volume name")do { do { if (0) printf ("Unable to get volume name"); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 798, GF_LOG_ERROR , "Unable to get volume name"); } while (0); |
799 | goto out; |
800 | } |
801 | |
802 | exists = glusterd_check_volume_exists (volname); |
803 | if (!exists) { |
804 | gf_log ("", GF_LOG_ERROR, "Volume with name: %s "do { do { if (0) printf ("Volume with name: %s " "does not exist" , volname); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__ , 806, GF_LOG_ERROR, "Volume with name: %s " "does not exist" , volname); } while (0) |
805 | "does not exist",do { do { if (0) printf ("Volume with name: %s " "does not exist" , volname); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__ , 806, GF_LOG_ERROR, "Volume with name: %s " "does not exist" , volname); } while (0) |
806 | volname)do { do { if (0) printf ("Volume with name: %s " "does not exist" , volname); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__ , 806, GF_LOG_ERROR, "Volume with name: %s " "does not exist" , volname); } while (0); |
807 | *op_errstr = gf_strdup ("Invalid volume name"); |
808 | ret = -1; |
809 | goto out; |
810 | } |
811 | |
812 | ret = dict_get_int32 (dict, "type", &type); |
813 | if (ret) { |
814 | gf_log ("", GF_LOG_ERROR, "Unable to get 'type' for quota op")do { do { if (0) printf ("Unable to get 'type' for quota op") ; } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 814, GF_LOG_ERROR, "Unable to get 'type' for quota op"); } while (0); |
815 | *op_errstr = gf_strdup ("Volume quota failed, internal error " |
816 | ", unable to get type of operation"); |
817 | goto out; |
818 | } |
819 | |
820 | |
821 | ctx = glusterd_op_get_ctx(); |
822 | if (ctx && (type == GF_QUOTA_OPTION_TYPE_ENABLE |
823 | || type == GF_QUOTA_OPTION_TYPE_LIST)) { |
824 | /* Fuse mount req. only for enable & list-usage options*/ |
825 | if (!glusterd_is_fuse_available ()) { |
826 | gf_log ("glusterd", GF_LOG_ERROR, "Unable to open /dev/"do { do { if (0) printf ("Unable to open /dev/" "fuse (%s), quota command failed" , strerror ((*__errno_location ()))); } while (0); _gf_log ("glusterd" , "glusterd-quota.c", __FUNCTION__, 828, GF_LOG_ERROR, "Unable to open /dev/" "fuse (%s), quota command failed", strerror ((*__errno_location ()))); } while (0) |
827 | "fuse (%s), quota command failed",do { do { if (0) printf ("Unable to open /dev/" "fuse (%s), quota command failed" , strerror ((*__errno_location ()))); } while (0); _gf_log ("glusterd" , "glusterd-quota.c", __FUNCTION__, 828, GF_LOG_ERROR, "Unable to open /dev/" "fuse (%s), quota command failed", strerror ((*__errno_location ()))); } while (0) |
828 | strerror (errno))do { do { if (0) printf ("Unable to open /dev/" "fuse (%s), quota command failed" , strerror ((*__errno_location ()))); } while (0); _gf_log ("glusterd" , "glusterd-quota.c", __FUNCTION__, 828, GF_LOG_ERROR, "Unable to open /dev/" "fuse (%s), quota command failed", strerror ((*__errno_location ()))); } while (0); |
829 | *op_errstr = gf_strdup ("Fuse unavailable"); |
830 | ret = -1; |
831 | goto out; |
832 | } |
833 | } |
834 | |
835 | out: |
836 | gf_log ("", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("", "glusterd-quota.c", __FUNCTION__, 836, GF_LOG_DEBUG, "Returning %d" , ret); } while (0); |
837 | |
838 | return ret; |
839 | } |