PageRenderTime 88ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/cli/src/cli-rpc-ops.c

https://github.com/xiushu2012/glusterfs
C | 6510 lines | 5396 code | 1053 blank | 61 comment | 1020 complexity | 05b7acac85471e1509bbbf49103023a3 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-3.0, LGPL-2.0, Apache-2.0, BSD-3-Clause
  1. /*
  2. Copyright (c) 2010-2012 Red Hat, Inc. <http://www.redhat.com>
  3. This file is part of GlusterFS.
  4. This file is licensed to you under your choice of the GNU Lesser
  5. General Public License, version 3 or any later version (LGPLv3 or
  6. later), or the GNU General Public License, version 2 (GPLv2), in all
  7. cases as published by the Free Software Foundation.
  8. */
  9. #ifndef _CONFIG_H
  10. #define _CONFIG_H
  11. #include "config.h"
  12. #endif
  13. #ifndef GSYNC_CONF
  14. #define GSYNC_CONF GEOREP"/gsyncd.conf"
  15. #endif
  16. /* Widths of various columns in top read/write-perf output
  17. * Total width of top read/write-perf should be 80 chars
  18. * including one space between column
  19. */
  20. #define VOL_TOP_PERF_FILENAME_DEF_WIDTH 47
  21. #define VOL_TOP_PERF_FILENAME_ALT_WIDTH 44
  22. #define VOL_TOP_PERF_SPEED_WIDTH 4
  23. #define VOL_TOP_PERF_TIME_WIDTH 26
  24. #include "cli.h"
  25. #include "compat-errno.h"
  26. #include "cli-cmd.h"
  27. #include <sys/uio.h>
  28. #include <stdlib.h>
  29. #include <sys/mount.h>
  30. #include "cli1-xdr.h"
  31. #include "xdr-generic.h"
  32. #include "protocol-common.h"
  33. #include "cli-mem-types.h"
  34. #include "compat.h"
  35. #include "syscall.h"
  36. #include "glusterfs3.h"
  37. #include "portmap-xdr.h"
  38. #include "run.h"
  39. extern rpc_clnt_prog_t *cli_rpc_prog;
  40. extern int cli_op_ret;
  41. extern int connected;
  42. char *cli_vol_type_str[] = {"Distribute",
  43. "Stripe",
  44. "Replicate",
  45. "Striped-Replicate",
  46. "Distributed-Stripe",
  47. "Distributed-Replicate",
  48. "Distributed-Striped-Replicate",
  49. };
  50. char *cli_vol_status_str[] = {"Created",
  51. "Started",
  52. "Stopped",
  53. };
  54. char *cli_volume_backend[] = {"",
  55. "Volume Group",
  56. };
  57. int32_t
  58. gf_cli_get_volume (call_frame_t *frame, xlator_t *this,
  59. void *data);
  60. int
  61. cli_to_glusterd (gf_cli_req *req, call_frame_t *frame, fop_cbk_fn_t cbkfn,
  62. xdrproc_t xdrproc, dict_t *dict, int procnum, xlator_t *this,
  63. rpc_clnt_prog_t *prog, struct iobref *iobref);
  64. rpc_clnt_prog_t cli_handshake_prog = {
  65. .progname = "cli handshake",
  66. .prognum = GLUSTER_HNDSK_PROGRAM,
  67. .progver = GLUSTER_HNDSK_VERSION,
  68. };
  69. rpc_clnt_prog_t cli_pmap_prog = {
  70. .progname = "cli portmap",
  71. .prognum = GLUSTER_PMAP_PROGRAM,
  72. .progver = GLUSTER_PMAP_VERSION,
  73. };
  74. void
  75. gf_cli_probe_strerror (gf1_cli_probe_rsp *rsp, char *msg, size_t len)
  76. {
  77. switch (rsp->op_errno) {
  78. case GF_PROBE_ANOTHER_CLUSTER:
  79. snprintf (msg, len, "%s is already part of another cluster",
  80. rsp->hostname);
  81. break;
  82. case GF_PROBE_VOLUME_CONFLICT:
  83. snprintf (msg, len, "Atleast one volume on %s conflicts with "
  84. "existing volumes in the cluster", rsp->hostname);
  85. break;
  86. case GF_PROBE_UNKNOWN_PEER:
  87. snprintf (msg, len, "%s responded with 'unknown peer' error, "
  88. "this could happen if %s doesn't have localhost in "
  89. "its peer database", rsp->hostname, rsp->hostname);
  90. break;
  91. case GF_PROBE_ADD_FAILED:
  92. snprintf (msg, len, "Failed to add peer information on %s" ,
  93. rsp->hostname);
  94. break;
  95. case GF_PROBE_SAME_UUID:
  96. snprintf (msg, len, "Peer uuid (host %s) is same as local uuid",
  97. rsp->hostname);
  98. break;
  99. case GF_PROBE_QUORUM_NOT_MET:
  100. snprintf (msg, len, "Cluster quorum is not met. Changing "
  101. "peers is not allowed in this state");
  102. break;
  103. default:
  104. snprintf (msg, len, "Probe returned with unknown "
  105. "errno %d", rsp->op_errno);
  106. break;
  107. }
  108. }
  109. int
  110. gf_cli_probe_cbk (struct rpc_req *req, struct iovec *iov,
  111. int count, void *myframe)
  112. {
  113. gf1_cli_probe_rsp rsp = {0,};
  114. int ret = -1;
  115. char msg[1024] = {0,};
  116. if (-1 == req->rpc_status) {
  117. goto out;
  118. }
  119. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_probe_rsp);
  120. if (ret < 0) {
  121. gf_log ("", GF_LOG_ERROR, "error");
  122. //rsp.op_ret = -1;
  123. //rsp.op_errno = EINVAL;
  124. goto out;
  125. }
  126. gf_log ("cli", GF_LOG_INFO, "Received resp to probe");
  127. if (!rsp.op_ret) {
  128. switch (rsp.op_errno) {
  129. case GF_PROBE_SUCCESS:
  130. snprintf (msg, sizeof (msg),
  131. "success");
  132. break;
  133. case GF_PROBE_LOCALHOST:
  134. snprintf (msg, sizeof (msg),
  135. "success: on localhost not needed");
  136. break;
  137. case GF_PROBE_FRIEND:
  138. snprintf (msg, sizeof (msg),
  139. "success: host %s port %d already"
  140. " in peer list", rsp.hostname,
  141. rsp.port);
  142. break;
  143. default:
  144. rsp.op_ret = -1;
  145. snprintf (msg, sizeof (msg),
  146. "Probe returned with unknown errno"
  147. " %d", rsp.op_errno);
  148. break;
  149. }
  150. }
  151. if (rsp.op_ret) {
  152. if (rsp.op_errstr && (strlen (rsp.op_errstr) > 0)) {
  153. snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
  154. } else {
  155. gf_cli_probe_strerror (&rsp, msg, sizeof (msg));
  156. }
  157. gf_log ("cli", GF_LOG_ERROR, "%s", msg);
  158. }
  159. if (global_state->mode & GLUSTER_MODE_XML) {
  160. ret = cli_xml_output_str (NULL,
  161. (rsp.op_ret)? NULL : msg,
  162. rsp.op_ret, rsp.op_errno,
  163. (rsp.op_ret)? msg : NULL);
  164. if (ret)
  165. gf_log ("cli", GF_LOG_ERROR,
  166. "Error outputting to xml");
  167. goto out;
  168. }
  169. if (!rsp.op_ret)
  170. cli_out ("peer probe: %s", msg);
  171. else
  172. cli_err ("peer probe: failed: %s", msg);
  173. ret = rsp.op_ret;
  174. out:
  175. cli_cmd_broadcast_response (ret);
  176. return ret;
  177. }
  178. int
  179. gf_cli_deprobe_cbk (struct rpc_req *req, struct iovec *iov,
  180. int count, void *myframe)
  181. {
  182. gf1_cli_deprobe_rsp rsp = {0,};
  183. int ret = -1;
  184. char msg[1024] = {0,};
  185. if (-1 == req->rpc_status) {
  186. goto out;
  187. }
  188. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_deprobe_rsp);
  189. if (ret < 0) {
  190. gf_log ("", GF_LOG_ERROR, "error");
  191. //rsp.op_ret = -1;
  192. //rsp.op_errno = EINVAL;
  193. goto out;
  194. }
  195. gf_log ("cli", GF_LOG_INFO, "Received resp to deprobe");
  196. if (rsp.op_ret) {
  197. if (strlen (rsp.op_errstr) > 0) {
  198. snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
  199. gf_log ("cli", GF_LOG_ERROR, "%s", rsp.op_errstr);
  200. } else {
  201. switch (rsp.op_errno) {
  202. case GF_DEPROBE_LOCALHOST:
  203. snprintf (msg, sizeof (msg),
  204. "%s is localhost",
  205. rsp.hostname);
  206. break;
  207. case GF_DEPROBE_NOT_FRIEND:
  208. snprintf (msg, sizeof (msg),
  209. "%s is not part of cluster",
  210. rsp.hostname);
  211. break;
  212. case GF_DEPROBE_BRICK_EXIST:
  213. snprintf (msg, sizeof (msg),
  214. "Brick(s) with the peer %s "
  215. "exist in cluster",
  216. rsp.hostname);
  217. break;
  218. case GF_DEPROBE_FRIEND_DOWN:
  219. snprintf (msg, sizeof (msg),
  220. "One of the peers is probably"
  221. " down. Check with 'peer "
  222. "status'.");
  223. break;
  224. case GF_DEPROBE_QUORUM_NOT_MET:
  225. snprintf (msg, sizeof (msg), "Cluster "
  226. "quorum is not met. Changing "
  227. "peers is not allowed in this"
  228. " state");
  229. break;
  230. default:
  231. snprintf (msg, sizeof (msg),
  232. "Detach returned with unknown"
  233. " errno %d", rsp.op_errno);
  234. break;
  235. }
  236. gf_log ("cli", GF_LOG_ERROR,"Detach failed with op_ret "
  237. "%d and op_errno %d", rsp.op_ret, rsp.op_errno);
  238. }
  239. } else {
  240. snprintf (msg, sizeof (msg), "success");
  241. }
  242. if (global_state->mode & GLUSTER_MODE_XML) {
  243. ret = cli_xml_output_str (NULL,
  244. (rsp.op_ret)? NULL : msg,
  245. rsp.op_ret, rsp.op_errno,
  246. (rsp.op_ret)? msg : NULL);
  247. if (ret)
  248. gf_log ("cli", GF_LOG_ERROR,
  249. "Error outputting to xml");
  250. goto out;
  251. }
  252. if (!rsp.op_ret)
  253. cli_out ("peer detach: %s", msg);
  254. else
  255. cli_err ("peer detach: failed: %s", msg);
  256. ret = rsp.op_ret;
  257. out:
  258. cli_cmd_broadcast_response (ret);
  259. return ret;
  260. }
  261. int
  262. gf_cli_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
  263. int count, void *myframe)
  264. {
  265. gf1_cli_peer_list_rsp rsp = {0,};
  266. int ret = -1;
  267. dict_t *dict = NULL;
  268. char *uuid_buf = NULL;
  269. char *hostname_buf = NULL;
  270. int32_t i = 1;
  271. char key[256] = {0,};
  272. char *state = NULL;
  273. int32_t port = 0;
  274. int32_t connected = 0;
  275. char *connected_str = NULL;
  276. char msg[1024] = {0,};
  277. if (-1 == req->rpc_status) {
  278. goto out;
  279. }
  280. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_peer_list_rsp);
  281. if (ret < 0) {
  282. gf_log ("", GF_LOG_ERROR, "error");
  283. //rsp.op_ret = -1;
  284. //rsp.op_errno = EINVAL;
  285. goto out;
  286. }
  287. gf_log ("cli", GF_LOG_INFO, "Received resp to list: %d",
  288. rsp.op_ret);
  289. ret = rsp.op_ret;
  290. if (!rsp.op_ret) {
  291. if (!rsp.friends.friends_len) {
  292. snprintf (msg, sizeof (msg),
  293. "peer status: No peers present");
  294. if (global_state->mode & GLUSTER_MODE_XML) {
  295. ret = cli_xml_output_peer_status (dict,
  296. rsp.op_ret,
  297. rsp.op_errno,
  298. msg);
  299. if (ret)
  300. gf_log ("cli", GF_LOG_ERROR,
  301. "Error outputting to xml");
  302. goto out;
  303. }
  304. cli_err ("%s", msg);
  305. ret = 0;
  306. goto out;
  307. }
  308. dict = dict_new ();
  309. if (!dict) {
  310. ret = -1;
  311. goto out;
  312. }
  313. ret = dict_unserialize (rsp.friends.friends_val,
  314. rsp.friends.friends_len,
  315. &dict);
  316. if (ret) {
  317. gf_log ("", GF_LOG_ERROR,
  318. "Unable to allocate memory");
  319. goto out;
  320. }
  321. if (global_state->mode & GLUSTER_MODE_XML) {
  322. ret = cli_xml_output_peer_status (dict, rsp.op_ret,
  323. rsp.op_errno, msg);
  324. if (ret)
  325. gf_log ("cli", GF_LOG_ERROR,
  326. "Error outputting to xml");
  327. goto out;
  328. }
  329. ret = dict_get_int32 (dict, "count", &count);
  330. if (ret) {
  331. goto out;
  332. }
  333. cli_out ("Number of Peers: %d", count);
  334. i = 1;
  335. while ( i <= count) {
  336. snprintf (key, 256, "friend%d.uuid", i);
  337. ret = dict_get_str (dict, key, &uuid_buf);
  338. if (ret)
  339. goto out;
  340. snprintf (key, 256, "friend%d.hostname", i);
  341. ret = dict_get_str (dict, key, &hostname_buf);
  342. if (ret)
  343. goto out;
  344. snprintf (key, 256, "friend%d.connected", i);
  345. ret = dict_get_int32 (dict, key, &connected);
  346. if (ret)
  347. goto out;
  348. if (connected)
  349. connected_str = "Connected";
  350. else
  351. connected_str = "Disconnected";
  352. snprintf (key, 256, "friend%d.port", i);
  353. ret = dict_get_int32 (dict, key, &port);
  354. if (ret)
  355. goto out;
  356. snprintf (key, 256, "friend%d.state", i);
  357. ret = dict_get_str (dict, key, &state);
  358. if (ret)
  359. goto out;
  360. if (!port) {
  361. cli_out ("\nHostname: %s\nUuid: %s\nState: %s "
  362. "(%s)",
  363. hostname_buf, uuid_buf, state,
  364. connected_str);
  365. } else {
  366. cli_out ("\nHostname: %s\nPort: %d\nUuid: %s\n"
  367. "State: %s (%s)", hostname_buf, port,
  368. uuid_buf, state, connected_str);
  369. }
  370. i++;
  371. }
  372. } else {
  373. if (global_state->mode & GLUSTER_MODE_XML) {
  374. ret = cli_xml_output_peer_status (dict, rsp.op_ret,
  375. rsp.op_errno, NULL);
  376. if (ret)
  377. gf_log ("cli", GF_LOG_ERROR,
  378. "Error outputting to xml");
  379. } else {
  380. ret = -1;
  381. }
  382. goto out;
  383. }
  384. ret = 0;
  385. out:
  386. cli_cmd_broadcast_response (ret);
  387. if (ret)
  388. cli_err ("peer status: failed");
  389. if (dict)
  390. dict_destroy (dict);
  391. return ret;
  392. }
  393. void
  394. cli_out_options ( char *substr, char *optstr, char *valstr)
  395. {
  396. char *ptr1 = NULL;
  397. char *ptr2 = NULL;
  398. ptr1 = substr;
  399. ptr2 = optstr;
  400. while (ptr1)
  401. {
  402. if (*ptr1 != *ptr2)
  403. break;
  404. ptr1++;
  405. ptr2++;
  406. if (!ptr1)
  407. return;
  408. if (!ptr2)
  409. return;
  410. }
  411. if (*ptr2 == '\0')
  412. return;
  413. cli_out ("%s: %s",ptr2 , valstr);
  414. }
  415. static int
  416. _gf_cli_output_volinfo_opts (dict_t *d, char *k,
  417. data_t *v, void *tmp)
  418. {
  419. int ret = 0;
  420. char *key = NULL;
  421. char *ptr = NULL;
  422. data_t *value = NULL;
  423. key = tmp;
  424. ptr = strstr (k, "option.");
  425. if (ptr) {
  426. value = v;
  427. if (!value) {
  428. ret = -1;
  429. goto out;
  430. }
  431. cli_out_options (key, k, v->data);
  432. }
  433. out:
  434. return ret;
  435. }
  436. int
  437. gf_cli_get_volume_cbk (struct rpc_req *req, struct iovec *iov,
  438. int count, void *myframe)
  439. {
  440. int ret = -1;
  441. int opt_count = 0;
  442. int32_t i = 0;
  443. int32_t j = 1;
  444. int32_t status = 0;
  445. int32_t type = 0;
  446. int32_t brick_count = 0;
  447. int32_t dist_count = 0;
  448. int32_t stripe_count = 0;
  449. int32_t replica_count = 0;
  450. int32_t vol_type = 0;
  451. int32_t transport = 0;
  452. char *volume_id_str = NULL;
  453. char *brick = NULL;
  454. char *volname = NULL;
  455. dict_t *dict = NULL;
  456. cli_local_t *local = NULL;
  457. char key[1024] = {0};
  458. char err_str[2048] = {0};
  459. gf_cli_rsp rsp = {0};
  460. int32_t backend = 0;
  461. if (-1 == req->rpc_status)
  462. goto out;
  463. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  464. if (ret < 0) {
  465. gf_log ("cli", GF_LOG_ERROR, "error");
  466. goto out;
  467. }
  468. gf_log ("cli", GF_LOG_INFO, "Received resp to get vol: %d",
  469. rsp.op_ret);
  470. if (rsp.op_ret) {
  471. ret = -1;
  472. goto out;
  473. }
  474. if (!rsp.dict.dict_len) {
  475. if (global_state->mode & GLUSTER_MODE_XML)
  476. goto xml_output;
  477. cli_err ("No volumes present");
  478. ret = 0;
  479. goto out;
  480. }
  481. dict = dict_new ();
  482. if (!dict) {
  483. ret = -1;
  484. goto out;
  485. }
  486. ret = dict_unserialize (rsp.dict.dict_val,
  487. rsp.dict.dict_len,
  488. &dict);
  489. if (ret) {
  490. gf_log ("cli", GF_LOG_ERROR,
  491. "Unable to allocate memory");
  492. goto out;
  493. }
  494. ret = dict_get_int32 (dict, "count", &count);
  495. if (ret)
  496. goto out;
  497. local = ((call_frame_t *)myframe)->local;
  498. if (!count) {
  499. switch (local->get_vol.flags) {
  500. case GF_CLI_GET_NEXT_VOLUME:
  501. GF_FREE (local->get_vol.volname);
  502. local->get_vol.volname = NULL;
  503. ret = 0;
  504. goto out;
  505. case GF_CLI_GET_VOLUME:
  506. memset (err_str, 0, sizeof (err_str));
  507. snprintf (err_str, sizeof (err_str),
  508. "Volume %s does not exist",
  509. local->get_vol.volname);
  510. ret = -1;
  511. if (!(global_state->mode & GLUSTER_MODE_XML))
  512. goto out;
  513. }
  514. }
  515. xml_output:
  516. if (global_state->mode & GLUSTER_MODE_XML) {
  517. /* For GET_NEXT_VOLUME output is already begun in
  518. * and will also end in gf_cli_get_next_volume()
  519. */
  520. if (local->get_vol.flags == GF_CLI_GET_VOLUME) {
  521. ret = cli_xml_output_vol_info_begin
  522. (local, rsp.op_ret, rsp.op_errno,
  523. rsp.op_errstr);
  524. if (ret) {
  525. gf_log ("cli", GF_LOG_ERROR,
  526. "Error outputting to xml");
  527. goto out;
  528. }
  529. }
  530. if (dict) {
  531. ret = cli_xml_output_vol_info (local, dict);
  532. if (ret) {
  533. gf_log ("cli", GF_LOG_ERROR,
  534. "Error outputting to xml");
  535. goto out;
  536. }
  537. }
  538. if (local->get_vol.flags == GF_CLI_GET_VOLUME) {
  539. ret = cli_xml_output_vol_info_end (local);
  540. if (ret)
  541. gf_log ("cli", GF_LOG_ERROR,
  542. "Error outputting to xml");
  543. }
  544. goto out;
  545. }
  546. while ( i < count) {
  547. cli_out (" ");
  548. snprintf (key, 256, "volume%d.name", i);
  549. ret = dict_get_str (dict, key, &volname);
  550. if (ret)
  551. goto out;
  552. snprintf (key, 256, "volume%d.type", i);
  553. ret = dict_get_int32 (dict, key, &type);
  554. if (ret)
  555. goto out;
  556. snprintf (key, 256, "volume%d.status", i);
  557. ret = dict_get_int32 (dict, key, &status);
  558. if (ret)
  559. goto out;
  560. snprintf (key, 256, "volume%d.brick_count", i);
  561. ret = dict_get_int32 (dict, key, &brick_count);
  562. if (ret)
  563. goto out;
  564. snprintf (key, 256, "volume%d.dist_count", i);
  565. ret = dict_get_int32 (dict, key, &dist_count);
  566. if (ret)
  567. goto out;
  568. snprintf (key, 256, "volume%d.stripe_count", i);
  569. ret = dict_get_int32 (dict, key, &stripe_count);
  570. if (ret)
  571. goto out;
  572. snprintf (key, 256, "volume%d.replica_count", i);
  573. ret = dict_get_int32 (dict, key, &replica_count);
  574. if (ret)
  575. goto out;
  576. snprintf (key, 256, "volume%d.transport", i);
  577. ret = dict_get_int32 (dict, key, &transport);
  578. if (ret)
  579. goto out;
  580. snprintf (key, 256, "volume%d.volume_id", i);
  581. ret = dict_get_str (dict, key, &volume_id_str);
  582. if (ret)
  583. goto out;
  584. snprintf (key, 256, "volume%d.backend", i);
  585. ret = dict_get_int32 (dict, key, &backend);
  586. vol_type = type;
  587. // Distributed (stripe/replicate/stripe-replica) setups
  588. if ((type > 0) && ( dist_count < brick_count))
  589. vol_type = type + 3;
  590. cli_out ("Volume Name: %s", volname);
  591. cli_out ("Type: %s", cli_vol_type_str[vol_type]);
  592. cli_out ("Volume ID: %s", volume_id_str);
  593. cli_out ("Status: %s", cli_vol_status_str[status]);
  594. if (backend)
  595. goto next;
  596. if (type == GF_CLUSTER_TYPE_STRIPE_REPLICATE) {
  597. cli_out ("Number of Bricks: %d x %d x %d = %d",
  598. (brick_count / dist_count),
  599. stripe_count,
  600. replica_count,
  601. brick_count);
  602. } else if (type == GF_CLUSTER_TYPE_NONE) {
  603. cli_out ("Number of Bricks: %d", brick_count);
  604. } else {
  605. /* For both replicate and stripe, dist_count is
  606. good enough */
  607. cli_out ("Number of Bricks: %d x %d = %d",
  608. (brick_count / dist_count),
  609. dist_count, brick_count);
  610. }
  611. cli_out ("Transport-type: %s",
  612. ((transport == 0)?"tcp":
  613. (transport == 1)?"rdma":
  614. "tcp,rdma"));
  615. next:
  616. if (backend) {
  617. cli_out ("Backend Type: Block, %s",
  618. cli_volume_backend[backend]);
  619. }
  620. j = 1;
  621. GF_FREE (local->get_vol.volname);
  622. local->get_vol.volname = gf_strdup (volname);
  623. if (brick_count)
  624. cli_out ("Bricks:");
  625. while (j <= brick_count) {
  626. snprintf (key, 1024, "volume%d.brick%d", i, j);
  627. ret = dict_get_str (dict, key, &brick);
  628. if (ret)
  629. goto out;
  630. cli_out ("Brick%d: %s", j, brick);
  631. j++;
  632. }
  633. snprintf (key, 256, "volume%d.opt_count",i);
  634. ret = dict_get_int32 (dict, key, &opt_count);
  635. if (ret)
  636. goto out;
  637. if (!opt_count)
  638. goto out;
  639. cli_out ("Options Reconfigured:");
  640. snprintf (key, 256, "volume%d.option.",i);
  641. ret = dict_foreach (dict, _gf_cli_output_volinfo_opts, key);
  642. if (ret)
  643. goto out;
  644. i++;
  645. }
  646. ret = 0;
  647. out:
  648. cli_cmd_broadcast_response (ret);
  649. if (ret)
  650. cli_err ("%s", err_str);
  651. if (dict)
  652. dict_destroy (dict);
  653. free (rsp.dict.dict_val);
  654. free (rsp.op_errstr);
  655. gf_log ("cli", GF_LOG_INFO, "Returning: %d", ret);
  656. return ret;
  657. }
  658. int
  659. gf_cli_create_volume_cbk (struct rpc_req *req, struct iovec *iov,
  660. int count, void *myframe)
  661. {
  662. gf_cli_rsp rsp = {0,};
  663. int ret = -1;
  664. cli_local_t *local = NULL;
  665. char *volname = NULL;
  666. dict_t *dict = NULL;
  667. dict_t *rsp_dict = NULL;
  668. if (-1 == req->rpc_status) {
  669. goto out;
  670. }
  671. local = ((call_frame_t *) (myframe))->local;
  672. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  673. if (ret < 0) {
  674. gf_log ("", GF_LOG_ERROR, "error");
  675. goto out;
  676. }
  677. gf_log ("cli", GF_LOG_INFO, "Received resp to create volume");
  678. dict = local->dict;
  679. ret = dict_get_str (dict, "volname", &volname);
  680. if (ret)
  681. goto out;
  682. if (global_state->mode & GLUSTER_MODE_XML) {
  683. if (rsp.op_ret == 0) {
  684. rsp_dict = dict_new ();
  685. ret = dict_unserialize (rsp.dict.dict_val,
  686. rsp.dict.dict_len,
  687. &rsp_dict);
  688. if (ret) {
  689. gf_log ("cli", GF_LOG_ERROR,
  690. "Failed rsp_dict unserialization");
  691. goto out;
  692. }
  693. }
  694. ret = cli_xml_output_vol_create (rsp_dict, rsp.op_ret,
  695. rsp.op_errno, rsp.op_errstr);
  696. if (ret)
  697. gf_log ("cli", GF_LOG_ERROR,
  698. "Error outputting to xml");
  699. goto out;
  700. }
  701. if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
  702. cli_err ("volume create: %s: failed: %s", volname,
  703. rsp.op_errstr);
  704. else if (rsp.op_ret)
  705. cli_err ("volume create: %s: failed", volname);
  706. else
  707. cli_out ("volume create: %s: success: "
  708. "please start the volume to access data", volname);
  709. ret = rsp.op_ret;
  710. out:
  711. cli_cmd_broadcast_response (ret);
  712. free (rsp.dict.dict_val);
  713. free (rsp.op_errstr);
  714. return ret;
  715. }
  716. int
  717. gf_cli_delete_volume_cbk (struct rpc_req *req, struct iovec *iov,
  718. int count, void *myframe)
  719. {
  720. gf_cli_rsp rsp = {0,};
  721. int ret = -1;
  722. cli_local_t *local = NULL;
  723. char *volname = NULL;
  724. call_frame_t *frame = NULL;
  725. dict_t *dict = NULL;
  726. dict_t *rsp_dict = NULL;
  727. if (-1 == req->rpc_status) {
  728. goto out;
  729. }
  730. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  731. if (ret < 0) {
  732. gf_log ("", GF_LOG_ERROR, "error");
  733. goto out;
  734. }
  735. frame = myframe;
  736. local = frame->local;
  737. if (local)
  738. dict = local->dict;
  739. ret = dict_get_str (dict, "volname", &volname);
  740. if (ret) {
  741. gf_log (THIS->name, GF_LOG_ERROR,
  742. "dict get failed");
  743. goto out;
  744. }
  745. gf_log ("cli", GF_LOG_INFO, "Received resp to delete volume");
  746. if (global_state->mode & GLUSTER_MODE_XML) {
  747. if (rsp.op_ret == 0) {
  748. rsp_dict = dict_new ();
  749. ret = dict_unserialize (rsp.dict.dict_val,
  750. rsp.dict.dict_len,
  751. &rsp_dict);
  752. if (ret) {
  753. gf_log ("cli", GF_LOG_ERROR,
  754. "Failed rsp_dict unserialization");
  755. goto out;
  756. }
  757. }
  758. ret = cli_xml_output_generic_volume ("volDelete", rsp_dict,
  759. rsp.op_ret, rsp.op_errno,
  760. rsp.op_errstr);
  761. if (ret)
  762. gf_log ("cli", GF_LOG_ERROR,
  763. "Error outputting to xml");
  764. goto out;
  765. }
  766. if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
  767. cli_err ("volume delete: %s: failed: %s", volname,
  768. rsp.op_errstr);
  769. else if (rsp.op_ret)
  770. cli_err ("volume delete: %s: failed", volname);
  771. else
  772. cli_out ("volume delete: %s: success", volname);
  773. ret = rsp.op_ret;
  774. out:
  775. cli_cmd_broadcast_response (ret);
  776. free (rsp.dict.dict_val);
  777. gf_log ("", GF_LOG_INFO, "Returning with %d", ret);
  778. return ret;
  779. }
  780. int
  781. gf_cli3_1_uuid_reset_cbk (struct rpc_req *req, struct iovec *iov,
  782. int count, void *myframe)
  783. {
  784. gf_cli_rsp rsp = {0,};
  785. int ret = -1;
  786. cli_local_t *local = NULL;
  787. call_frame_t *frame = NULL;
  788. dict_t *dict = NULL;
  789. if (-1 == req->rpc_status) {
  790. goto out;
  791. }
  792. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  793. if (ret < 0) {
  794. gf_log ("", GF_LOG_ERROR, "error");
  795. goto out;
  796. }
  797. frame = myframe;
  798. local = frame->local;
  799. frame->local = NULL;
  800. gf_log ("cli", GF_LOG_INFO, "Received resp to uuid reset");
  801. if (global_state->mode & GLUSTER_MODE_XML) {
  802. ret = cli_xml_output_dict ("uuidReset", dict, rsp.op_ret,
  803. rsp.op_errno, rsp.op_errstr);
  804. if (ret)
  805. gf_log ("cli", GF_LOG_ERROR,
  806. "Error outputting to xml");
  807. goto out;
  808. }
  809. if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
  810. cli_err ("%s", rsp.op_errstr);
  811. else
  812. cli_out ("resetting the peer uuid has been %s",
  813. (rsp.op_ret) ? "unsuccessful": "successful");
  814. ret = rsp.op_ret;
  815. out:
  816. cli_cmd_broadcast_response (ret);
  817. cli_local_wipe (local);
  818. if (rsp.dict.dict_val)
  819. free (rsp.dict.dict_val);
  820. if (dict)
  821. dict_unref (dict);
  822. gf_log ("", GF_LOG_INFO, "Returning with %d", ret);
  823. return ret;
  824. }
  825. int
  826. gf_cli_start_volume_cbk (struct rpc_req *req, struct iovec *iov,
  827. int count, void *myframe)
  828. {
  829. gf_cli_rsp rsp = {0,};
  830. int ret = -1;
  831. cli_local_t *local = NULL;
  832. char *volname = NULL;
  833. call_frame_t *frame = NULL;
  834. dict_t *dict = NULL;
  835. dict_t *rsp_dict = NULL;
  836. if (-1 == req->rpc_status) {
  837. goto out;
  838. }
  839. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  840. if (ret < 0) {
  841. gf_log ("", GF_LOG_ERROR, "error");
  842. goto out;
  843. }
  844. frame = myframe;
  845. if (frame)
  846. local = frame->local;
  847. if (local)
  848. dict = local->dict;
  849. ret = dict_get_str (dict, "volname", &volname);
  850. if (ret) {
  851. gf_log (THIS->name, GF_LOG_ERROR, "dict get failed");
  852. goto out;
  853. }
  854. gf_log ("cli", GF_LOG_INFO, "Received resp to start volume");
  855. if (global_state->mode & GLUSTER_MODE_XML) {
  856. if (rsp.op_ret == 0) {
  857. rsp_dict = dict_new ();
  858. ret = dict_unserialize (rsp.dict.dict_val,
  859. rsp.dict.dict_len,
  860. &rsp_dict);
  861. if (ret) {
  862. gf_log ("cli", GF_LOG_ERROR,
  863. "Failed rsp_dict unserialization");
  864. goto out;
  865. }
  866. }
  867. ret = cli_xml_output_generic_volume ("volStart", rsp_dict,
  868. rsp.op_ret, rsp.op_errno,
  869. rsp.op_errstr);
  870. if (ret)
  871. gf_log ("cli", GF_LOG_ERROR,
  872. "Error outputting to xml");
  873. goto out;
  874. }
  875. if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
  876. cli_err ("volume start: %s: failed: %s", volname,
  877. rsp.op_errstr);
  878. else if (rsp.op_ret)
  879. cli_err ("volume start: %s: failed", volname);
  880. else
  881. cli_out ("volume start: %s: success", volname);
  882. ret = rsp.op_ret;
  883. out:
  884. cli_cmd_broadcast_response (ret);
  885. free (rsp.dict.dict_val);
  886. free (rsp.op_errstr);
  887. return ret;
  888. }
  889. int
  890. gf_cli_stop_volume_cbk (struct rpc_req *req, struct iovec *iov,
  891. int count, void *myframe)
  892. {
  893. gf_cli_rsp rsp = {0,};
  894. int ret = -1;
  895. cli_local_t *local = NULL;
  896. char *volname = NULL;
  897. call_frame_t *frame = NULL;
  898. dict_t *dict = NULL;
  899. dict_t *rsp_dict = NULL;
  900. if (-1 == req->rpc_status) {
  901. goto out;
  902. }
  903. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  904. if (ret < 0) {
  905. gf_log ("", GF_LOG_ERROR, "error");
  906. goto out;
  907. }
  908. frame = myframe;
  909. if (frame)
  910. local = frame->local;
  911. if (local) {
  912. dict = local->dict;
  913. ret = dict_get_str (dict, "volname", &volname);
  914. if (ret) {
  915. gf_log (THIS->name, GF_LOG_ERROR,
  916. "Unable to get volname from dict");
  917. goto out;
  918. }
  919. }
  920. gf_log ("cli", GF_LOG_INFO, "Received resp to stop volume");
  921. if (global_state->mode & GLUSTER_MODE_XML) {
  922. if (rsp.op_ret == 0) {
  923. rsp_dict = dict_new ();
  924. ret = dict_unserialize (rsp.dict.dict_val,
  925. rsp.dict.dict_len,
  926. &rsp_dict);
  927. if (ret) {
  928. gf_log ("cli", GF_LOG_ERROR,
  929. "Failed rsp_dict unserialization");
  930. goto out;
  931. }
  932. }
  933. ret = cli_xml_output_generic_volume ("volStop", rsp_dict,
  934. rsp.op_ret, rsp.op_errno,
  935. rsp.op_errstr);
  936. if (ret)
  937. gf_log ("cli", GF_LOG_ERROR,
  938. "Error outputting to xml");
  939. goto out;
  940. }
  941. if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
  942. cli_err ("volume stop: %s: failed: %s", volname, rsp.op_errstr);
  943. else if (rsp.op_ret)
  944. cli_err ("volume stop: %s: failed", volname);
  945. else
  946. cli_out ("volume stop: %s: success", volname);
  947. ret = rsp.op_ret;
  948. out:
  949. cli_cmd_broadcast_response (ret);
  950. free (rsp.op_errstr);
  951. free (rsp.dict.dict_val);
  952. return ret;
  953. }
  954. int
  955. gf_cli_defrag_volume_cbk (struct rpc_req *req, struct iovec *iov,
  956. int count, void *myframe)
  957. {
  958. gf_cli_rsp rsp = {0,};
  959. cli_local_t *local = NULL;
  960. char *volname = NULL;
  961. call_frame_t *frame = NULL;
  962. char *status = "unknown";
  963. int cmd = 0;
  964. int ret = -1;
  965. dict_t *dict = NULL;
  966. dict_t *local_dict = NULL;
  967. uint64_t files = 0;
  968. uint64_t size = 0;
  969. uint64_t lookup = 0;
  970. char msg[1024] = {0,};
  971. gf_defrag_status_t status_rcd = GF_DEFRAG_STATUS_NOT_STARTED;
  972. int32_t counter = 0;
  973. char *node_uuid = NULL;
  974. char key[256] = {0,};
  975. int32_t i = 1;
  976. uint64_t failures = 0;
  977. double elapsed = 0;
  978. char *size_str = NULL;
  979. char *task_id_str = NULL;
  980. if (-1 == req->rpc_status) {
  981. goto out;
  982. }
  983. ret = xdr_to_generic (*iov, &rsp,
  984. (xdrproc_t)xdr_gf_cli_rsp);
  985. if (ret < 0) {
  986. gf_log ("", GF_LOG_ERROR, "error");
  987. goto out;
  988. }
  989. frame = myframe;
  990. if (frame)
  991. local = frame->local;
  992. if (local)
  993. local_dict = local->dict;
  994. ret = dict_get_str (local_dict, "volname", &volname);
  995. if (ret) {
  996. gf_log (THIS->name, GF_LOG_ERROR,
  997. "Failed to get volname");
  998. goto out;
  999. }
  1000. ret = dict_get_int32 (local_dict, "rebalance-command", (int32_t*)&cmd);
  1001. if (ret) {
  1002. gf_log (THIS->name, GF_LOG_ERROR,
  1003. "Failed to get command");
  1004. goto out;
  1005. }
  1006. if (rsp.dict.dict_len) {
  1007. /* Unserialize the dictionary */
  1008. dict = dict_new ();
  1009. ret = dict_unserialize (rsp.dict.dict_val,
  1010. rsp.dict.dict_len,
  1011. &dict);
  1012. if (ret < 0) {
  1013. gf_log ("glusterd", GF_LOG_ERROR,
  1014. "failed to "
  1015. "unserialize req-buffer to dictionary");
  1016. goto out;
  1017. }
  1018. }
  1019. if (!((cmd == GF_DEFRAG_CMD_STOP) || (cmd == GF_DEFRAG_CMD_STATUS)) &&
  1020. !(global_state->mode & GLUSTER_MODE_XML)) {
  1021. /* All other possibilites are about starting a rebalance */
  1022. ret = dict_get_str (dict, GF_REBALANCE_TID_KEY, &task_id_str);
  1023. if (rsp.op_ret && strcmp (rsp.op_errstr, "")) {
  1024. snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
  1025. } else {
  1026. if (!rsp.op_ret) {
  1027. snprintf (msg, sizeof (msg),
  1028. "Starting rebalance on volume %s has "
  1029. "been successful.\nID: %s", volname,
  1030. task_id_str);
  1031. } else {
  1032. snprintf (msg, sizeof (msg),
  1033. "Starting rebalance on volume %s has "
  1034. "been unsuccessful.", volname);
  1035. }
  1036. }
  1037. goto done;
  1038. }
  1039. if (cmd == GF_DEFRAG_CMD_STOP) {
  1040. if (rsp.op_ret == -1) {
  1041. if (strcmp (rsp.op_errstr, ""))
  1042. snprintf (msg, sizeof (msg),
  1043. "%s", rsp.op_errstr);
  1044. else
  1045. snprintf (msg, sizeof (msg),
  1046. "rebalance volume %s stop failed",
  1047. volname);
  1048. goto done;
  1049. } else {
  1050. snprintf (msg, sizeof (msg),
  1051. "Stopped rebalance process on volume %s \n",
  1052. volname);
  1053. }
  1054. }
  1055. if (cmd == GF_DEFRAG_CMD_STATUS) {
  1056. if (rsp.op_ret == -1) {
  1057. if (strcmp (rsp.op_errstr, ""))
  1058. snprintf (msg, sizeof (msg),
  1059. "%s", rsp.op_errstr);
  1060. else
  1061. snprintf (msg, sizeof (msg),
  1062. "Failed to get the status of "
  1063. "rebalance process");
  1064. goto done;
  1065. }
  1066. }
  1067. if (global_state->mode & GLUSTER_MODE_XML) {
  1068. ret = cli_xml_output_vol_rebalance (cmd, dict, rsp.op_ret,
  1069. rsp.op_errno,
  1070. rsp.op_errstr);
  1071. goto out;
  1072. }
  1073. ret = dict_get_int32 (dict, "count", &counter);
  1074. if (ret) {
  1075. gf_log (THIS->name, GF_LOG_ERROR, "count not set");
  1076. goto out;
  1077. }
  1078. cli_out ("%40s %16s %13s %13s %13s %14s %s", "Node", "Rebalanced-files",
  1079. "size", "scanned", "failures", "status", "run time in secs");
  1080. cli_out ("%40s %16s %13s %13s %13s %14s %16s", "---------",
  1081. "-----------", "-----------", "-----------", "-----------",
  1082. "------------", "--------------");
  1083. do {
  1084. snprintf (key, 256, "node-uuid-%d", i);
  1085. ret = dict_get_str (dict, key, &node_uuid);
  1086. if (ret)
  1087. gf_log (THIS->name, GF_LOG_TRACE,
  1088. "failed to get node-uuid");
  1089. memset (key, 0, 256);
  1090. snprintf (key, 256, "files-%d", i);
  1091. ret = dict_get_uint64 (dict, key, &files);
  1092. if (ret)
  1093. gf_log (THIS->name, GF_LOG_TRACE,
  1094. "failed to get file count");
  1095. memset (key, 0, 256);
  1096. snprintf (key, 256, "size-%d", i);
  1097. ret = dict_get_uint64 (dict, key, &size);
  1098. if (ret)
  1099. gf_log (THIS->name, GF_LOG_TRACE,
  1100. "failed to get size of xfer");
  1101. memset (key, 0, 256);
  1102. snprintf (key, 256, "lookups-%d", i);
  1103. ret = dict_get_uint64 (dict, key, &lookup);
  1104. if (ret)
  1105. gf_log (THIS->name, GF_LOG_TRACE,
  1106. "failed to get lookedup file count");
  1107. memset (key, 0, 256);
  1108. snprintf (key, 256, "status-%d", i);
  1109. ret = dict_get_int32 (dict, key, (int32_t *)&status_rcd);
  1110. if (ret)
  1111. gf_log (THIS->name, GF_LOG_TRACE,
  1112. "failed to get status");
  1113. memset (key, 0, 256);
  1114. snprintf (key, 256, "failures-%d", i);
  1115. ret = dict_get_uint64 (dict, key, &failures);
  1116. if (ret)
  1117. gf_log (THIS->name, GF_LOG_TRACE,
  1118. "failed to get failures count");
  1119. memset (key, 0, 256);
  1120. snprintf (key, 256, "run-time-%d", i);
  1121. ret = dict_get_double (dict, key, &elapsed);
  1122. if (ret)
  1123. gf_log (THIS->name, GF_LOG_TRACE,
  1124. "failed to get run-time");
  1125. switch (status_rcd) {
  1126. case GF_DEFRAG_STATUS_NOT_STARTED:
  1127. status = "not started";
  1128. break;
  1129. case GF_DEFRAG_STATUS_STARTED:
  1130. status = "in progress";
  1131. break;
  1132. case GF_DEFRAG_STATUS_STOPPED:
  1133. status = "stopped";
  1134. break;
  1135. case GF_DEFRAG_STATUS_COMPLETE:
  1136. status = "completed";
  1137. break;
  1138. case GF_DEFRAG_STATUS_FAILED:
  1139. status = "failed";
  1140. break;
  1141. }
  1142. size_str = gf_uint64_2human_readable(size);
  1143. cli_out ("%40s %16"PRIu64 " %13s" " %13"PRIu64 " %13"PRIu64
  1144. " %14s %16.2f", node_uuid, files, size_str, lookup,
  1145. failures, status, elapsed);
  1146. GF_FREE(size_str);
  1147. i++;
  1148. } while (i <= counter);
  1149. done:
  1150. if (rsp.op_ret)
  1151. cli_err ("volume rebalance: %s: failed: %s", volname, msg);
  1152. else
  1153. cli_out ("volume rebalance: %s: success: %s", volname, msg);
  1154. ret = rsp.op_ret;
  1155. out:
  1156. free (rsp.op_errstr); //malloced by xdr
  1157. free (rsp.dict.dict_val); //malloced by xdr
  1158. if (dict)
  1159. dict_unref (dict);
  1160. cli_cmd_broadcast_response (ret);
  1161. return ret;
  1162. }
  1163. int
  1164. gf_cli_rename_volume_cbk (struct rpc_req *req, struct iovec *iov,
  1165. int count, void *myframe)
  1166. {
  1167. gf_cli_rsp rsp = {0,};
  1168. int ret = -1;
  1169. char msg[1024] = {0,};
  1170. if (-1 == req->rpc_status) {
  1171. goto out;
  1172. }
  1173. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  1174. if (ret < 0) {
  1175. gf_log ("", GF_LOG_ERROR, "error");
  1176. goto out;
  1177. }
  1178. gf_log ("cli", GF_LOG_INFO, "Received resp to probe");
  1179. snprintf (msg, sizeof (msg), "Rename volume %s",
  1180. (rsp.op_ret) ? "unsuccessful": "successful");
  1181. if (global_state->mode & GLUSTER_MODE_XML) {
  1182. ret = cli_xml_output_str ("volRename", msg, rsp.op_ret,
  1183. rsp.op_errno, rsp.op_errstr);
  1184. if (ret)
  1185. gf_log ("cli", GF_LOG_ERROR,
  1186. "Error outputting to xml");
  1187. goto out;
  1188. }
  1189. if (rsp.op_ret)
  1190. cli_err ("volume rename: failed");
  1191. else
  1192. cli_out ("volume rename: success");
  1193. ret = rsp.op_ret;
  1194. out:
  1195. cli_cmd_broadcast_response (ret);
  1196. return ret;
  1197. }
  1198. int
  1199. gf_cli_reset_volume_cbk (struct rpc_req *req, struct iovec *iov,
  1200. int count, void *myframe)
  1201. {
  1202. gf_cli_rsp rsp = {0,};
  1203. int ret = -1;
  1204. char msg[1024] = {0,};
  1205. if (-1 == req->rpc_status) {
  1206. goto out;
  1207. }
  1208. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  1209. if (ret < 0) {
  1210. gf_log ("", GF_LOG_ERROR, "error");
  1211. goto out;
  1212. }
  1213. gf_log ("cli", GF_LOG_INFO, "Received resp to reset");
  1214. if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
  1215. snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
  1216. else
  1217. snprintf (msg, sizeof (msg), "reset volume %s",
  1218. (rsp.op_ret) ? "unsuccessful": "successful");
  1219. if (global_state->mode & GLUSTER_MODE_XML) {
  1220. ret = cli_xml_output_str ("volReset", msg, rsp.op_ret,
  1221. rsp.op_errno, rsp.op_errstr);
  1222. if (ret)
  1223. gf_log ("cli", GF_LOG_ERROR,
  1224. "Error outputting to xml");
  1225. goto out;
  1226. }
  1227. if (rsp.op_ret)
  1228. cli_err ("volume reset: failed: %s", msg);
  1229. else
  1230. cli_out ("volume reset: success");
  1231. ret = rsp.op_ret;
  1232. out:
  1233. cli_cmd_broadcast_response (ret);
  1234. return ret;
  1235. }
  1236. int
  1237. gf_cli_set_volume_cbk (struct rpc_req *req, struct iovec *iov,
  1238. int count, void *myframe)
  1239. {
  1240. gf_cli_rsp rsp = {0,};
  1241. int ret = -1;
  1242. dict_t *dict = NULL;
  1243. char *help_str = NULL;
  1244. char msg[1024] = {0,};
  1245. if (-1 == req->rpc_status) {
  1246. goto out;
  1247. }
  1248. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  1249. if (ret < 0) {
  1250. gf_log ("", GF_LOG_ERROR, "error");
  1251. goto out;
  1252. }
  1253. gf_log ("cli", GF_LOG_INFO, "Received resp to set");
  1254. dict = dict_new ();
  1255. if (!dict) {
  1256. ret = -1;
  1257. goto out;
  1258. }
  1259. ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
  1260. if (dict_get_str (dict, "help-str", &help_str) && !msg[0])
  1261. snprintf (msg, sizeof (msg), "Set volume %s",
  1262. (rsp.op_ret) ? "unsuccessful": "successful");
  1263. if ((global_state->mode & GLUSTER_MODE_XML) && (help_str == NULL)) {
  1264. ret = cli_xml_output_str ("volSet", msg, rsp.op_ret,
  1265. rsp.op_errno, rsp.op_errstr);
  1266. if (ret)
  1267. gf_log ("cli", GF_LOG_ERROR,
  1268. "Error outputting to xml");
  1269. goto out;
  1270. }
  1271. if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
  1272. cli_err ("volume set: failed: %s", rsp.op_errstr);
  1273. if (!rsp.op_ret) {
  1274. if (help_str == NULL)
  1275. cli_out ("volume set: success");
  1276. else
  1277. cli_out ("%s", help_str);
  1278. } else {
  1279. cli_err ("volume set: failed");
  1280. }
  1281. ret = rsp.op_ret;
  1282. out:
  1283. if (dict)
  1284. dict_unref (dict);
  1285. cli_cmd_broadcast_response (ret);
  1286. return ret;
  1287. }
  1288. int
  1289. gf_cli_add_brick_cbk (struct rpc_req *req, struct iovec *iov,
  1290. int count, void *myframe)
  1291. {
  1292. gf_cli_rsp rsp = {0,};
  1293. int ret = -1;
  1294. char msg[1024] = {0,};
  1295. if (-1 == req->rpc_status) {
  1296. goto out;
  1297. }
  1298. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  1299. if (ret < 0) {
  1300. gf_log ("", GF_LOG_ERROR, "error");
  1301. goto out;
  1302. }
  1303. gf_log ("cli", GF_LOG_INFO, "Received resp to add brick");
  1304. if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
  1305. snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
  1306. else
  1307. snprintf (msg, sizeof (msg), "Add Brick %s",
  1308. (rsp.op_ret) ? "unsuccessful": "successful");
  1309. if (global_state->mode & GLUSTER_MODE_XML) {
  1310. ret = cli_xml_output_str ("volAddBrick", msg, rsp.op_ret,
  1311. rsp.op_errno, rsp.op_errstr);
  1312. if (ret)
  1313. gf_log ("cli", GF_LOG_ERROR,
  1314. "Error outputting to xml");
  1315. goto out;
  1316. }
  1317. if (rsp.op_ret)
  1318. cli_err ("volume add-brick: failed: %s", rsp.op_errstr);
  1319. else
  1320. cli_out ("volume add-brick: success");
  1321. ret = rsp.op_ret;
  1322. out:
  1323. cli_cmd_broadcast_response (ret);
  1324. free (rsp.dict.dict_val);
  1325. free (rsp.op_errstr);
  1326. return ret;
  1327. }
  1328. int
  1329. gf_cli3_remove_brick_status_cbk (struct rpc_req *req, struct iovec *iov,
  1330. int count, void *myframe)
  1331. {
  1332. gf_cli_rsp rsp = {0,};
  1333. char *status = "unknown";
  1334. int ret = -1;
  1335. uint64_t files = 0;
  1336. uint64_t size = 0;
  1337. uint64_t lookup = 0;
  1338. dict_t *dict = NULL;
  1339. char msg[1024] = {0,};
  1340. char key[256] = {0,};
  1341. int32_t i = 1;
  1342. int32_t counter = 0;
  1343. char *node_uuid = 0;
  1344. gf_defrag_status_t status_rcd = GF_DEFRAG_STATUS_NOT_STARTED;
  1345. uint64_t failures = 0;
  1346. double elapsed = 0;
  1347. char *size_str = NULL;
  1348. if (-1 == req->rpc_status) {
  1349. goto out;
  1350. }
  1351. ret = xdr_to_generic (*iov, &rsp,
  1352. (xdrproc_t)xdr_gf_cli_rsp);
  1353. if (ret < 0) {
  1354. gf_log ("", GF_LOG_ERROR, "error");
  1355. goto out;
  1356. }
  1357. ret = rsp.op_ret;
  1358. if (rsp.op_ret == -1) {
  1359. if (strcmp (rsp.op_errstr, ""))
  1360. snprintf (msg, sizeof (msg), "volume remove-brick: "
  1361. "failed: %s", rsp.op_errstr);
  1362. else
  1363. snprintf (msg, sizeof (msg), "volume remove-brick: "
  1364. "failed: status getting failed");
  1365. if (global_state->mode & GLUSTER_MODE_XML)
  1366. goto xml_output;
  1367. cli_err ("%s", msg);
  1368. goto out;
  1369. }
  1370. if (rsp.dict.dict_len) {
  1371. /* Unserialize the dictionary */
  1372. dict = dict_new ();
  1373. ret = dict_unserialize (rsp.dict.dict_val,
  1374. rsp.dict.dict_len,
  1375. &dict);
  1376. if (ret < 0) {
  1377. strncpy (msg, "failed to unserialize req-buffer to "
  1378. "dictionary", sizeof (msg));
  1379. if (global_state->mode & GLUSTER_MODE_XML) {
  1380. rsp.op_ret = -1;
  1381. goto xml_output;
  1382. }
  1383. gf_log ("cli", GF_LOG_ERROR, "%s", msg);
  1384. goto out;
  1385. }
  1386. }
  1387. xml_output:
  1388. if (global_state->mode & GLUSTER_MODE_XML) {
  1389. if (strcmp (rsp.op_errstr, "")) {
  1390. ret = cli_xml_output_vol_remove_brick (_gf_true, dict,
  1391. rsp.op_ret,
  1392. rsp.op_errno,
  1393. rsp.op_errstr);
  1394. } else {
  1395. ret = cli_xml_output_vol_remove_brick (_gf_true, dict,
  1396. rsp.op_ret,
  1397. rsp.op_errno,
  1398. msg);
  1399. }
  1400. goto out;
  1401. }
  1402. ret = dict_get_int32 (dict, "count", &counter);
  1403. if (ret) {
  1404. gf_log (THIS->name, GF_LOG_ERROR, "count not set");
  1405. goto out;
  1406. }
  1407. cli_out ("%40s %16s %13s %13s %13s %14s %s", "Node", "Rebalanced-files",
  1408. "size", "scanned", "failures", "status", "run-time in secs");
  1409. cli_out ("%40s %16s %13s %13s %13s %14s %16s", "---------",
  1410. "-----------", "-----------", "-----------", "-----------",
  1411. "------------", "--------------");
  1412. do {
  1413. snprintf (key, 256, "node-uuid-%d", i);
  1414. ret = dict_get_str (dict, key, &node_uuid);
  1415. if (ret)
  1416. gf_log (THIS->name, GF_LOG_TRACE,
  1417. "failed to get node-uuid");
  1418. memset (key, 0, 256);
  1419. snprintf (key, 256, "files-%d", i);
  1420. ret = dict_get_uint64 (dict, key, &files);
  1421. if (ret)
  1422. gf_log (THIS->name, GF_LOG_TRACE,
  1423. "failed to get file count");
  1424. memset (key, 0, 256);
  1425. snprintf (key, 256, "size-%d", i);
  1426. ret = dict_get_uint64 (dict, key, &size);
  1427. if (ret)
  1428. gf_log (THIS->name, GF_LOG_TRACE,
  1429. "failed to get size of xfer");
  1430. memset (key, 0, 256);
  1431. snprintf (key, 256, "lookups-%d", i);
  1432. ret = dict_get_uint64 (dict, key, &lookup);
  1433. if (ret)
  1434. gf_log (THIS->name, GF_LOG_TRACE,
  1435. "failed to get lookedup file count");
  1436. memset (key, 0, 256);
  1437. snprintf (key, 256, "status-%d", i);
  1438. ret = dict_get_int32 (dict, key, (int32_t *)&status_rcd);
  1439. if (ret)
  1440. gf_log (THIS->name, GF_LOG_TRACE,
  1441. "failed to get status");
  1442. snprintf (key, 256, "failures-%d", i);
  1443. ret = dict_get_uint64 (dict, key, &failures);
  1444. if (ret)
  1445. gf_log (THIS->name, GF_LOG_TRACE,
  1446. "Failed to get failure on files");
  1447. memset (key, 0, 256);
  1448. snprintf (key, 256, "run-time-%d", i);
  1449. ret = dict_get_double (dict, key, &elapsed);
  1450. if (ret)
  1451. gf_log (THIS->name, GF_LOG_TRACE,
  1452. "Failed to get run-time");
  1453. switch (status_rcd) {
  1454. case GF_DEFRAG_STATUS_NOT_STARTED:
  1455. status = "not started";
  1456. break;
  1457. case GF_DEFRAG_STATUS_STARTED:
  1458. status = "in progress";
  1459. break;
  1460. case GF_DEFRAG_STATUS_STOPPED:
  1461. status = "stopped";
  1462. break;
  1463. case GF_DEFRAG_STATUS_COMPLETE:
  1464. status = "completed";
  1465. break;
  1466. case GF_DEFRAG_STATUS_FAILED:
  1467. status = "failed";
  1468. break;
  1469. }
  1470. size_str = gf_uint64_2human_readable(size);
  1471. cli_out ("%40s %16"PRIu64 " %13s" " %13"PRIu64 " %13"PRIu64
  1472. " %14s %16.2f", node_uuid, files, size_str, lookup,
  1473. failures, status, elapsed);
  1474. GF_FREE(size_str);
  1475. i++;
  1476. } while (i <= counter);
  1477. out:
  1478. free (rsp.dict.dict_val); //malloced by xdr
  1479. if (dict)
  1480. dict_unref (dict);
  1481. cli_cmd_broadcast_response (ret);
  1482. return ret;
  1483. }
  1484. int
  1485. gf_cli_remove_brick_cbk (struct rpc_req *req, struct iovec *iov,
  1486. int count, void *myframe)
  1487. {
  1488. gf_cli_rsp rsp = {0,};
  1489. int ret = -1;
  1490. char msg[1024] = {0,};
  1491. gf1_op_commands cmd = GF_OP_CMD_NONE;
  1492. char *cmd_str = "unknown";
  1493. cli_local_t *local = NULL;
  1494. call_frame_t *frame = NULL;
  1495. char *task_id_str = NULL;
  1496. dict_t *rsp_dict = NULL;
  1497. if (-1 == req->rpc_status) {
  1498. goto out;
  1499. }
  1500. frame = myframe;
  1501. local = frame->local;
  1502. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  1503. if (ret < 0) {
  1504. gf_log ("", GF_LOG_ERROR, "error");
  1505. goto out;
  1506. }
  1507. ret = dict_get_int32 (local->dict, "command", (int32_t *)&cmd);
  1508. if (ret) {
  1509. gf_log ("", GF_LOG_ERROR, "failed to get command");
  1510. goto out;
  1511. }
  1512. if (rsp.dict.dict_len) {
  1513. rsp_dict = dict_new ();
  1514. if (!rsp_dict) {
  1515. ret = -1;
  1516. goto out;
  1517. }
  1518. ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len,
  1519. &rsp_dict);
  1520. if (ret) {
  1521. gf_log ("cli", GF_LOG_ERROR,
  1522. "Failed to unserialize rsp_dict");
  1523. goto out;
  1524. }
  1525. }
  1526. switch (cmd) {
  1527. case GF_OP_CMD_START:
  1528. cmd_str = "start";
  1529. ret = dict_get_str (rsp_dict, GF_REMOVE_BRICK_TID_KEY, &task_id_str);
  1530. if (ret) {
  1531. gf_log ("cli", GF_LOG_ERROR,
  1532. "remove-brick-id is not present in dict");
  1533. goto out;
  1534. }
  1535. break;
  1536. case GF_OP_CMD_COMMIT:
  1537. cmd_str = "commit";
  1538. break;
  1539. case GF_OP_CMD_COMMIT_FORCE:
  1540. cmd_str = "commit force";
  1541. break;
  1542. default:
  1543. cmd_str = "unknown";
  1544. break;
  1545. }
  1546. gf_log ("cli", GF_LOG_INFO, "Received resp to remove brick");
  1547. if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
  1548. snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
  1549. else
  1550. snprintf (msg, sizeof (msg), "Remove Brick %s %s", cmd_str,
  1551. (rsp.op_ret) ? "unsuccessful": "successful");
  1552. if (global_state->mode & GLUSTER_MODE_XML) {
  1553. ret = cli_xml_output_vol_remove_brick (_gf_false, rsp_dict,
  1554. rsp.op_ret, rsp.op_errno,
  1555. rsp.op_errstr);
  1556. if (ret)
  1557. gf_log ("cli", GF_LOG_ERROR,
  1558. "Error outputting to xml");
  1559. goto out;
  1560. }
  1561. if (rsp.op_ret) {
  1562. cli_err ("volume remove-brick %s: failed: %s", cmd_str,
  1563. rsp.op_errstr);
  1564. } else {
  1565. cli_out ("volume remove-brick %s: success", cmd_str);
  1566. if (GF_OP_CMD_START == cmd)
  1567. cli_out ("ID: %s", task_id_str);
  1568. }
  1569. ret = rsp.op_ret;
  1570. out:
  1571. cli_cmd_broadcast_response (ret);
  1572. free (rsp.dict.dict_val);
  1573. free (rsp.op_errstr);
  1574. return ret;
  1575. }
  1576. int
  1577. gf_cli_replace_brick_cbk (struct rpc_req *req, struct iovec *iov,
  1578. int count, void *myframe)
  1579. {
  1580. gf_cli_rsp rsp = {0,};
  1581. int ret = -1;
  1582. cli_local_t *local = NULL;
  1583. call_frame_t *frame = NULL;
  1584. dict_t *dict = NULL;
  1585. char *src_brick = NULL;
  1586. char *dst_brick = NULL;
  1587. char *status_reply = NULL;
  1588. gf1_cli_replace_op replace_op = 0;
  1589. char *rb_operation_str = NULL;
  1590. dict_t *rsp_dict = NULL;
  1591. char msg[1024] = {0,};
  1592. char *task_id_str = NULL;
  1593. if (-1 == req->rpc_status) {
  1594. goto out;
  1595. }
  1596. frame = (call_frame_t *) myframe;
  1597. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  1598. if (ret < 0) {
  1599. gf_log ("", GF_LOG_ERROR, "error");
  1600. goto out;
  1601. }
  1602. local = frame->local;
  1603. GF_ASSERT (local);
  1604. dict = local->dict;
  1605. ret = dict_get_int32 (dict, "operation", (int32_t *)&replace_op);
  1606. if (ret) {
  1607. gf_log ("", GF_LOG_DEBUG,
  1608. "dict_get on operation failed");
  1609. goto out;
  1610. }
  1611. if (rsp.dict.dict_len) {
  1612. /* Unserialize the dictionary */
  1613. rsp_dict = dict_new ();
  1614. ret = dict_unserialize (rsp.dict.dict_val,
  1615. rsp.dict.dict_len,
  1616. &rsp_dict);
  1617. if (ret < 0) {
  1618. gf_log ("glusterd", GF_LOG_ERROR,
  1619. "failed to "
  1620. "unserialize rsp buffer to dictionary");
  1621. goto out;
  1622. }
  1623. }
  1624. switch (replace_op) {
  1625. case GF_REPLACE_OP_START:
  1626. if (rsp.op_ret) {
  1627. rb_operation_str = gf_strdup ("replace-brick failed to"
  1628. " start");
  1629. } else {
  1630. ret = dict_get_str (rsp_dict, GF_REPLACE_BRICK_TID_KEY,
  1631. &task_id_str);
  1632. if (ret) {
  1633. gf_log ("cli", GF_LOG_ERROR, "Failed to get "
  1634. "\"replace-brick-id\" from dict");
  1635. goto out;
  1636. }
  1637. ret = gf_asprintf (&rb_operation_str,
  1638. "replace-brick started successfully"
  1639. "\nID: %s", task_id_str);
  1640. if (ret < 0)
  1641. goto out;
  1642. }
  1643. break;
  1644. case GF_REPLACE_OP_STATUS:
  1645. if (rsp.op_ret || ret) {
  1646. rb_operation_str = gf_strdup ("replace-brick status "
  1647. "unknown");
  1648. } else {
  1649. ret = dict_get_str (rsp_dict, "status-reply",
  1650. &status_reply);
  1651. if (ret) {
  1652. gf_log (THIS->name, GF_LOG_ERROR, "failed to"
  1653. "get status");
  1654. goto out;
  1655. }
  1656. rb_operation_str = gf_strdup (status_reply);
  1657. }
  1658. break;
  1659. case GF_REPLACE_OP_PAUSE:
  1660. if (rsp.op_ret)
  1661. rb_operation_str = gf_strdup ("replace-brick pause "
  1662. "failed");
  1663. else
  1664. rb_operation_str = gf_strdup ("replace-brick paused "
  1665. "successfully");
  1666. break;
  1667. case GF_REPLACE_OP_ABORT:
  1668. if (rsp.op_ret)
  1669. rb_operation_str = gf_strdup ("replace-brick abort "
  1670. "failed");
  1671. else
  1672. rb_operation_str = gf_strdup ("replace-brick aborted "
  1673. "successfully");
  1674. break;
  1675. case GF_REPLACE_OP_COMMIT:
  1676. case GF_REPLACE_OP_COMMIT_FORCE:
  1677. ret = dict_get_str (dict, "src-brick", &src_brick);
  1678. if (ret) {
  1679. gf_log ("", GF_LOG_DEBUG,
  1680. "dict_get on src-brick failed");
  1681. goto out;
  1682. }
  1683. ret = dict_get_str (dict, "dst-brick", &dst_brick);
  1684. if (ret) {
  1685. gf_log ("", GF_LOG_DEBUG,
  1686. "dict_get on dst-brick failed");
  1687. goto out;
  1688. }
  1689. if (rsp.op_ret || ret)
  1690. rb_operation_str = gf_strdup ("replace-brick commit "
  1691. "failed");
  1692. else
  1693. rb_operation_str = gf_strdup ("replace-brick commit "
  1694. "successful");
  1695. break;
  1696. default:
  1697. gf_log ("", GF_LOG_DEBUG,
  1698. "Unknown operation");
  1699. break;
  1700. }
  1701. if (rsp.op_ret && (strcmp (rsp.op_errstr, ""))) {
  1702. rb_operation_str = gf_strdup (rsp.op_errstr);
  1703. }
  1704. gf_log ("cli", GF_LOG_INFO, "Received resp to replace brick");
  1705. snprintf (msg, sizeof (msg), "%s",
  1706. rb_operation_str ? rb_operation_str : "Unknown operation");
  1707. if (global_state->mode & GLUSTER_MODE_XML) {
  1708. ret = cli_xml_output_vol_replace_brick (replace_op, rsp_dict,
  1709. rsp.op_ret,
  1710. rsp.op_errno, msg);
  1711. if (ret)
  1712. gf_log ("cli", GF_LOG_ERROR,
  1713. "Error outputting to xml");
  1714. goto out;
  1715. }
  1716. if (rsp.op_ret)
  1717. cli_err ("volume replace-brick: failed: %s", msg);
  1718. else
  1719. cli_out ("volume replace-brick: success: %s", msg);
  1720. ret = rsp.op_ret;
  1721. out:
  1722. if (frame)
  1723. frame->local = NULL;
  1724. if (local) {
  1725. dict_unref (local->dict);
  1726. cli_local_wipe (local);
  1727. }
  1728. if (rb_operation_str)
  1729. GF_FREE (rb_operation_str);
  1730. cli_cmd_broadcast_response (ret);
  1731. free (rsp.dict.dict_val);
  1732. if (rsp_dict)
  1733. dict_unref (rsp_dict);
  1734. return ret;
  1735. }
  1736. static int
  1737. gf_cli_log_rotate_cbk (struct rpc_req *req, struct iovec *iov,
  1738. int count, void *myframe)
  1739. {
  1740. gf_cli_rsp rsp = {0,};
  1741. int ret = -1;
  1742. char msg[1024] = {0,};
  1743. if (-1 == req->rpc_status) {
  1744. goto out;
  1745. }
  1746. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  1747. if (ret < 0) {
  1748. gf_log ("", GF_LOG_ERROR, "error");
  1749. goto out;
  1750. }
  1751. gf_log ("cli", GF_LOG_DEBUG, "Received resp to log rotate");
  1752. if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
  1753. snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
  1754. else
  1755. snprintf (msg, sizeof (msg), "log rotate %s",
  1756. (rsp.op_ret) ? "unsuccessful": "successful");
  1757. if (global_state->mode & GLUSTER_MODE_XML) {
  1758. ret = cli_xml_output_str ("volLogRotate", msg, rsp.op_ret,
  1759. rsp.op_errno, rsp.op_errstr);
  1760. if (ret)
  1761. gf_log ("cli", GF_LOG_ERROR,
  1762. "Error outputting to xml");
  1763. goto out;
  1764. }
  1765. if (rsp.op_ret)
  1766. cli_err ("volume log-rotate: failed: %s", msg);
  1767. else
  1768. cli_out ("volume log-rotate: success");
  1769. ret = rsp.op_ret;
  1770. out:
  1771. cli_cmd_broadcast_response (ret);
  1772. free (rsp.dict.dict_val);
  1773. return ret;
  1774. }
  1775. static int
  1776. gf_cli_sync_volume_cbk (struct rpc_req *req, struct iovec *iov,
  1777. int count, void *myframe)
  1778. {
  1779. gf_cli_rsp rsp = {0,};
  1780. int ret = -1;
  1781. char msg[1024] = {0,};
  1782. if (-1 == req->rpc_status) {
  1783. goto out;
  1784. }
  1785. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  1786. if (ret < 0) {
  1787. gf_log ("", GF_LOG_ERROR, "error");
  1788. goto out;
  1789. }
  1790. gf_log ("cli", GF_LOG_DEBUG, "Received resp to sync");
  1791. if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
  1792. snprintf (msg, sizeof (msg), "volume sync: failed: %s",
  1793. rsp.op_errstr);
  1794. else
  1795. snprintf (msg, sizeof (msg), "volume sync: %s",
  1796. (rsp.op_ret) ? "failed": "success");
  1797. if (global_state->mode & GLUSTER_MODE_XML) {
  1798. ret = cli_xml_output_str ("volSync", msg, rsp.op_ret,
  1799. rsp.op_errno, rsp.op_errstr);
  1800. if (ret)
  1801. gf_log ("cli", GF_LOG_ERROR,
  1802. "Error outputting to xml");
  1803. goto out;
  1804. }
  1805. if (rsp.op_ret)
  1806. cli_err ("%s", msg);
  1807. else
  1808. cli_out ("%s", msg);
  1809. ret = rsp.op_ret;
  1810. out:
  1811. cli_cmd_broadcast_response (ret);
  1812. return ret;
  1813. }
  1814. int32_t
  1815. gf_cli_print_limit_list (char *volname, char *limit_list,
  1816. char *op_errstr)
  1817. {
  1818. int64_t size = 0;
  1819. int64_t limit_value = 0;
  1820. int32_t i, j;
  1821. int32_t len = 0, ret = -1;
  1822. char *size_str = NULL;
  1823. char path [PATH_MAX] = {0, };
  1824. char ret_str [1024] = {0, };
  1825. char value [1024] = {0, };
  1826. char mountdir [] = "/tmp/mntXXXXXX";
  1827. char abspath [PATH_MAX] = {0, };
  1828. char *colon_ptr = NULL;
  1829. runner_t runner = {0,};
  1830. GF_VALIDATE_OR_GOTO ("cli", volname, out);
  1831. GF_VALIDATE_OR_GOTO ("cli", limit_list, out);
  1832. if (!connected)
  1833. goto out;
  1834. len = strlen (limit_list);
  1835. if (len == 0) {
  1836. cli_err ("%s", op_errstr?op_errstr:"quota limit not set ");
  1837. goto out;
  1838. }
  1839. if (mkdtemp (mountdir) == NULL) {
  1840. gf_log ("cli", GF_LOG_WARNING, "failed to create a temporary "
  1841. "mount directory");
  1842. ret = -1;
  1843. goto out;
  1844. }
  1845. /* Mount a temporary client to fetch the disk usage
  1846. * of the directory on which the limit is set.
  1847. */
  1848. ret = runcmd (SBIN_DIR"/glusterfs", "-s",
  1849. "localhost", "--volfile-id", volname, "-l",
  1850. DEFAULT_LOG_FILE_DIRECTORY"/quota-list.log",
  1851. mountdir, NULL);
  1852. if (ret) {
  1853. gf_log ("cli", GF_LOG_WARNING, "failed to mount glusterfs client");
  1854. ret = -1;
  1855. goto rm_dir;
  1856. }
  1857. len = strlen (limit_list);
  1858. if (len == 0) {
  1859. cli_err ("quota limit not set ");
  1860. goto unmount;
  1861. }
  1862. i = 0;
  1863. cli_out ("\tpath\t\t limit_set\t size");
  1864. cli_out ("-----------------------------------------------------------"
  1865. "-----------------------");
  1866. while (i < len) {
  1867. j = 0;
  1868. while (limit_list [i] != ',' && limit_list [i] != '\0') {
  1869. path [j++] = limit_list[i++];
  1870. }
  1871. path [j] = '\0';
  1872. //here path[] contains both path and limit value
  1873. colon_ptr = strrchr (path, ':');
  1874. *colon_ptr = '\0';
  1875. strcpy (value, ++colon_ptr);
  1876. snprintf (abspath, sizeof (abspath), "%s/%s", mountdir, path);
  1877. ret = sys_lgetxattr (abspath, "trusted.limit.list", (void *) ret_str, 4096);
  1878. if (ret < 0) {
  1879. cli_out ("%-20s %10s", path, value);
  1880. } else {
  1881. sscanf (ret_str, "%"PRId64",%"PRId64, &size,
  1882. &limit_value);
  1883. size_str = gf_uint64_2human_readable ((uint64_t) size);
  1884. if (size_str == NULL) {
  1885. cli_out ("%-20s %10s %20"PRId64, path,
  1886. value, size);
  1887. } else {
  1888. cli_out ("%-20s %10s %20s", path,
  1889. value, size_str);
  1890. GF_FREE (size_str);
  1891. }
  1892. }
  1893. i++;
  1894. }
  1895. unmount:
  1896. runinit (&runner);
  1897. runner_add_args (&runner, "umount",
  1898. #if GF_LINUX_HOST_OS
  1899. "-l",
  1900. #endif
  1901. mountdir, NULL);
  1902. ret = runner_run_reuse (&runner);
  1903. if (ret)
  1904. runner_log (&runner, "cli", GF_LOG_WARNING, "error executing");
  1905. runner_end (&runner);
  1906. rm_dir:
  1907. rmdir (mountdir);
  1908. out:
  1909. return ret;
  1910. }
  1911. int
  1912. gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov,
  1913. int count, void *myframe)
  1914. {
  1915. gf_cli_rsp rsp = {0,};
  1916. int ret = -1;
  1917. dict_t *dict = NULL;
  1918. char *volname = NULL;
  1919. char *limit_list = NULL;
  1920. int32_t type = 0;
  1921. char msg[1024] = {0,};
  1922. if (-1 == req->rpc_status) {
  1923. goto out;
  1924. }
  1925. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  1926. if (ret < 0) {
  1927. gf_log ("", GF_LOG_ERROR, "error");
  1928. goto out;
  1929. }
  1930. if (rsp.op_ret &&
  1931. strcmp (rsp.op_errstr, "") == 0) {
  1932. snprintf (msg, sizeof (msg), "command unsuccessful %s",
  1933. rsp.op_errstr);
  1934. if (global_state->mode & GLUSTER_MODE_XML)
  1935. goto xml_output;
  1936. goto out;
  1937. }
  1938. if (rsp.dict.dict_len) {
  1939. /* Unserialize the dictionary */
  1940. dict = dict_new ();
  1941. ret = dict_unserialize (rsp.dict.dict_val,
  1942. rsp.dict.dict_len,
  1943. &dict);
  1944. if (ret < 0) {
  1945. gf_log ("glusterd", GF_LOG_ERROR,
  1946. "failed to "
  1947. "unserialize req-buffer to dictionary");
  1948. goto out;
  1949. }
  1950. }
  1951. ret = dict_get_str (dict, "volname", &volname);
  1952. if (ret)
  1953. gf_log (THIS->name, GF_LOG_TRACE,
  1954. "failed to get volname");
  1955. ret = dict_get_str (dict, "limit_list", &limit_list);
  1956. if (ret)
  1957. gf_log (THIS->name, GF_LOG_TRACE,
  1958. "failed to get limit_list");
  1959. ret = dict_get_int32 (dict, "type", &type);
  1960. if (ret)
  1961. gf_log (THIS->name, GF_LOG_TRACE,
  1962. "failed to get type");
  1963. if (type == GF_QUOTA_OPTION_TYPE_LIST) {
  1964. if (global_state->mode & GLUSTER_MODE_XML) {
  1965. ret = cli_xml_output_vol_quota_limit_list
  1966. (volname, limit_list, rsp.op_ret,
  1967. rsp.op_errno, rsp.op_errstr);
  1968. if (ret)
  1969. gf_log ("cli", GF_LOG_ERROR,
  1970. "Error outputting to xml");
  1971. goto out;
  1972. }
  1973. if (limit_list) {
  1974. gf_cli_print_limit_list (volname,
  1975. limit_list,
  1976. rsp.op_errstr);
  1977. } else {
  1978. gf_log ("cli", GF_LOG_INFO, "Received resp to quota "
  1979. "command ");
  1980. if (rsp.op_errstr)
  1981. snprintf (msg, sizeof (msg), "%s",
  1982. rsp.op_errstr);
  1983. }
  1984. } else {
  1985. gf_log ("cli", GF_LOG_INFO, "Received resp to quota command ");
  1986. if (rsp.op_errstr)
  1987. snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
  1988. else
  1989. snprintf (msg, sizeof (msg), "successful");
  1990. }
  1991. xml_output:
  1992. if (global_state->mode & GLUSTER_MODE_XML) {
  1993. ret = cli_xml_output_str ("volQuota", msg, rsp.op_ret,
  1994. rsp.op_errno, rsp.op_errstr);
  1995. if (ret)
  1996. gf_log ("cli", GF_LOG_ERROR,
  1997. "Error outputting to xml");
  1998. goto out;
  1999. }
  2000. if (strlen (msg) > 0) {
  2001. if (rsp.op_ret)
  2002. cli_err ("%s", msg);
  2003. else
  2004. cli_out ("%s", msg);
  2005. }
  2006. ret = rsp.op_ret;
  2007. out:
  2008. cli_cmd_broadcast_response (ret);
  2009. if (dict)
  2010. dict_unref (dict);
  2011. free (rsp.dict.dict_val);
  2012. return ret;
  2013. }
  2014. int
  2015. gf_cli_getspec_cbk (struct rpc_req *req, struct iovec *iov,
  2016. int count, void *myframe)
  2017. {
  2018. gf_getspec_rsp rsp = {0,};
  2019. int ret = -1;
  2020. char *spec = NULL;
  2021. if (-1 == req->rpc_status) {
  2022. goto out;
  2023. }
  2024. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
  2025. if (ret < 0 || rsp.op_ret == -1) {
  2026. gf_log ("", GF_LOG_ERROR, "error");
  2027. goto out;
  2028. }
  2029. gf_log ("cli", GF_LOG_INFO, "Received resp to getspec");
  2030. spec = GF_MALLOC (rsp.op_ret + 1, cli_mt_char);
  2031. if (!spec) {
  2032. gf_log("", GF_LOG_ERROR, "out of memory");
  2033. goto out;
  2034. }
  2035. memcpy (spec, rsp.spec, rsp.op_ret);
  2036. spec[rsp.op_ret] = '\0';
  2037. cli_out ("%s", spec);
  2038. GF_FREE (spec);
  2039. ret = 0;
  2040. out:
  2041. cli_cmd_broadcast_response (ret);
  2042. return ret;
  2043. }
  2044. int
  2045. gf_cli_pmap_b2p_cbk (struct rpc_req *req, struct iovec *iov,
  2046. int count, void *myframe)
  2047. {
  2048. pmap_port_by_brick_rsp rsp = {0,};
  2049. int ret = -1;
  2050. char *spec = NULL;
  2051. if (-1 == req->rpc_status) {
  2052. goto out;
  2053. }
  2054. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_pmap_port_by_brick_rsp);
  2055. if (ret < 0 || rsp.op_ret == -1) {
  2056. gf_log ("", GF_LOG_ERROR, "error");
  2057. goto out;
  2058. }
  2059. gf_log ("cli", GF_LOG_INFO, "Received resp to pmap b2p");
  2060. cli_out ("%d", rsp.port);
  2061. GF_FREE (spec);
  2062. ret = rsp.op_ret;
  2063. out:
  2064. cli_cmd_broadcast_response (ret);
  2065. return ret;
  2066. }
  2067. int32_t
  2068. gf_cli_probe (call_frame_t *frame, xlator_t *this,
  2069. void *data)
  2070. {
  2071. gf1_cli_probe_req req = {0,};
  2072. int ret = 0;
  2073. dict_t *dict = NULL;
  2074. char *hostname = NULL;
  2075. int port = 0;
  2076. if (!frame || !this || !data) {
  2077. ret = -1;
  2078. goto out;
  2079. }
  2080. dict = data;
  2081. ret = dict_get_str (dict, "hostname", &hostname);
  2082. if (ret)
  2083. goto out;
  2084. ret = dict_get_int32 (dict, "port", &port);
  2085. if (ret)
  2086. port = CLI_GLUSTERD_PORT;
  2087. req.hostname = hostname;
  2088. req.port = port;
  2089. ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
  2090. GLUSTER_CLI_PROBE, NULL,
  2091. this, gf_cli_probe_cbk,
  2092. (xdrproc_t)xdr_gf1_cli_probe_req);
  2093. out:
  2094. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2095. return ret;
  2096. }
  2097. int32_t
  2098. gf_cli_deprobe (call_frame_t *frame, xlator_t *this,
  2099. void *data)
  2100. {
  2101. gf1_cli_deprobe_req req = {0,};
  2102. int ret = 0;
  2103. dict_t *dict = NULL;
  2104. char *hostname = NULL;
  2105. int port = 0;
  2106. int flags = 0;
  2107. if (!frame || !this || !data) {
  2108. ret = -1;
  2109. goto out;
  2110. }
  2111. dict = data;
  2112. ret = dict_get_str (dict, "hostname", &hostname);
  2113. if (ret)
  2114. goto out;
  2115. ret = dict_get_int32 (dict, "port", &port);
  2116. if (ret)
  2117. port = CLI_GLUSTERD_PORT;
  2118. ret = dict_get_int32 (dict, "flags", &flags);
  2119. if (ret)
  2120. flags = 0;
  2121. req.hostname = hostname;
  2122. req.port = port;
  2123. req.flags = flags;
  2124. ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
  2125. GLUSTER_CLI_DEPROBE, NULL,
  2126. this, gf_cli_deprobe_cbk,
  2127. (xdrproc_t)xdr_gf1_cli_deprobe_req);
  2128. out:
  2129. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2130. return ret;
  2131. }
  2132. int32_t
  2133. gf_cli_list_friends (call_frame_t *frame, xlator_t *this,
  2134. void *data)
  2135. {
  2136. gf1_cli_peer_list_req req = {0,};
  2137. int ret = 0;
  2138. if (!frame || !this) {
  2139. ret = -1;
  2140. goto out;
  2141. }
  2142. req.flags = GF_CLI_LIST_ALL;
  2143. ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
  2144. GLUSTER_CLI_LIST_FRIENDS, NULL,
  2145. this, gf_cli_list_friends_cbk,
  2146. (xdrproc_t) xdr_gf1_cli_peer_list_req);
  2147. out:
  2148. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2149. return ret;
  2150. }
  2151. int32_t
  2152. gf_cli_get_next_volume (call_frame_t *frame, xlator_t *this,
  2153. void *data)
  2154. {
  2155. int ret = 0;
  2156. cli_cmd_volume_get_ctx_t *ctx = NULL;
  2157. cli_local_t *local = NULL;
  2158. if (!frame || !this || !data) {
  2159. ret = -1;
  2160. goto out;
  2161. }
  2162. ctx = data;
  2163. local = frame->local;
  2164. if (global_state->mode & GLUSTER_MODE_XML) {
  2165. ret = cli_xml_output_vol_info_begin (local, 0, 0, "");
  2166. if (ret) {
  2167. gf_log ("cli", GF_LOG_ERROR, "Error outputting to xml");
  2168. goto out;
  2169. }
  2170. }
  2171. ret = gf_cli_get_volume (frame, this, data);
  2172. if (!local || !local->get_vol.volname) {
  2173. if ((global_state->mode & GLUSTER_MODE_XML))
  2174. goto end_xml;
  2175. cli_err ("No volumes present");
  2176. goto out;
  2177. }
  2178. ctx->volname = local->get_vol.volname;
  2179. while (ctx->volname) {
  2180. ret = gf_cli_get_volume (frame, this, ctx);
  2181. if (ret)
  2182. goto out;
  2183. ctx->volname = local->get_vol.volname;
  2184. }
  2185. end_xml:
  2186. if (global_state->mode & GLUSTER_MODE_XML) {
  2187. ret = cli_xml_output_vol_info_end (local);
  2188. if (ret)
  2189. gf_log ("cli", GF_LOG_ERROR, "Error outputting to xml");
  2190. }
  2191. out:
  2192. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2193. return ret;
  2194. }
  2195. int32_t
  2196. gf_cli_get_volume (call_frame_t *frame, xlator_t *this,
  2197. void *data)
  2198. {
  2199. gf_cli_req req = {{0,}};
  2200. int ret = 0;
  2201. cli_cmd_volume_get_ctx_t *ctx = NULL;
  2202. dict_t *dict = NULL;
  2203. int32_t flags = 0;
  2204. if (!frame || !this || !data) {
  2205. ret = -1;
  2206. goto out;
  2207. }
  2208. ctx = data;
  2209. dict = dict_new ();
  2210. if (!dict)
  2211. goto out;
  2212. if (ctx->volname) {
  2213. ret = dict_set_str (dict, "volname", ctx->volname);
  2214. if (ret)
  2215. goto out;
  2216. }
  2217. flags = ctx->flags;
  2218. ret = dict_set_int32 (dict, "flags", flags);
  2219. if (ret) {
  2220. gf_log (THIS->name, GF_LOG_ERROR, "failed to set flags");
  2221. goto out;
  2222. }
  2223. ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
  2224. &req.dict.dict_len);
  2225. ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
  2226. GLUSTER_CLI_GET_VOLUME, NULL,
  2227. this, gf_cli_get_volume_cbk,
  2228. (xdrproc_t) xdr_gf_cli_req);
  2229. out:
  2230. if (dict)
  2231. dict_unref (dict);
  2232. GF_FREE (req.dict.dict_val);
  2233. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2234. return ret;
  2235. }
  2236. int32_t
  2237. gf_cli3_1_uuid_reset (call_frame_t *frame, xlator_t *this,
  2238. void *data)
  2239. {
  2240. gf_cli_req req = {{0,}};
  2241. int ret = 0;
  2242. dict_t *dict = NULL;
  2243. if (!frame || !this || !data) {
  2244. ret = -1;
  2245. goto out;
  2246. }
  2247. dict = data;
  2248. ret = cli_to_glusterd (&req, frame, gf_cli3_1_uuid_reset_cbk,
  2249. (xdrproc_t)xdr_gf_cli_req, dict,
  2250. GLUSTER_CLI_UUID_RESET, this, cli_rpc_prog,
  2251. NULL);
  2252. out:
  2253. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2254. return ret;
  2255. }
  2256. #ifdef HAVE_BD_XLATOR
  2257. int
  2258. gf_cli_bd_op_cbk (struct rpc_req *req, struct iovec *iov,
  2259. int count, void *myframe)
  2260. {
  2261. gf_cli_rsp rsp = {0,};
  2262. int ret = -1;
  2263. cli_local_t *local = NULL;
  2264. dict_t *dict = NULL;
  2265. dict_t *input_dict = NULL;
  2266. gf_xl_bd_op_t bd_op = GF_BD_OP_INVALID;
  2267. char *operation = NULL;
  2268. call_frame_t *frame = NULL;
  2269. if (-1 == req->rpc_status)
  2270. goto out;
  2271. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  2272. if (ret < 0) {
  2273. gf_log ("", GF_LOG_ERROR, "error");
  2274. goto out;
  2275. }
  2276. dict = dict_new ();
  2277. if (!dict) {
  2278. ret = -1;
  2279. goto out;
  2280. }
  2281. frame = myframe;
  2282. if (frame)
  2283. local = frame->local;
  2284. if (local) {
  2285. input_dict = local->dict;
  2286. ret = dict_get_int32 (input_dict, "bd-op",
  2287. (int32_t *)&bd_op);
  2288. }
  2289. switch (bd_op) {
  2290. case GF_BD_OP_NEW_BD:
  2291. operation = gf_strdup ("create");
  2292. break;
  2293. case GF_BD_OP_DELETE_BD:
  2294. operation = gf_strdup ("delete");
  2295. break;
  2296. case GF_BD_OP_CLONE_BD:
  2297. operation = gf_strdup ("clone");
  2298. break;
  2299. case GF_BD_OP_SNAPSHOT_BD:
  2300. operation = gf_strdup ("snapshot");
  2301. break;
  2302. default:
  2303. break;
  2304. }
  2305. ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
  2306. if (ret)
  2307. goto out;
  2308. gf_log ("cli", GF_LOG_INFO, "Received resp to %s bd op", operation);
  2309. if (global_state->mode & GLUSTER_MODE_XML) {
  2310. ret = cli_xml_output_dict ("BdOp", dict, rsp.op_ret,
  2311. rsp.op_errno, rsp.op_errstr);
  2312. if (ret)
  2313. gf_log ("cli", GF_LOG_ERROR,
  2314. "Error outputting to xml");
  2315. goto out;
  2316. }
  2317. if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
  2318. cli_err ("%s", rsp.op_errstr);
  2319. else
  2320. cli_out ("BD %s has been %s", operation,
  2321. (rsp.op_ret) ? "unsuccessful":
  2322. "successful.");
  2323. ret = rsp.op_ret;
  2324. out:
  2325. cli_cmd_broadcast_response (ret);
  2326. if (dict)
  2327. dict_unref (dict);
  2328. if (operation)
  2329. GF_FREE (operation);
  2330. if (rsp.dict.dict_val)
  2331. free (rsp.dict.dict_val);
  2332. if (rsp.op_errstr)
  2333. free (rsp.op_errstr);
  2334. return ret;
  2335. }
  2336. int32_t
  2337. gf_cli_bd_op (call_frame_t *frame, xlator_t *this,
  2338. void *data)
  2339. {
  2340. gf_cli_req req = { {0,} };
  2341. int ret = 0;
  2342. dict_t *dict = NULL;
  2343. if (!frame || !this || !data) {
  2344. ret = -1;
  2345. goto out;
  2346. }
  2347. dict = dict_ref ((dict_t *)data);
  2348. if (!dict)
  2349. goto out;
  2350. ret = dict_allocate_and_serialize (dict,
  2351. &req.dict.dict_val,
  2352. &req.dict.dict_len);
  2353. ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
  2354. GLUSTER_CLI_BD_OP, NULL,
  2355. this, gf_cli_bd_op_cbk,
  2356. (xdrproc_t) xdr_gf_cli_req);
  2357. out:
  2358. if (dict)
  2359. dict_unref (dict);
  2360. if (req.dict.dict_val)
  2361. GF_FREE (req.dict.dict_val);
  2362. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2363. return ret;
  2364. }
  2365. #endif
  2366. int32_t
  2367. gf_cli_create_volume (call_frame_t *frame, xlator_t *this,
  2368. void *data)
  2369. {
  2370. gf_cli_req req = {{0,}};
  2371. int ret = 0;
  2372. dict_t *dict = NULL;
  2373. if (!frame || !this || !data) {
  2374. ret = -1;
  2375. goto out;
  2376. }
  2377. dict = data;
  2378. ret = cli_to_glusterd (&req, frame, gf_cli_create_volume_cbk,
  2379. (xdrproc_t) xdr_gf_cli_req, dict,
  2380. GLUSTER_CLI_CREATE_VOLUME, this, cli_rpc_prog,
  2381. NULL);
  2382. out:
  2383. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2384. GF_FREE (req.dict.dict_val);
  2385. return ret;
  2386. }
  2387. int32_t
  2388. gf_cli_delete_volume (call_frame_t *frame, xlator_t *this,
  2389. void *data)
  2390. {
  2391. gf_cli_req req = {{0,}};
  2392. int ret = 0;
  2393. dict_t *dict = NULL;
  2394. if (!frame || !this || !data) {
  2395. ret = -1;
  2396. goto out;
  2397. }
  2398. dict = data;
  2399. ret = cli_to_glusterd (&req, frame, gf_cli_delete_volume_cbk,
  2400. (xdrproc_t) xdr_gf_cli_req, dict,
  2401. GLUSTER_CLI_DELETE_VOLUME, this, cli_rpc_prog,
  2402. NULL);
  2403. out:
  2404. GF_FREE (req.dict.dict_val);
  2405. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2406. return ret;
  2407. }
  2408. int32_t
  2409. gf_cli_start_volume (call_frame_t *frame, xlator_t *this,
  2410. void *data)
  2411. {
  2412. gf_cli_req req = {{0,}};
  2413. int ret = 0;
  2414. dict_t *dict = NULL;
  2415. if (!frame || !this || !data) {
  2416. ret = -1;
  2417. goto out;
  2418. }
  2419. dict = data;
  2420. ret = cli_to_glusterd (&req, frame, gf_cli_start_volume_cbk,
  2421. (xdrproc_t) xdr_gf_cli_req, dict,
  2422. GLUSTER_CLI_START_VOLUME, this, cli_rpc_prog,
  2423. NULL);
  2424. out:
  2425. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2426. return ret;
  2427. }
  2428. int32_t
  2429. gf_cli_stop_volume (call_frame_t *frame, xlator_t *this,
  2430. void *data)
  2431. {
  2432. gf_cli_req req = {{0,}};
  2433. int ret = 0;
  2434. dict_t *dict = data;
  2435. if (!frame || !this || !data) {
  2436. ret = -1;
  2437. goto out;
  2438. }
  2439. dict = data;
  2440. ret = cli_to_glusterd (&req, frame, gf_cli_stop_volume_cbk,
  2441. (xdrproc_t) xdr_gf_cli_req, dict,
  2442. GLUSTER_CLI_STOP_VOLUME, this, cli_rpc_prog,
  2443. NULL);
  2444. out:
  2445. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2446. return ret;
  2447. }
  2448. int32_t
  2449. gf_cli_defrag_volume (call_frame_t *frame, xlator_t *this,
  2450. void *data)
  2451. {
  2452. gf_cli_req req = {{0,}};
  2453. int ret = 0;
  2454. dict_t *dict = NULL;
  2455. if (!frame || !this || !data) {
  2456. ret = -1;
  2457. goto out;
  2458. }
  2459. dict = data;
  2460. ret = cli_to_glusterd (&req, frame, gf_cli_defrag_volume_cbk,
  2461. (xdrproc_t) xdr_gf_cli_req, dict,
  2462. GLUSTER_CLI_DEFRAG_VOLUME, this, cli_rpc_prog,
  2463. NULL);
  2464. out:
  2465. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2466. return ret;
  2467. }
  2468. int32_t
  2469. gf_cli_rename_volume (call_frame_t *frame, xlator_t *this,
  2470. void *data)
  2471. {
  2472. gf_cli_req req = {{0,}};
  2473. int ret = 0;
  2474. dict_t *dict = NULL;
  2475. if (!frame || !this || !data) {
  2476. ret = -1;
  2477. goto out;
  2478. }
  2479. dict = data;
  2480. ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
  2481. &req.dict.dict_len);
  2482. if (ret < 0) {
  2483. gf_log (this->name, GF_LOG_ERROR,
  2484. "failed to serialize the data");
  2485. goto out;
  2486. }
  2487. ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
  2488. GLUSTER_CLI_RENAME_VOLUME, NULL,
  2489. this, gf_cli_rename_volume_cbk,
  2490. (xdrproc_t) xdr_gf_cli_req);
  2491. out:
  2492. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2493. return ret;
  2494. }
  2495. int32_t
  2496. gf_cli_reset_volume (call_frame_t *frame, xlator_t *this,
  2497. void *data)
  2498. {
  2499. gf_cli_req req = {{0,}};
  2500. int ret = 0;
  2501. dict_t *dict = NULL;
  2502. if (!frame || !this || !data) {
  2503. ret = -1;
  2504. goto out;
  2505. }
  2506. dict = data;
  2507. ret = cli_to_glusterd (&req, frame, gf_cli_reset_volume_cbk,
  2508. (xdrproc_t) xdr_gf_cli_req, dict,
  2509. GLUSTER_CLI_RESET_VOLUME, this, cli_rpc_prog,
  2510. NULL);
  2511. out:
  2512. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2513. return ret;
  2514. }
  2515. int32_t
  2516. gf_cli_set_volume (call_frame_t *frame, xlator_t *this,
  2517. void *data)
  2518. {
  2519. gf_cli_req req = {{0,}};
  2520. int ret = 0;
  2521. dict_t *dict = NULL;
  2522. if (!frame || !this || !data) {
  2523. ret = -1;
  2524. goto out;
  2525. }
  2526. dict = data;
  2527. ret = cli_to_glusterd (&req, frame, gf_cli_set_volume_cbk,
  2528. (xdrproc_t) xdr_gf_cli_req, dict,
  2529. GLUSTER_CLI_SET_VOLUME, this, cli_rpc_prog,
  2530. NULL);
  2531. out:
  2532. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2533. return ret;
  2534. }
  2535. int32_t
  2536. gf_cli_add_brick (call_frame_t *frame, xlator_t *this,
  2537. void *data)
  2538. {
  2539. gf_cli_req req = {{0,}};
  2540. int ret = 0;
  2541. dict_t *dict = NULL;
  2542. char *volname = NULL;
  2543. int32_t count = 0;
  2544. if (!frame || !this || !data) {
  2545. ret = -1;
  2546. goto out;
  2547. }
  2548. dict = data;
  2549. ret = dict_get_str (dict, "volname", &volname);
  2550. if (ret)
  2551. goto out;
  2552. ret = dict_get_int32 (dict, "count", &count);
  2553. if (ret)
  2554. goto out;
  2555. ret = cli_to_glusterd (&req, frame, gf_cli_add_brick_cbk,
  2556. (xdrproc_t) xdr_gf_cli_req, dict,
  2557. GLUSTER_CLI_ADD_BRICK, this, cli_rpc_prog, NULL);
  2558. out:
  2559. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2560. GF_FREE (req.dict.dict_val);
  2561. return ret;
  2562. }
  2563. int32_t
  2564. gf_cli_remove_brick (call_frame_t *frame, xlator_t *this,
  2565. void *data)
  2566. {
  2567. gf_cli_req req = {{0,}};;
  2568. gf_cli_req status_req = {{0,}};;
  2569. int ret = 0;
  2570. dict_t *dict = NULL;
  2571. int32_t command = 0;
  2572. char *volname = NULL;
  2573. dict_t *req_dict = NULL;
  2574. int32_t cmd = 0;
  2575. if (!frame || !this || !data) {
  2576. ret = -1;
  2577. goto out;
  2578. }
  2579. dict = data;
  2580. ret = dict_get_str (dict, "volname", &volname);
  2581. if (ret)
  2582. goto out;
  2583. ret = dict_get_int32 (dict, "command", &command);
  2584. if (ret)
  2585. goto out;
  2586. if ((command != GF_OP_CMD_STATUS) &&
  2587. (command != GF_OP_CMD_STOP)) {
  2588. ret = cli_to_glusterd (&req, frame, gf_cli_remove_brick_cbk,
  2589. (xdrproc_t) xdr_gf_cli_req, dict,
  2590. GLUSTER_CLI_REMOVE_BRICK, this,
  2591. cli_rpc_prog, NULL);
  2592. } else {
  2593. /* Need rebalance status to be sent :-) */
  2594. req_dict = dict_new ();
  2595. if (!req_dict) {
  2596. ret = -1;
  2597. goto out;
  2598. }
  2599. ret = dict_set_str (req_dict, "volname", volname);
  2600. if (ret) {
  2601. gf_log (THIS->name, GF_LOG_ERROR,
  2602. "Failed to set dict");
  2603. goto out;
  2604. }
  2605. if (command == GF_OP_CMD_STATUS)
  2606. cmd |= GF_DEFRAG_CMD_STATUS;
  2607. else
  2608. cmd |= GF_DEFRAG_CMD_STOP;
  2609. ret = dict_set_int32 (req_dict, "rebalance-command", (int32_t) cmd);
  2610. if (ret) {
  2611. gf_log (THIS->name, GF_LOG_ERROR,
  2612. "Failed to set dict");
  2613. goto out;
  2614. }
  2615. ret = cli_to_glusterd (&status_req, frame,
  2616. gf_cli3_remove_brick_status_cbk,
  2617. (xdrproc_t) xdr_gf_cli_req, req_dict,
  2618. GLUSTER_CLI_DEFRAG_VOLUME, this,
  2619. cli_rpc_prog, NULL);
  2620. }
  2621. out:
  2622. if (req_dict)
  2623. dict_unref (req_dict);
  2624. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2625. GF_FREE (req.dict.dict_val);
  2626. GF_FREE (status_req.dict.dict_val);
  2627. return ret;
  2628. }
  2629. int32_t
  2630. gf_cli_replace_brick (call_frame_t *frame, xlator_t *this,
  2631. void *data)
  2632. {
  2633. gf_cli_req req = {{0,}};
  2634. int ret = 0;
  2635. dict_t *dict = NULL;
  2636. char *src_brick = NULL;
  2637. char *dst_brick = NULL;
  2638. char *volname = NULL;
  2639. int32_t op = 0;
  2640. if (!frame || !this || !data) {
  2641. ret = -1;
  2642. goto out;
  2643. }
  2644. dict = data;
  2645. ret = dict_get_int32 (dict, "operation", &op);
  2646. if (ret) {
  2647. gf_log (this->name, GF_LOG_DEBUG,
  2648. "dict_get on operation failed");
  2649. goto out;
  2650. }
  2651. ret = dict_get_str (dict, "volname", &volname);
  2652. if (ret) {
  2653. gf_log (this->name, GF_LOG_DEBUG,
  2654. "dict_get on volname failed");
  2655. goto out;
  2656. }
  2657. ret = dict_get_str (dict, "src-brick", &src_brick);
  2658. if (ret) {
  2659. gf_log (this->name, GF_LOG_DEBUG,
  2660. "dict_get on src-brick failed");
  2661. goto out;
  2662. }
  2663. ret = dict_get_str (dict, "dst-brick", &dst_brick);
  2664. if (ret) {
  2665. gf_log (this->name, GF_LOG_DEBUG,
  2666. "dict_get on dst-brick failed");
  2667. goto out;
  2668. }
  2669. gf_log (this->name, GF_LOG_DEBUG,
  2670. "Received command replace-brick %s with "
  2671. "%s with operation=%d", src_brick,
  2672. dst_brick, op);
  2673. ret = cli_to_glusterd (&req, frame, gf_cli_replace_brick_cbk,
  2674. (xdrproc_t) xdr_gf_cli_req, dict,
  2675. GLUSTER_CLI_REPLACE_BRICK, this, cli_rpc_prog,
  2676. NULL);
  2677. out:
  2678. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2679. GF_FREE (req.dict.dict_val);
  2680. return ret;
  2681. }
  2682. int32_t
  2683. gf_cli_log_rotate (call_frame_t *frame, xlator_t *this,
  2684. void *data)
  2685. {
  2686. gf_cli_req req = {{0,}};
  2687. int ret = 0;
  2688. dict_t *dict = NULL;
  2689. if (!frame || !this || !data) {
  2690. ret = -1;
  2691. goto out;
  2692. }
  2693. dict = data;
  2694. ret = cli_to_glusterd (&req, frame, gf_cli_log_rotate_cbk,
  2695. (xdrproc_t) xdr_gf_cli_req, dict,
  2696. GLUSTER_CLI_LOG_ROTATE, this, cli_rpc_prog,
  2697. NULL);
  2698. out:
  2699. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2700. GF_FREE (req.dict.dict_val);
  2701. return ret;
  2702. }
  2703. int32_t
  2704. gf_cli_sync_volume (call_frame_t *frame, xlator_t *this,
  2705. void *data)
  2706. {
  2707. int ret = 0;
  2708. gf_cli_req req = {{0,}};
  2709. dict_t *dict = NULL;
  2710. if (!frame || !this || !data) {
  2711. ret = -1;
  2712. goto out;
  2713. }
  2714. dict = data;
  2715. ret = cli_to_glusterd (&req, frame, gf_cli_sync_volume_cbk,
  2716. (xdrproc_t) xdr_gf_cli_req, dict,
  2717. GLUSTER_CLI_SYNC_VOLUME, this, cli_rpc_prog,
  2718. NULL);
  2719. out:
  2720. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2721. GF_FREE (req.dict.dict_val);
  2722. return ret;
  2723. }
  2724. int32_t
  2725. gf_cli_getspec (call_frame_t *frame, xlator_t *this,
  2726. void *data)
  2727. {
  2728. gf_getspec_req req = {0,};
  2729. int ret = 0;
  2730. dict_t *dict = NULL;
  2731. if (!frame || !this || !data) {
  2732. ret = -1;
  2733. goto out;
  2734. }
  2735. dict = data;
  2736. ret = dict_get_str (dict, "volid", &req.key);
  2737. if (ret)
  2738. goto out;
  2739. ret = cli_cmd_submit (&req, frame, &cli_handshake_prog,
  2740. GF_HNDSK_GETSPEC, NULL,
  2741. this, gf_cli_getspec_cbk,
  2742. (xdrproc_t) xdr_gf_getspec_req);
  2743. out:
  2744. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2745. return ret;
  2746. }
  2747. int32_t
  2748. gf_cli_quota (call_frame_t *frame, xlator_t *this,
  2749. void *data)
  2750. {
  2751. gf_cli_req req = {{0,}};
  2752. int ret = 0;
  2753. dict_t *dict = NULL;
  2754. if (!frame || !this || !data) {
  2755. ret = -1;
  2756. goto out;
  2757. }
  2758. dict = data;
  2759. ret = cli_to_glusterd (&req, frame, gf_cli_quota_cbk,
  2760. (xdrproc_t) xdr_gf_cli_req, dict,
  2761. GLUSTER_CLI_QUOTA, this, cli_rpc_prog, NULL);
  2762. out:
  2763. GF_FREE (req.dict.dict_val);
  2764. return ret;
  2765. }
  2766. int32_t
  2767. gf_cli_pmap_b2p (call_frame_t *frame, xlator_t *this, void *data)
  2768. {
  2769. pmap_port_by_brick_req req = {0,};
  2770. int ret = 0;
  2771. dict_t *dict = NULL;
  2772. if (!frame || !this || !data) {
  2773. ret = -1;
  2774. goto out;
  2775. }
  2776. dict = data;
  2777. ret = dict_get_str (dict, "brick", &req.brick);
  2778. if (ret)
  2779. goto out;
  2780. ret = cli_cmd_submit (&req, frame, &cli_pmap_prog,
  2781. GF_PMAP_PORTBYBRICK, NULL,
  2782. this, gf_cli_pmap_b2p_cbk,
  2783. (xdrproc_t) xdr_pmap_port_by_brick_req);
  2784. out:
  2785. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2786. return ret;
  2787. }
  2788. static int
  2789. gf_cli_fsm_log_cbk (struct rpc_req *req, struct iovec *iov,
  2790. int count, void *myframe)
  2791. {
  2792. gf1_cli_fsm_log_rsp rsp = {0,};
  2793. int ret = -1;
  2794. dict_t *dict = NULL;
  2795. int tr_count = 0;
  2796. char key[256] = {0};
  2797. int i = 0;
  2798. char *old_state = NULL;
  2799. char *new_state = NULL;
  2800. char *event = NULL;
  2801. char *time = NULL;
  2802. if (-1 == req->rpc_status) {
  2803. goto out;
  2804. }
  2805. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_fsm_log_rsp);
  2806. if (ret < 0) {
  2807. gf_log ("", GF_LOG_ERROR, "error");
  2808. goto out;
  2809. }
  2810. if (rsp.op_ret) {
  2811. if (strcmp (rsp.op_errstr, ""))
  2812. cli_err ("%s", rsp.op_errstr);
  2813. cli_err ("fsm log unsuccessful");
  2814. ret = rsp.op_ret;
  2815. goto out;
  2816. }
  2817. dict = dict_new ();
  2818. if (!dict) {
  2819. ret = -1;
  2820. goto out;
  2821. }
  2822. ret = dict_unserialize (rsp.fsm_log.fsm_log_val,
  2823. rsp.fsm_log.fsm_log_len,
  2824. &dict);
  2825. if (ret) {
  2826. cli_err ("bad response");
  2827. goto out;
  2828. }
  2829. ret = dict_get_int32 (dict, "count", &tr_count);
  2830. if (tr_count)
  2831. cli_out("number of transitions: %d", tr_count);
  2832. else
  2833. cli_err("No transitions");
  2834. for (i = 0; i < tr_count; i++) {
  2835. memset (key, 0, sizeof (key));
  2836. snprintf (key, sizeof (key), "log%d-old-state", i);
  2837. ret = dict_get_str (dict, key, &old_state);
  2838. if (ret)
  2839. goto out;
  2840. memset (key, 0, sizeof (key));
  2841. snprintf (key, sizeof (key), "log%d-event", i);
  2842. ret = dict_get_str (dict, key, &event);
  2843. if (ret)
  2844. goto out;
  2845. memset (key, 0, sizeof (key));
  2846. snprintf (key, sizeof (key), "log%d-new-state", i);
  2847. ret = dict_get_str (dict, key, &new_state);
  2848. if (ret)
  2849. goto out;
  2850. memset (key, 0, sizeof (key));
  2851. snprintf (key, sizeof (key), "log%d-time", i);
  2852. ret = dict_get_str (dict, key, &time);
  2853. if (ret)
  2854. goto out;
  2855. cli_out ("Old State: [%s]\n"
  2856. "New State: [%s]\n"
  2857. "Event : [%s]\n"
  2858. "timestamp: [%s]\n", old_state, new_state, event, time);
  2859. }
  2860. ret = rsp.op_ret;
  2861. out:
  2862. cli_cmd_broadcast_response (ret);
  2863. return ret;
  2864. }
  2865. int32_t
  2866. gf_cli_fsm_log (call_frame_t *frame, xlator_t *this, void *data)
  2867. {
  2868. int ret = -1;
  2869. gf1_cli_fsm_log_req req = {0,};
  2870. GF_ASSERT (frame);
  2871. GF_ASSERT (this);
  2872. GF_ASSERT (data);
  2873. if (!frame || !this || !data)
  2874. goto out;
  2875. req.name = data;
  2876. ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
  2877. GLUSTER_CLI_FSM_LOG, NULL,
  2878. this, gf_cli_fsm_log_cbk,
  2879. (xdrproc_t) xdr_gf1_cli_fsm_log_req);
  2880. out:
  2881. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  2882. return ret;
  2883. }
  2884. int
  2885. gf_cli_gsync_config_command (dict_t *dict)
  2886. {
  2887. runner_t runner = {0,};
  2888. char *subop = NULL;
  2889. char *gwd = NULL;
  2890. char *slave = NULL;
  2891. char *master = NULL;
  2892. char *op_name = NULL;
  2893. if (dict_get_str (dict, "subop", &subop) != 0)
  2894. return -1;
  2895. if (strcmp (subop, "get") != 0 && strcmp (subop, "get-all") != 0) {
  2896. cli_out (GEOREP" config updated successfully");
  2897. return 0;
  2898. }
  2899. if (dict_get_str (dict, "glusterd_workdir", &gwd) != 0 ||
  2900. dict_get_str (dict, "slave", &slave) != 0)
  2901. return -1;
  2902. if (dict_get_str (dict, "master", &master) != 0)
  2903. master = NULL;
  2904. if (dict_get_str (dict, "op_name", &op_name) != 0)
  2905. op_name = NULL;
  2906. runinit (&runner);
  2907. runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
  2908. runner_argprintf (&runner, "%s/"GSYNC_CONF, gwd);
  2909. if (master)
  2910. runner_argprintf (&runner, ":%s", master);
  2911. runner_add_arg (&runner, slave);
  2912. runner_argprintf (&runner, "--config-%s", subop);
  2913. if (op_name)
  2914. runner_add_arg (&runner, op_name);
  2915. return runner_run (&runner);
  2916. }
  2917. int
  2918. gf_cli_gsync_out_status (dict_t *dict)
  2919. {
  2920. int gsync_count = 0;
  2921. int i = 0;
  2922. int ret = 0;
  2923. char mst[PATH_MAX] = {0, };
  2924. char slv[PATH_MAX] = {0, };
  2925. char sts[PATH_MAX] = {0, };
  2926. char nds[PATH_MAX] = {0, };
  2927. char hyphens[100] = {0, };
  2928. char *mst_val = NULL;
  2929. char *slv_val = NULL;
  2930. char *sts_val = NULL;
  2931. char *nds_val = NULL;
  2932. cli_out ("%-20s %-20s %-50s %-10s", "NODE", "MASTER", "SLAVE", "STATUS");
  2933. for (i=0; i<sizeof(hyphens)-1; i++)
  2934. hyphens[i] = '-';
  2935. cli_out ("%s", hyphens);
  2936. ret = dict_get_int32 (dict, "gsync-count", &gsync_count);
  2937. if (ret) {
  2938. gf_log ("cli", GF_LOG_INFO, "No active geo-replication sessions"
  2939. "present for the selected");
  2940. ret = 0;
  2941. goto out;
  2942. }
  2943. for (i = 1; i <= gsync_count; i++) {
  2944. snprintf (nds, sizeof(nds), "node%d", i);
  2945. snprintf (mst, sizeof(mst), "master%d", i);
  2946. snprintf (slv, sizeof(slv), "slave%d", i);
  2947. snprintf (sts, sizeof(sts), "status%d", i);
  2948. ret = dict_get_str (dict, nds, &nds_val);
  2949. if (ret)
  2950. goto out;
  2951. ret = dict_get_str (dict, mst, &mst_val);
  2952. if (ret)
  2953. goto out;
  2954. ret = dict_get_str (dict, slv, &slv_val);
  2955. if (ret)
  2956. goto out;
  2957. ret = dict_get_str (dict, sts, &sts_val);
  2958. if (ret)
  2959. goto out;
  2960. cli_out ("%-20s %-20s %-50s %-10s", nds_val, mst_val,
  2961. slv_val, sts_val);
  2962. }
  2963. out:
  2964. return ret;
  2965. }
  2966. int
  2967. gf_cli_gsync_set_cbk (struct rpc_req *req, struct iovec *iov,
  2968. int count, void *myframe)
  2969. {
  2970. int ret = -1;
  2971. gf_cli_rsp rsp = {0, };
  2972. dict_t *dict = NULL;
  2973. char *gsync_status = NULL;
  2974. char *master = NULL;
  2975. char *slave = NULL;
  2976. int32_t type = 0;
  2977. if (req->rpc_status == -1) {
  2978. ret = -1;
  2979. goto out;
  2980. }
  2981. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  2982. if (ret < 0) {
  2983. gf_log ("", GF_LOG_ERROR,
  2984. "Unable to get response structure");
  2985. goto out;
  2986. }
  2987. dict = dict_new ();
  2988. if (!dict) {
  2989. ret = -1;
  2990. goto out;
  2991. }
  2992. ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
  2993. if (ret)
  2994. goto out;
  2995. if (global_state->mode & GLUSTER_MODE_XML) {
  2996. ret = cli_xml_output_vol_gsync (dict, rsp.op_ret, rsp.op_errno,
  2997. rsp.op_errstr);
  2998. if (ret)
  2999. gf_log ("cli", GF_LOG_ERROR,
  3000. "Error outputting to xml");
  3001. goto out;
  3002. }
  3003. if (rsp.op_ret) {
  3004. cli_err ("%s", rsp.op_errstr ? rsp.op_errstr :
  3005. GEOREP" command unsuccessful");
  3006. ret = rsp.op_ret;
  3007. goto out;
  3008. }
  3009. ret = dict_get_str (dict, "gsync-status", &gsync_status);
  3010. if (!ret)
  3011. cli_out ("%s", gsync_status);
  3012. else
  3013. ret = 0;
  3014. ret = dict_get_int32 (dict, "type", &type);
  3015. if (ret) {
  3016. gf_log (THIS->name, GF_LOG_ERROR, "failed to get type");
  3017. goto out;
  3018. }
  3019. switch (type) {
  3020. case GF_GSYNC_OPTION_TYPE_START:
  3021. case GF_GSYNC_OPTION_TYPE_STOP:
  3022. if (dict_get_str (dict, "master", &master) != 0)
  3023. master = "???";
  3024. if (dict_get_str (dict, "slave", &slave) != 0)
  3025. slave = "???";
  3026. cli_out ("%s " GEOREP " session between %s & %s"
  3027. " has been successful",
  3028. type == GF_GSYNC_OPTION_TYPE_START ?
  3029. "Starting" : "Stopping",
  3030. master, slave);
  3031. break;
  3032. case GF_GSYNC_OPTION_TYPE_CONFIG:
  3033. ret = gf_cli_gsync_config_command (dict);
  3034. break;
  3035. case GF_GSYNC_OPTION_TYPE_STATUS:
  3036. ret = gf_cli_gsync_out_status (dict);
  3037. goto out;
  3038. default:
  3039. cli_out (GEOREP" command executed successfully");
  3040. }
  3041. out:
  3042. if (dict)
  3043. dict_unref (dict);
  3044. cli_cmd_broadcast_response (ret);
  3045. free (rsp.dict.dict_val);
  3046. return ret;
  3047. }
  3048. int32_t
  3049. gf_cli_gsync_set (call_frame_t *frame, xlator_t *this,
  3050. void *data)
  3051. {
  3052. int ret = 0;
  3053. dict_t *dict = NULL;
  3054. gf_cli_req req = {{0,}};
  3055. if (!frame || !this || !data) {
  3056. ret = -1;
  3057. goto out;
  3058. }
  3059. dict = data;
  3060. ret = cli_to_glusterd (&req, frame, gf_cli_gsync_set_cbk,
  3061. (xdrproc_t) xdr_gf_cli_req, dict,
  3062. GLUSTER_CLI_GSYNC_SET, this, cli_rpc_prog,
  3063. NULL);
  3064. out:
  3065. GF_FREE (req.dict.dict_val);
  3066. return ret;
  3067. }
  3068. int
  3069. cli_profile_info_percentage_cmp (void *a, void *b)
  3070. {
  3071. cli_profile_info_t *ia = NULL;
  3072. cli_profile_info_t *ib = NULL;
  3073. int ret = 0;
  3074. ia = a;
  3075. ib = b;
  3076. if (ia->percentage_avg_latency < ib->percentage_avg_latency)
  3077. ret = -1;
  3078. else if (ia->percentage_avg_latency > ib->percentage_avg_latency)
  3079. ret = 1;
  3080. else
  3081. ret = 0;
  3082. return ret;
  3083. }
  3084. void
  3085. cmd_profile_volume_brick_out (dict_t *dict, int count, int interval)
  3086. {
  3087. char key[256] = {0};
  3088. int i = 0;
  3089. uint64_t sec = 0;
  3090. uint64_t r_count = 0;
  3091. uint64_t w_count = 0;
  3092. uint64_t rb_counts[32] = {0};
  3093. uint64_t wb_counts[32] = {0};
  3094. cli_profile_info_t profile_info[GF_FOP_MAXVALUE] = {{0}};
  3095. char output[128] = {0};
  3096. int per_line = 0;
  3097. char read_blocks[128] = {0};
  3098. char write_blocks[128] = {0};
  3099. int index = 0;
  3100. int is_header_printed = 0;
  3101. int ret = 0;
  3102. double total_percentage_latency = 0;
  3103. for (i = 0; i < 32; i++) {
  3104. memset (key, 0, sizeof (key));
  3105. snprintf (key, sizeof (key), "%d-%d-read-%d", count,
  3106. interval, (1 << i));
  3107. ret = dict_get_uint64 (dict, key, &rb_counts[i]);
  3108. }
  3109. for (i = 0; i < 32; i++) {
  3110. memset (key, 0, sizeof (key));
  3111. snprintf (key, sizeof (key), "%d-%d-write-%d", count, interval,
  3112. (1<<i));
  3113. ret = dict_get_uint64 (dict, key, &wb_counts[i]);
  3114. }
  3115. for (i = 0; i < GF_FOP_MAXVALUE; i++) {
  3116. memset (key, 0, sizeof (key));
  3117. snprintf (key, sizeof (key), "%d-%d-%d-hits", count,
  3118. interval, i);
  3119. ret = dict_get_uint64 (dict, key, &profile_info[i].fop_hits);
  3120. memset (key, 0, sizeof (key));
  3121. snprintf (key, sizeof (key), "%d-%d-%d-avglatency", count,
  3122. interval, i);
  3123. ret = dict_get_double (dict, key, &profile_info[i].avg_latency);
  3124. memset (key, 0, sizeof (key));
  3125. snprintf (key, sizeof (key), "%d-%d-%d-minlatency", count,
  3126. interval, i);
  3127. ret = dict_get_double (dict, key, &profile_info[i].min_latency);
  3128. memset (key, 0, sizeof (key));
  3129. snprintf (key, sizeof (key), "%d-%d-%d-maxlatency", count,
  3130. interval, i);
  3131. ret = dict_get_double (dict, key, &profile_info[i].max_latency);
  3132. profile_info[i].fop_name = (char *)gf_fop_list[i];
  3133. total_percentage_latency +=
  3134. (profile_info[i].fop_hits * profile_info[i].avg_latency);
  3135. }
  3136. if (total_percentage_latency) {
  3137. for (i = 0; i < GF_FOP_MAXVALUE; i++) {
  3138. profile_info[i].percentage_avg_latency = 100 * (
  3139. (profile_info[i].avg_latency* profile_info[i].fop_hits) /
  3140. total_percentage_latency);
  3141. }
  3142. gf_array_insertionsort (profile_info, 1, GF_FOP_MAXVALUE - 1,
  3143. sizeof (cli_profile_info_t),
  3144. cli_profile_info_percentage_cmp);
  3145. }
  3146. memset (key, 0, sizeof (key));
  3147. snprintf (key, sizeof (key), "%d-%d-duration", count, interval);
  3148. ret = dict_get_uint64 (dict, key, &sec);
  3149. memset (key, 0, sizeof (key));
  3150. snprintf (key, sizeof (key), "%d-%d-total-read", count, interval);
  3151. ret = dict_get_uint64 (dict, key, &r_count);
  3152. memset (key, 0, sizeof (key));
  3153. snprintf (key, sizeof (key), "%d-%d-total-write", count, interval);
  3154. ret = dict_get_uint64 (dict, key, &w_count);
  3155. if (ret == 0) {
  3156. }
  3157. if (interval == -1)
  3158. cli_out ("Cumulative Stats:");
  3159. else
  3160. cli_out ("Interval %d Stats:", interval);
  3161. snprintf (output, sizeof (output), "%14s", "Block Size:");
  3162. snprintf (read_blocks, sizeof (read_blocks), "%14s", "No. of Reads:");
  3163. snprintf (write_blocks, sizeof (write_blocks), "%14s", "No. of Writes:");
  3164. index = 14;
  3165. for (i = 0; i < 32; i++) {
  3166. if ((rb_counts[i] == 0) && (wb_counts[i] == 0))
  3167. continue;
  3168. per_line++;
  3169. snprintf (output+index, sizeof (output)-index, "%19db+ ", (1<<i));
  3170. if (rb_counts[i]) {
  3171. snprintf (read_blocks+index, sizeof (read_blocks)-index,
  3172. "%21"PRId64" ", rb_counts[i]);
  3173. } else {
  3174. snprintf (read_blocks+index, sizeof (read_blocks)-index,
  3175. "%21s ", "0");
  3176. }
  3177. if (wb_counts[i]) {
  3178. snprintf (write_blocks+index, sizeof (write_blocks)-index,
  3179. "%21"PRId64" ", wb_counts[i]);
  3180. } else {
  3181. snprintf (write_blocks+index, sizeof (write_blocks)-index,
  3182. "%21s ", "0");
  3183. }
  3184. index += 22;
  3185. if (per_line == 3) {
  3186. cli_out ("%s", output);
  3187. cli_out ("%s", read_blocks);
  3188. cli_out ("%s", write_blocks);
  3189. cli_out (" ");
  3190. per_line = 0;
  3191. memset (output, 0, sizeof (output));
  3192. memset (read_blocks, 0, sizeof (read_blocks));
  3193. memset (write_blocks, 0, sizeof (write_blocks));
  3194. snprintf (output, sizeof (output), "%14s", "Block Size:");
  3195. snprintf (read_blocks, sizeof (read_blocks), "%14s",
  3196. "No. of Reads:");
  3197. snprintf (write_blocks, sizeof (write_blocks), "%14s",
  3198. "No. of Writes:");
  3199. index = 14;
  3200. }
  3201. }
  3202. if (per_line != 0) {
  3203. cli_out ("%s", output);
  3204. cli_out ("%s", read_blocks);
  3205. cli_out ("%s", write_blocks);
  3206. }
  3207. for (i = 0; i < GF_FOP_MAXVALUE; i++) {
  3208. if (profile_info[i].fop_hits == 0)
  3209. continue;
  3210. if (is_header_printed == 0) {
  3211. cli_out ("%10s %13s %13s %13s %14s %11s", "%-latency",
  3212. "Avg-latency", "Min-Latency", "Max-Latency",
  3213. "No. of calls", "Fop");
  3214. cli_out ("%10s %13s %13s %13s %14s %11s", "---------",
  3215. "-----------", "-----------", "-----------",
  3216. "------------", "----");
  3217. is_header_printed = 1;
  3218. }
  3219. if (profile_info[i].fop_hits) {
  3220. cli_out ("%10.2lf %10.2lf us %10.2lf us %10.2lf us"
  3221. " %14"PRId64" %11s",
  3222. profile_info[i].percentage_avg_latency,
  3223. profile_info[i].avg_latency,
  3224. profile_info[i].min_latency,
  3225. profile_info[i].max_latency,
  3226. profile_info[i].fop_hits,
  3227. profile_info[i].fop_name);
  3228. }
  3229. }
  3230. cli_out (" ");
  3231. cli_out ("%12s: %"PRId64" seconds", "Duration", sec);
  3232. cli_out ("%12s: %"PRId64" bytes", "Data Read", r_count);
  3233. cli_out ("%12s: %"PRId64" bytes", "Data Written", w_count);
  3234. cli_out (" ");
  3235. }
  3236. int32_t
  3237. gf_cli_profile_volume_cbk (struct rpc_req *req, struct iovec *iov,
  3238. int count, void *myframe)
  3239. {
  3240. gf_cli_rsp rsp = {0,};
  3241. int ret = -1;
  3242. dict_t *dict = NULL;
  3243. gf1_cli_stats_op op = GF_CLI_STATS_NONE;
  3244. char key[256] = {0};
  3245. int interval = 0;
  3246. int i = 1;
  3247. int32_t brick_count = 0;
  3248. char *volname = NULL;
  3249. char *brick = NULL;
  3250. char str[1024] = {0,};
  3251. if (-1 == req->rpc_status) {
  3252. goto out;
  3253. }
  3254. gf_log ("cli", GF_LOG_DEBUG, "Received resp to profile");
  3255. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  3256. if (ret < 0) {
  3257. gf_log ("", GF_LOG_ERROR, "error");
  3258. goto out;
  3259. }
  3260. dict = dict_new ();
  3261. if (!dict) {
  3262. ret = -1;
  3263. goto out;
  3264. }
  3265. ret = dict_unserialize (rsp.dict.dict_val,
  3266. rsp.dict.dict_len,
  3267. &dict);
  3268. if (ret) {
  3269. gf_log ("", GF_LOG_ERROR,
  3270. "Unable to allocate memory");
  3271. goto out;
  3272. } else {
  3273. dict->extra_stdfree = rsp.dict.dict_val;
  3274. }
  3275. if (global_state->mode & GLUSTER_MODE_XML) {
  3276. ret = cli_xml_output_vol_profile (dict, rsp.op_ret,
  3277. rsp.op_errno,
  3278. rsp.op_errstr);
  3279. if (ret)
  3280. gf_log ("cli", GF_LOG_ERROR,
  3281. "Error outputting to xml");
  3282. goto out;
  3283. }
  3284. ret = dict_get_str (dict, "volname", &volname);
  3285. if (ret)
  3286. goto out;
  3287. ret = dict_get_int32 (dict, "op", (int32_t*)&op);
  3288. if (ret)
  3289. goto out;
  3290. if (rsp.op_ret && strcmp (rsp.op_errstr, "")) {
  3291. cli_err ("%s", rsp.op_errstr);
  3292. } else {
  3293. switch (op) {
  3294. case GF_CLI_STATS_START:
  3295. cli_out ("Starting volume profile on %s has been %s ",
  3296. volname,
  3297. (rsp.op_ret) ? "unsuccessful": "successful");
  3298. break;
  3299. case GF_CLI_STATS_STOP:
  3300. cli_out ("Stopping volume profile on %s has been %s ",
  3301. volname,
  3302. (rsp.op_ret) ? "unsuccessful": "successful");
  3303. break;
  3304. case GF_CLI_STATS_INFO:
  3305. break;
  3306. default:
  3307. cli_out ("volume profile on %s has been %s ",
  3308. volname,
  3309. (rsp.op_ret) ? "unsuccessful": "successful");
  3310. break;
  3311. }
  3312. }
  3313. if (rsp.op_ret) {
  3314. ret = rsp.op_ret;
  3315. goto out;
  3316. }
  3317. if (op != GF_CLI_STATS_INFO) {
  3318. ret = 0;
  3319. goto out;
  3320. }
  3321. ret = dict_get_int32 (dict, "count", &brick_count);
  3322. if (ret)
  3323. goto out;
  3324. if (!brick_count) {
  3325. cli_err ("All bricks of volume %s are down.", volname);
  3326. goto out;
  3327. }
  3328. while (i <= brick_count) {
  3329. memset (key, 0, sizeof (key));
  3330. snprintf (key, sizeof (key), "%d-brick", i);
  3331. ret = dict_get_str (dict, key, &brick);
  3332. if (ret) {
  3333. gf_log ("cli", GF_LOG_ERROR, "Couldn't get brick name");
  3334. goto out;
  3335. }
  3336. ret = dict_get_str_boolean (dict, "nfs", _gf_false);
  3337. if (ret)
  3338. snprintf (str, sizeof (str), "NFS Server : %s", brick);
  3339. else
  3340. snprintf (str, sizeof (str), "Brick: %s", brick);
  3341. cli_out ("%s", str);
  3342. memset (str, '-', strlen (str));
  3343. cli_out ("%s", str);
  3344. snprintf (key, sizeof (key), "%d-cumulative", i);
  3345. ret = dict_get_int32 (dict, key, &interval);
  3346. if (ret == 0) {
  3347. cmd_profile_volume_brick_out (dict, i, interval);
  3348. }
  3349. snprintf (key, sizeof (key), "%d-interval", i);
  3350. ret = dict_get_int32 (dict, key, &interval);
  3351. if (ret == 0) {
  3352. cmd_profile_volume_brick_out (dict, i, interval);
  3353. }
  3354. i++;
  3355. }
  3356. ret = rsp.op_ret;
  3357. out:
  3358. if (dict)
  3359. dict_unref (dict);
  3360. free (rsp.op_errstr);
  3361. cli_cmd_broadcast_response (ret);
  3362. return ret;
  3363. }
  3364. int32_t
  3365. gf_cli_profile_volume (call_frame_t *frame, xlator_t *this, void *data)
  3366. {
  3367. int ret = -1;
  3368. gf_cli_req req = {{0,}};
  3369. dict_t *dict = NULL;
  3370. GF_ASSERT (frame);
  3371. GF_ASSERT (this);
  3372. GF_ASSERT (data);
  3373. if (!frame || !this || !data)
  3374. goto out;
  3375. dict = data;
  3376. ret = cli_to_glusterd (&req, frame, gf_cli_profile_volume_cbk,
  3377. (xdrproc_t) xdr_gf_cli_req, dict,
  3378. GLUSTER_CLI_PROFILE_VOLUME, this, cli_rpc_prog,
  3379. NULL);
  3380. out:
  3381. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  3382. GF_FREE (req.dict.dict_val);
  3383. return ret;
  3384. }
  3385. int32_t
  3386. gf_cli_top_volume_cbk (struct rpc_req *req, struct iovec *iov,
  3387. int count, void *myframe)
  3388. {
  3389. gf_cli_rsp rsp = {0,};
  3390. int ret = -1;
  3391. dict_t *dict = NULL;
  3392. gf1_cli_stats_op op = GF_CLI_STATS_NONE;
  3393. char key[256] = {0};
  3394. int i = 0;
  3395. int32_t brick_count = 0;
  3396. char brick[1024];
  3397. int32_t members = 0;
  3398. char *filename;
  3399. char *bricks;
  3400. uint64_t value = 0;
  3401. int32_t j = 0;
  3402. gf1_cli_top_op top_op = GF_CLI_TOP_NONE;
  3403. uint64_t nr_open = 0;
  3404. uint64_t max_nr_open = 0;
  3405. double throughput = 0;
  3406. double time = 0;
  3407. int32_t time_sec = 0;
  3408. long int time_usec = 0;
  3409. char timestr[256] = {0, };
  3410. char *openfd_str = NULL;
  3411. gf_boolean_t nfs = _gf_false;
  3412. gf_boolean_t clear_stats = _gf_false;
  3413. int stats_cleared = 0;
  3414. if (-1 == req->rpc_status) {
  3415. goto out;
  3416. }
  3417. gf_log ("cli", GF_LOG_DEBUG, "Received resp to top");
  3418. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  3419. if (ret < 0) {
  3420. gf_log ("", GF_LOG_ERROR, "Unable to decode response");
  3421. goto out;
  3422. }
  3423. if (rsp.op_ret) {
  3424. if (strcmp (rsp.op_errstr, ""))
  3425. cli_err ("%s", rsp.op_errstr);
  3426. cli_err ("volume top unsuccessful");
  3427. ret = rsp.op_ret;
  3428. goto out;
  3429. }
  3430. dict = dict_new ();
  3431. if (!dict) {
  3432. ret = -1;
  3433. goto out;
  3434. }
  3435. ret = dict_unserialize (rsp.dict.dict_val,
  3436. rsp.dict.dict_len,
  3437. &dict);
  3438. if (ret) {
  3439. gf_log ("", GF_LOG_ERROR,
  3440. "Unable to allocate memory");
  3441. goto out;
  3442. }
  3443. ret = dict_get_int32 (dict, "op", (int32_t*)&op);
  3444. if (op != GF_CLI_STATS_TOP) {
  3445. ret = 0;
  3446. goto out;
  3447. }
  3448. if (global_state->mode & GLUSTER_MODE_XML) {
  3449. ret = cli_xml_output_vol_top (dict, rsp.op_ret,
  3450. rsp.op_errno,
  3451. rsp.op_errstr);
  3452. if (ret) {
  3453. gf_log ("cli", GF_LOG_ERROR,
  3454. "Error outputting to xml");
  3455. }
  3456. goto out;
  3457. }
  3458. ret = dict_get_int32 (dict, "count", &brick_count);
  3459. if (ret)
  3460. goto out;
  3461. snprintf (key, sizeof (key), "%d-top-op", 1);
  3462. ret = dict_get_int32 (dict, key, (int32_t*)&top_op);
  3463. if (ret)
  3464. goto out;
  3465. clear_stats = dict_get_str_boolean (dict, "clear-stats", _gf_false);
  3466. while (i < brick_count) {
  3467. i++;
  3468. snprintf (brick, sizeof (brick), "%d-brick", i);
  3469. ret = dict_get_str (dict, brick, &bricks);
  3470. if (ret)
  3471. goto out;
  3472. nfs = dict_get_str_boolean (dict, "nfs", _gf_false);
  3473. if (clear_stats) {
  3474. memset (key, 0, sizeof (key));
  3475. snprintf (key, sizeof (key), "%d-stats-cleared", i);
  3476. ret = dict_get_int32 (dict, key, &stats_cleared);
  3477. if (ret)
  3478. goto out;
  3479. cli_out (stats_cleared ? "Cleared stats for %s %s" :
  3480. "Failed to clear stats for %s %s",
  3481. nfs ? "NFS server on" : "brick", bricks);
  3482. continue;
  3483. }
  3484. if (nfs)
  3485. cli_out ("NFS Server : %s", bricks);
  3486. else
  3487. cli_out ("Brick: %s", bricks);
  3488. snprintf(key, sizeof (key), "%d-members", i);
  3489. ret = dict_get_int32 (dict, key, &members);
  3490. switch (top_op) {
  3491. case GF_CLI_TOP_OPEN:
  3492. snprintf (key, sizeof (key), "%d-current-open", i);
  3493. ret = dict_get_uint64 (dict, key, &nr_open);
  3494. if (ret)
  3495. break;
  3496. snprintf (key, sizeof (key), "%d-max-open", i);
  3497. ret = dict_get_uint64 (dict, key, &max_nr_open);
  3498. if (ret)
  3499. goto out;
  3500. snprintf (key, sizeof (key), "%d-max-openfd-time", i);
  3501. ret = dict_get_str (dict, key, &openfd_str);
  3502. if (ret)
  3503. goto out;
  3504. cli_out ("Current open fds: %"PRIu64", Max open"
  3505. " fds: %"PRIu64", Max openfd time: %s", nr_open,
  3506. max_nr_open, openfd_str);
  3507. case GF_CLI_TOP_READ:
  3508. case GF_CLI_TOP_WRITE:
  3509. case GF_CLI_TOP_OPENDIR:
  3510. case GF_CLI_TOP_READDIR:
  3511. if (!members) {
  3512. continue;
  3513. }
  3514. cli_out ("Count\t\tfilename\n=======================");
  3515. break;
  3516. case GF_CLI_TOP_READ_PERF:
  3517. case GF_CLI_TOP_WRITE_PERF:
  3518. snprintf (key, sizeof (key), "%d-throughput", i);
  3519. ret = dict_get_double (dict, key, &throughput);
  3520. if (!ret) {
  3521. snprintf (key, sizeof (key), "%d-time", i);
  3522. ret = dict_get_double (dict, key, &time);
  3523. }
  3524. if (!ret)
  3525. cli_out ("Throughput %.2f MBps time %.4f secs", throughput,
  3526. time / 1e6);
  3527. if (!members) {
  3528. continue;
  3529. }
  3530. cli_out ("%*s %-*s %-*s",
  3531. VOL_TOP_PERF_SPEED_WIDTH, "MBps",
  3532. VOL_TOP_PERF_FILENAME_DEF_WIDTH, "Filename",
  3533. VOL_TOP_PERF_TIME_WIDTH, "Time");
  3534. cli_out ("%*s %-*s %-*s",
  3535. VOL_TOP_PERF_SPEED_WIDTH, "====",
  3536. VOL_TOP_PERF_FILENAME_DEF_WIDTH, "========",
  3537. VOL_TOP_PERF_TIME_WIDTH, "====");
  3538. break;
  3539. default:
  3540. goto out;
  3541. }
  3542. for (j = 1; j <= members; j++) {
  3543. snprintf (key, sizeof (key), "%d-filename-%d", i, j);
  3544. ret = dict_get_str (dict, key, &filename);
  3545. if (ret)
  3546. break;
  3547. snprintf (key, sizeof (key), "%d-value-%d", i, j);
  3548. ret = dict_get_uint64 (dict, key, &value);
  3549. if (ret)
  3550. goto out;
  3551. if ( top_op == GF_CLI_TOP_READ_PERF ||
  3552. top_op == GF_CLI_TOP_WRITE_PERF) {
  3553. snprintf (key, sizeof (key), "%d-time-sec-%d", i, j);
  3554. ret = dict_get_int32 (dict, key, (int32_t *)&time_sec);
  3555. if (ret)
  3556. goto out;
  3557. snprintf (key, sizeof (key), "%d-time-usec-%d", i, j);
  3558. ret = dict_get_int32 (dict, key, (int32_t *)&time_usec);
  3559. if (ret)
  3560. goto out;
  3561. gf_time_fmt (timestr, sizeof timestr,
  3562. time_sec, gf_timefmt_FT);
  3563. snprintf (timestr + strlen (timestr), sizeof timestr - strlen (timestr),
  3564. ".%"GF_PRI_SUSECONDS, time_usec);
  3565. if (strlen (filename) < VOL_TOP_PERF_FILENAME_DEF_WIDTH)
  3566. cli_out ("%*"PRIu64" %-*s %-*s",
  3567. VOL_TOP_PERF_SPEED_WIDTH,
  3568. value,
  3569. VOL_TOP_PERF_FILENAME_DEF_WIDTH,
  3570. filename,
  3571. VOL_TOP_PERF_TIME_WIDTH,
  3572. timestr);
  3573. else
  3574. cli_out ("%*"PRIu64" ...%-*s %-*s",
  3575. VOL_TOP_PERF_SPEED_WIDTH,
  3576. value,
  3577. VOL_TOP_PERF_FILENAME_ALT_WIDTH ,
  3578. filename + strlen (filename) -
  3579. VOL_TOP_PERF_FILENAME_ALT_WIDTH,
  3580. VOL_TOP_PERF_TIME_WIDTH,
  3581. timestr);
  3582. } else {
  3583. cli_out ("%"PRIu64"\t\t%s", value, filename);
  3584. }
  3585. }
  3586. }
  3587. ret = rsp.op_ret;
  3588. out:
  3589. cli_cmd_broadcast_response (ret);
  3590. if (dict)
  3591. dict_unref (dict);
  3592. free (rsp.dict.dict_val);
  3593. return ret;
  3594. }
  3595. int32_t
  3596. gf_cli_top_volume (call_frame_t *frame, xlator_t *this, void *data)
  3597. {
  3598. int ret = -1;
  3599. gf_cli_req req = {{0,}};
  3600. dict_t *dict = NULL;
  3601. GF_ASSERT (frame);
  3602. GF_ASSERT (this);
  3603. GF_ASSERT (data);
  3604. if (!frame || !this || !data)
  3605. goto out;
  3606. dict = data;
  3607. ret = cli_to_glusterd (&req, frame, gf_cli_top_volume_cbk,
  3608. (xdrproc_t) xdr_gf_cli_req, dict,
  3609. GLUSTER_CLI_PROFILE_VOLUME, this, cli_rpc_prog,
  3610. NULL);
  3611. out:
  3612. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  3613. GF_FREE (req.dict.dict_val);
  3614. return ret;
  3615. }
  3616. int
  3617. gf_cli_getwd_cbk (struct rpc_req *req, struct iovec *iov,
  3618. int count, void *myframe)
  3619. {
  3620. gf1_cli_getwd_rsp rsp = {0,};
  3621. int ret = -1;
  3622. if (-1 == req->rpc_status) {
  3623. goto out;
  3624. }
  3625. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_getwd_rsp);
  3626. if (ret < 0 || rsp.op_ret == -1) {
  3627. gf_log ("", GF_LOG_ERROR, "error");
  3628. goto out;
  3629. }
  3630. gf_log ("cli", GF_LOG_INFO, "Received resp to getwd");
  3631. cli_out ("%s", rsp.wd);
  3632. ret = 0;
  3633. out:
  3634. cli_cmd_broadcast_response (ret);
  3635. return ret;
  3636. }
  3637. int32_t
  3638. gf_cli_getwd (call_frame_t *frame, xlator_t *this, void *data)
  3639. {
  3640. int ret = -1;
  3641. gf1_cli_getwd_req req = {0,};
  3642. GF_ASSERT (frame);
  3643. GF_ASSERT (this);
  3644. if (!frame || !this)
  3645. goto out;
  3646. ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
  3647. GLUSTER_CLI_GETWD, NULL,
  3648. this, gf_cli_getwd_cbk,
  3649. (xdrproc_t) xdr_gf1_cli_getwd_req);
  3650. out:
  3651. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  3652. return ret;
  3653. }
  3654. void
  3655. cli_print_volume_status_mempool (dict_t *dict, char *prefix)
  3656. {
  3657. int ret = -1;
  3658. int32_t mempool_count = 0;
  3659. char *name = NULL;
  3660. int32_t hotcount = 0;
  3661. int32_t coldcount = 0;
  3662. uint64_t paddedsizeof = 0;
  3663. uint64_t alloccount = 0;
  3664. int32_t maxalloc = 0;
  3665. uint64_t pool_misses = 0;
  3666. int32_t maxstdalloc = 0;
  3667. char key[1024] = {0,};
  3668. int i = 0;
  3669. GF_ASSERT (dict);
  3670. GF_ASSERT (prefix);
  3671. memset (key, 0, sizeof (key));
  3672. snprintf (key, sizeof (key), "%s.mempool-count",prefix);
  3673. ret = dict_get_int32 (dict, key, &mempool_count);
  3674. if (ret)
  3675. goto out;
  3676. cli_out ("Mempool Stats\n-------------");
  3677. cli_out ("%-30s %9s %9s %12s %10s %8s %8s %12s", "Name", "HotCount",
  3678. "ColdCount", "PaddedSizeof", "AllocCount", "MaxAlloc",
  3679. "Misses", "Max-StdAlloc");
  3680. cli_out ("%-30s %9s %9s %12s %10s %8s %8s %12s", "----", "--------",
  3681. "---------", "------------", "----------",
  3682. "--------", "--------", "------------");
  3683. for (i = 0; i < mempool_count; i++) {
  3684. memset (key, 0, sizeof (key));
  3685. snprintf (key, sizeof (key), "%s.pool%d.name", prefix, i);
  3686. ret = dict_get_str (dict, key, &name);
  3687. if (ret)
  3688. goto out;
  3689. memset (key, 0, sizeof (key));
  3690. snprintf (key, sizeof (key), "%s.pool%d.hotcount", prefix, i);
  3691. ret = dict_get_int32 (dict, key, &hotcount);
  3692. if (ret)
  3693. goto out;
  3694. memset (key, 0, sizeof (key));
  3695. snprintf (key, sizeof (key), "%s.pool%d.coldcount", prefix, i);
  3696. ret = dict_get_int32 (dict, key, &coldcount);
  3697. if (ret)
  3698. goto out;
  3699. memset (key, 0, sizeof (key));
  3700. snprintf (key, sizeof (key), "%s.pool%d.paddedsizeof",
  3701. prefix, i);
  3702. ret = dict_get_uint64 (dict, key, &paddedsizeof);
  3703. if (ret)
  3704. goto out;
  3705. memset (key, 0, sizeof (key));
  3706. snprintf (key, sizeof (key), "%s.pool%d.alloccount", prefix, i);
  3707. ret = dict_get_uint64 (dict, key, &alloccount);
  3708. if (ret)
  3709. goto out;
  3710. memset (key, 0, sizeof (key));
  3711. snprintf (key, sizeof (key), "%s.pool%d.max_alloc", prefix, i);
  3712. ret = dict_get_int32 (dict, key, &maxalloc);
  3713. if (ret)
  3714. goto out;
  3715. memset (key, 0, sizeof (key));
  3716. snprintf (key, sizeof (key), "%s.pool%d.max-stdalloc", prefix, i);
  3717. ret = dict_get_int32 (dict, key, &maxstdalloc);
  3718. if (ret)
  3719. goto out;
  3720. memset (key, 0, sizeof (key));
  3721. snprintf (key, sizeof (key), "%s.pool%d.pool-misses", prefix, i);
  3722. ret = dict_get_uint64 (dict, key, &pool_misses);
  3723. if (ret)
  3724. goto out;
  3725. cli_out ("%-30s %9d %9d %12"PRIu64" %10"PRIu64" %8d %8"PRIu64
  3726. " %12d", name, hotcount, coldcount, paddedsizeof,
  3727. alloccount, maxalloc, pool_misses, maxstdalloc);
  3728. }
  3729. out:
  3730. return;
  3731. }
  3732. void
  3733. cli_print_volume_status_mem (dict_t *dict, gf_boolean_t notbrick)
  3734. {
  3735. int ret = -1;
  3736. char *volname = NULL;
  3737. char *hostname = NULL;
  3738. char *path = NULL;
  3739. int online = -1;
  3740. char key[1024] = {0,};
  3741. int brick_index_max = -1;
  3742. int other_count = 0;
  3743. int index_max = 0;
  3744. int val = 0;
  3745. int i = 0;
  3746. GF_ASSERT (dict);
  3747. ret = dict_get_str (dict, "volname", &volname);
  3748. if (ret)
  3749. goto out;
  3750. cli_out ("Memory status for volume : %s", volname);
  3751. ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
  3752. if (ret)
  3753. goto out;
  3754. ret = dict_get_int32 (dict, "other-count", &other_count);
  3755. if (ret)
  3756. goto out;
  3757. index_max = brick_index_max + other_count;
  3758. for (i = 0; i <= index_max; i++) {
  3759. cli_out ("----------------------------------------------");
  3760. memset (key, 0, sizeof (key));
  3761. snprintf (key, sizeof (key), "brick%d.hostname", i);
  3762. ret = dict_get_str (dict, key, &hostname);
  3763. if (ret)
  3764. continue;
  3765. memset (key, 0, sizeof (key));
  3766. snprintf (key, sizeof (key), "brick%d.path", i);
  3767. ret = dict_get_str (dict, key, &path);
  3768. if (ret)
  3769. continue;
  3770. if (notbrick)
  3771. cli_out ("%s : %s", hostname, path);
  3772. else
  3773. cli_out ("Brick : %s:%s", hostname, path);
  3774. memset (key, 0, sizeof (key));
  3775. snprintf (key, sizeof (key), "brick%d.status", i);
  3776. ret = dict_get_int32 (dict, key, &online);
  3777. if (ret)
  3778. goto out;
  3779. if (!online) {
  3780. if (notbrick)
  3781. cli_out ("%s is offline", hostname);
  3782. else
  3783. cli_out ("Brick is offline");
  3784. continue;
  3785. }
  3786. cli_out ("Mallinfo\n--------");
  3787. memset (key, 0, sizeof (key));
  3788. snprintf (key, sizeof (key), "brick%d.mallinfo.arena", i);
  3789. ret = dict_get_int32 (dict, key, &val);
  3790. if (ret)
  3791. goto out;
  3792. cli_out ("%-8s : %d","Arena", val);
  3793. memset (key, 0, sizeof (key));
  3794. snprintf (key, sizeof (key), "brick%d.mallinfo.ordblks", i);
  3795. ret = dict_get_int32 (dict, key, &val);
  3796. if(ret)
  3797. goto out;
  3798. cli_out ("%-8s : %d","Ordblks", val);
  3799. memset (key, 0, sizeof (key));
  3800. snprintf (key, sizeof (key), "brick%d.mallinfo.smblks", i);
  3801. ret = dict_get_int32 (dict, key, &val);
  3802. if(ret)
  3803. goto out;
  3804. cli_out ("%-8s : %d","Smblks", val);
  3805. memset (key, 0, sizeof (key));
  3806. snprintf (key, sizeof (key), "brick%d.mallinfo.hblks", i);
  3807. ret = dict_get_int32 (dict, key, &val);
  3808. if(ret)
  3809. goto out;
  3810. cli_out ("%-8s : %d", "Hblks", val);
  3811. memset (key, 0, sizeof (key));
  3812. snprintf (key, sizeof (key), "brick%d.mallinfo.hblkhd", i);
  3813. ret = dict_get_int32 (dict, key, &val);
  3814. if (ret)
  3815. goto out;
  3816. cli_out ("%-8s : %d", "Hblkhd", val);
  3817. memset (key, 0, sizeof (key));
  3818. snprintf (key, sizeof (key), "brick%d.mallinfo.usmblks", i);
  3819. ret = dict_get_int32 (dict, key, &val);
  3820. if (ret)
  3821. goto out;
  3822. cli_out ("%-8s : %d", "Usmblks", val);
  3823. memset (key, 0, sizeof (key));
  3824. snprintf (key, sizeof (key), "brick%d.mallinfo.fsmblks", i);
  3825. ret = dict_get_int32 (dict, key, &val);
  3826. if (ret)
  3827. goto out;
  3828. cli_out ("%-8s : %d", "Fsmblks", val);
  3829. memset (key, 0, sizeof (key));
  3830. snprintf (key, sizeof (key), "brick%d.mallinfo.uordblks", i);
  3831. ret = dict_get_int32 (dict, key, &val);
  3832. if (ret)
  3833. goto out;
  3834. cli_out ("%-8s : %d", "Uordblks", val);
  3835. memset (key, 0, sizeof (key));
  3836. snprintf (key, sizeof (key), "brick%d.mallinfo.fordblks", i);
  3837. ret = dict_get_int32 (dict, key, &val);
  3838. if (ret)
  3839. goto out;
  3840. cli_out ("%-8s : %d", "Fordblks", val);
  3841. memset (key, 0, sizeof (key));
  3842. snprintf (key, sizeof (key), "brick%d.mallinfo.keepcost", i);
  3843. ret = dict_get_int32 (dict, key, &val);
  3844. if (ret)
  3845. goto out;
  3846. cli_out ("%-8s : %d", "Keepcost", val);
  3847. cli_out (" ");
  3848. memset (key, 0, sizeof (key));
  3849. snprintf (key, sizeof (key), "brick%d", i);
  3850. cli_print_volume_status_mempool (dict, key);
  3851. }
  3852. out:
  3853. cli_out ("----------------------------------------------\n");
  3854. return;
  3855. }
  3856. void
  3857. cli_print_volume_status_clients (dict_t *dict, gf_boolean_t notbrick)
  3858. {
  3859. int ret = -1;
  3860. char *volname = NULL;
  3861. int brick_index_max = -1;
  3862. int other_count = 0;
  3863. int index_max = 0;
  3864. char *hostname = NULL;
  3865. char *path = NULL;
  3866. int online = -1;
  3867. int client_count = 0;
  3868. char *clientname = NULL;
  3869. uint64_t bytesread = 0;
  3870. uint64_t byteswrite = 0;
  3871. char key[1024] = {0,};
  3872. int i = 0;
  3873. int j = 0;
  3874. GF_ASSERT (dict);
  3875. ret = dict_get_str (dict, "volname", &volname);
  3876. if (ret)
  3877. goto out;
  3878. cli_out ("Client connections for volume %s", volname);
  3879. ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
  3880. if (ret)
  3881. goto out;
  3882. ret = dict_get_int32 (dict, "other-count", &other_count);
  3883. if (ret)
  3884. goto out;
  3885. index_max = brick_index_max + other_count;
  3886. for (i = 0; i <= index_max; i++) {
  3887. cli_out ("----------------------------------------------");
  3888. memset (key, 0, sizeof (key));
  3889. snprintf (key, sizeof (key), "brick%d.hostname", i);
  3890. ret = dict_get_str (dict, key, &hostname);
  3891. if (ret)
  3892. goto out;
  3893. memset (key, 0, sizeof (key));
  3894. snprintf (key, sizeof (key), "brick%d.path", i);
  3895. ret = dict_get_str (dict, key, &path);
  3896. if (ret)
  3897. goto out;
  3898. if (notbrick)
  3899. cli_out ("%s : %s", hostname, path);
  3900. else
  3901. cli_out ("Brick : %s:%s", hostname, path);
  3902. memset (key, 0, sizeof (key));
  3903. snprintf (key, sizeof (key), "brick%d.status", i);
  3904. ret = dict_get_int32 (dict, key, &online);
  3905. if (ret)
  3906. goto out;
  3907. if (!online) {
  3908. if (notbrick)
  3909. cli_out ("%s is offline", hostname);
  3910. else
  3911. cli_out ("Brick is offline");
  3912. continue;
  3913. }
  3914. memset (key, 0, sizeof (key));
  3915. snprintf (key, sizeof (key), "brick%d.clientcount", i);
  3916. ret = dict_get_int32 (dict, key, &client_count);
  3917. if (ret)
  3918. goto out;
  3919. cli_out ("Clients connected : %d", client_count);
  3920. if (client_count == 0)
  3921. continue;
  3922. cli_out ("%-48s %15s %15s", "Hostname", "BytesRead",
  3923. "BytesWritten");
  3924. cli_out ("%-48s %15s %15s", "--------", "---------",
  3925. "------------");
  3926. for (j =0; j < client_count; j++) {
  3927. memset (key, 0, sizeof (key));
  3928. snprintf (key, sizeof (key),
  3929. "brick%d.client%d.hostname", i, j);
  3930. ret = dict_get_str (dict, key, &clientname);
  3931. if (ret)
  3932. goto out;
  3933. memset (key, 0, sizeof (key));
  3934. snprintf (key, sizeof (key),
  3935. "brick%d.client%d.bytesread", i, j);
  3936. ret = dict_get_uint64 (dict, key, &bytesread);
  3937. if (ret)
  3938. goto out;
  3939. memset (key, 0, sizeof (key));
  3940. snprintf (key, sizeof (key),
  3941. "brick%d.client%d.byteswrite", i, j);
  3942. ret = dict_get_uint64 (dict, key, &byteswrite);
  3943. if (ret)
  3944. goto out;
  3945. cli_out ("%-48s %15"PRIu64" %15"PRIu64,
  3946. clientname, bytesread, byteswrite);
  3947. }
  3948. }
  3949. out:
  3950. cli_out ("----------------------------------------------\n");
  3951. return;
  3952. }
  3953. void
  3954. cli_print_volume_status_inode_entry (dict_t *dict, char *prefix)
  3955. {
  3956. int ret = -1;
  3957. char key[1024] = {0,};
  3958. char *gfid = NULL;
  3959. uint64_t nlookup = 0;
  3960. uint32_t ref = 0;
  3961. int ia_type = 0;
  3962. char inode_type;
  3963. GF_ASSERT (dict);
  3964. GF_ASSERT (prefix);
  3965. memset (key, 0, sizeof (key));
  3966. snprintf (key, sizeof (key), "%s.gfid", prefix);
  3967. ret = dict_get_str (dict, key, &gfid);
  3968. if (ret)
  3969. goto out;
  3970. memset (key, 0, sizeof (key));
  3971. snprintf (key, sizeof (key), "%s.nlookup", prefix);
  3972. ret = dict_get_uint64 (dict, key, &nlookup);
  3973. if (ret)
  3974. goto out;
  3975. memset (key, 0, sizeof (key));
  3976. snprintf (key, sizeof (key), "%s.ref", prefix);
  3977. ret = dict_get_uint32 (dict, key, &ref);
  3978. if (ret)
  3979. goto out;
  3980. memset (key, 0, sizeof (key));
  3981. snprintf (key, sizeof (key), "%s.ia_type", prefix);
  3982. ret = dict_get_int32 (dict, key, &ia_type);
  3983. if (ret)
  3984. goto out;
  3985. switch (ia_type) {
  3986. case IA_IFREG:
  3987. inode_type = 'R';
  3988. break;
  3989. case IA_IFDIR:
  3990. inode_type = 'D';
  3991. break;
  3992. case IA_IFLNK:
  3993. inode_type = 'L';
  3994. break;
  3995. case IA_IFBLK:
  3996. inode_type = 'B';
  3997. break;
  3998. case IA_IFCHR:
  3999. inode_type = 'C';
  4000. break;
  4001. case IA_IFIFO:
  4002. inode_type = 'F';
  4003. break;
  4004. case IA_IFSOCK:
  4005. inode_type = 'S';
  4006. break;
  4007. default:
  4008. inode_type = 'I';
  4009. break;
  4010. }
  4011. cli_out ("%-40s %14"PRIu64" %14"PRIu32" %9c",
  4012. gfid, nlookup, ref, inode_type);
  4013. out:
  4014. return;
  4015. }
  4016. void
  4017. cli_print_volume_status_itables (dict_t *dict, char *prefix)
  4018. {
  4019. int ret = -1;
  4020. char key[1024] = {0,};
  4021. uint32_t active_size = 0;
  4022. uint32_t lru_size = 0;
  4023. uint32_t purge_size = 0;
  4024. int i =0;
  4025. GF_ASSERT (dict);
  4026. GF_ASSERT (prefix);
  4027. memset (key, 0, sizeof (key));
  4028. snprintf (key, sizeof (key), "%s.active_size", prefix);
  4029. ret = dict_get_uint32 (dict, key, &active_size);
  4030. if (ret)
  4031. goto out;
  4032. if (active_size != 0) {
  4033. cli_out ("Active inodes:");
  4034. cli_out ("%-40s %14s %14s %9s", "GFID", "Lookups", "Ref",
  4035. "IA type");
  4036. cli_out ("%-40s %14s %14s %9s", "----", "-------", "---",
  4037. "-------");
  4038. }
  4039. for (i = 0; i < active_size; i++) {
  4040. memset (key, 0, sizeof (key));
  4041. snprintf (key, sizeof (key), "%s.active%d", prefix, i);
  4042. cli_print_volume_status_inode_entry (dict, key);
  4043. }
  4044. cli_out (" ");
  4045. memset (key, 0, sizeof (key));
  4046. snprintf (key, sizeof (key), "%s.lru_size", prefix);
  4047. ret = dict_get_uint32 (dict, key, &lru_size);
  4048. if (ret)
  4049. goto out;
  4050. if (lru_size != 0) {
  4051. cli_out ("LRU inodes:");
  4052. cli_out ("%-40s %14s %14s %9s", "GFID", "Lookups", "Ref",
  4053. "IA type");
  4054. cli_out ("%-40s %14s %14s %9s", "----", "-------", "---",
  4055. "-------");
  4056. }
  4057. for (i = 0; i < lru_size; i++) {
  4058. memset (key, 0, sizeof (key));
  4059. snprintf (key, sizeof (key), "%s.lru%d", prefix, i);
  4060. cli_print_volume_status_inode_entry (dict, key);
  4061. }
  4062. cli_out (" ");
  4063. memset (key, 0, sizeof (key));
  4064. snprintf (key, sizeof (key), "%s.purge_size", prefix);
  4065. ret = dict_get_uint32 (dict, key, &purge_size);
  4066. if (ret)
  4067. goto out;
  4068. if (purge_size != 0) {
  4069. cli_out ("Purged inodes:");
  4070. cli_out ("%-40s %14s %14s %9s", "GFID", "Lookups", "Ref",
  4071. "IA type");
  4072. cli_out ("%-40s %14s %14s %9s", "----", "-------", "---",
  4073. "-------");
  4074. }
  4075. for (i = 0; i < purge_size; i++) {
  4076. memset (key, 0, sizeof (key));
  4077. snprintf (key, sizeof (key), "%s.purge%d", prefix, i);
  4078. cli_print_volume_status_inode_entry (dict, key);
  4079. }
  4080. out:
  4081. return;
  4082. }
  4083. void
  4084. cli_print_volume_status_inode (dict_t *dict, gf_boolean_t notbrick)
  4085. {
  4086. int ret = -1;
  4087. char *volname = NULL;
  4088. int brick_index_max = -1;
  4089. int other_count = 0;
  4090. int index_max = 0;
  4091. char *hostname = NULL;
  4092. char *path = NULL;
  4093. int online = -1;
  4094. int conn_count = 0;
  4095. char key[1024] = {0,};
  4096. int i = 0;
  4097. int j = 0;
  4098. GF_ASSERT (dict);
  4099. ret = dict_get_str (dict, "volname", &volname);
  4100. if (ret)
  4101. goto out;
  4102. cli_out ("Inode tables for volume %s", volname);
  4103. ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
  4104. if (ret)
  4105. goto out;
  4106. ret = dict_get_int32 (dict, "other-count", &other_count);
  4107. if (ret)
  4108. goto out;
  4109. index_max = brick_index_max + other_count;
  4110. for ( i = 0; i <= index_max; i++) {
  4111. cli_out ("----------------------------------------------");
  4112. memset (key, 0, sizeof (key));
  4113. snprintf (key, sizeof (key), "brick%d.hostname", i);
  4114. ret = dict_get_str (dict, key, &hostname);
  4115. if (ret)
  4116. goto out;
  4117. memset (key, 0, sizeof (key));
  4118. snprintf (key, sizeof (key), "brick%d.path", i);
  4119. ret = dict_get_str (dict, key, &path);
  4120. if (ret)
  4121. goto out;
  4122. if (notbrick)
  4123. cli_out ("%s : %s", hostname, path);
  4124. else
  4125. cli_out ("Brick : %s:%s", hostname, path);
  4126. memset (key, 0, sizeof (key));
  4127. snprintf (key, sizeof (key), "brick%d.status", i);
  4128. ret = dict_get_int32 (dict, key, &online);
  4129. if (ret)
  4130. goto out;
  4131. if (!online) {
  4132. if (notbrick)
  4133. cli_out ("%s is offline", hostname);
  4134. else
  4135. cli_out ("Brick is offline");
  4136. continue;
  4137. }
  4138. memset (key, 0, sizeof (key));
  4139. snprintf (key, sizeof (key), "brick%d.conncount", i);
  4140. ret = dict_get_int32 (dict, key, &conn_count);
  4141. if (ret)
  4142. goto out;
  4143. for (j = 0; j < conn_count; j++) {
  4144. if (conn_count > 1)
  4145. cli_out ("Connection %d:", j+1);
  4146. memset (key, 0, sizeof (key));
  4147. snprintf (key, sizeof (key), "brick%d.conn%d.itable",
  4148. i, j);
  4149. cli_print_volume_status_itables (dict, key);
  4150. cli_out (" ");
  4151. }
  4152. }
  4153. out:
  4154. cli_out ("----------------------------------------------");
  4155. return;
  4156. }
  4157. void
  4158. cli_print_volume_status_fdtable (dict_t *dict, char *prefix)
  4159. {
  4160. int ret = -1;
  4161. char key[1024] = {0,};
  4162. int refcount = 0;
  4163. uint32_t maxfds = 0;
  4164. int firstfree = 0;
  4165. int openfds = 0;
  4166. int fd_pid = 0;
  4167. int fd_refcount = 0;
  4168. int fd_flags = 0;
  4169. int i = 0;
  4170. GF_ASSERT (dict);
  4171. GF_ASSERT (prefix);
  4172. memset (key, 0, sizeof (key));
  4173. snprintf (key, sizeof (key), "%s.refcount", prefix);
  4174. ret = dict_get_int32 (dict, key, &refcount);
  4175. if (ret)
  4176. goto out;
  4177. memset (key, 0, sizeof (key));
  4178. snprintf (key, sizeof (key), "%s.maxfds", prefix);
  4179. ret = dict_get_uint32 (dict, key, &maxfds);
  4180. if (ret)
  4181. goto out;
  4182. memset (key, 0 ,sizeof (key));
  4183. snprintf (key, sizeof (key), "%s.firstfree", prefix);
  4184. ret = dict_get_int32 (dict, key, &firstfree);
  4185. if (ret)
  4186. goto out;
  4187. cli_out ("RefCount = %d MaxFDs = %d FirstFree = %d",
  4188. refcount, maxfds, firstfree);
  4189. memset (key, 0, sizeof (key));
  4190. snprintf (key, sizeof (key), "%s.openfds", prefix);
  4191. ret = dict_get_int32 (dict, key, &openfds);
  4192. if (ret)
  4193. goto out;
  4194. if (0 == openfds) {
  4195. cli_err ("No open fds");
  4196. goto out;
  4197. }
  4198. cli_out ("%-19s %-19s %-19s %-19s", "FD Entry", "PID",
  4199. "RefCount", "Flags");
  4200. cli_out ("%-19s %-19s %-19s %-19s", "--------", "---",
  4201. "--------", "-----");
  4202. for (i = 0; i < maxfds ; i++) {
  4203. memset (key, 0, sizeof (key));
  4204. snprintf (key, sizeof (key), "%s.fdentry%d.pid", prefix, i);
  4205. ret = dict_get_int32 (dict, key, &fd_pid);
  4206. if (ret)
  4207. continue;
  4208. memset (key, 0, sizeof (key));
  4209. snprintf (key, sizeof (key), "%s.fdentry%d.refcount",
  4210. prefix, i);
  4211. ret = dict_get_int32 (dict, key, &fd_refcount);
  4212. if (ret)
  4213. continue;
  4214. memset (key, 0, sizeof (key));
  4215. snprintf (key, sizeof (key), "%s.fdentry%d.flags", prefix, i);
  4216. ret = dict_get_int32 (dict, key, &fd_flags);
  4217. if (ret)
  4218. continue;
  4219. cli_out ("%-19d %-19d %-19d %-19d", i, fd_pid, fd_refcount,
  4220. fd_flags);
  4221. }
  4222. out:
  4223. return;
  4224. }
  4225. void
  4226. cli_print_volume_status_fd (dict_t *dict, gf_boolean_t notbrick)
  4227. {
  4228. int ret = -1;
  4229. char *volname = NULL;
  4230. int brick_index_max = -1;
  4231. int other_count = 0;
  4232. int index_max = 0;
  4233. char *hostname = NULL;
  4234. char *path = NULL;
  4235. int online = -1;
  4236. int conn_count = 0;
  4237. char key[1024] = {0,};
  4238. int i = 0;
  4239. int j = 0;
  4240. GF_ASSERT (dict);
  4241. ret = dict_get_str (dict, "volname", &volname);
  4242. if (ret)
  4243. goto out;
  4244. cli_out ("FD tables for volume %s", volname);
  4245. ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
  4246. if (ret)
  4247. goto out;
  4248. ret = dict_get_int32 (dict, "other-count", &other_count);
  4249. if (ret)
  4250. goto out;
  4251. index_max = brick_index_max + other_count;
  4252. for (i = 0; i <= index_max; i++) {
  4253. cli_out ("----------------------------------------------");
  4254. memset (key, 0, sizeof (key));
  4255. snprintf (key, sizeof (key), "brick%d.hostname", i);
  4256. ret = dict_get_str (dict, key, &hostname);
  4257. if (ret)
  4258. goto out;
  4259. memset (key, 0, sizeof (key));
  4260. snprintf (key, sizeof (key), "brick%d.path", i);
  4261. ret = dict_get_str (dict, key, &path);
  4262. if (ret)
  4263. goto out;
  4264. if (notbrick)
  4265. cli_out ("%s : %s", hostname, path);
  4266. else
  4267. cli_out ("Brick : %s:%s", hostname, path);
  4268. memset (key, 0, sizeof (key));
  4269. snprintf (key, sizeof (key), "brick%d.status", i);
  4270. ret = dict_get_int32 (dict, key, &online);
  4271. if (ret)
  4272. goto out;
  4273. if (!online) {
  4274. if (notbrick)
  4275. cli_out ("%s is offline", hostname);
  4276. else
  4277. cli_out ("Brick is offline");
  4278. continue;
  4279. }
  4280. memset (key, 0, sizeof (key));
  4281. snprintf (key, sizeof (key), "brick%d.conncount", i);
  4282. ret = dict_get_int32 (dict, key, &conn_count);
  4283. if (ret)
  4284. goto out;
  4285. for (j = 0; j < conn_count; j++) {
  4286. cli_out ("Connection %d:", j+1);
  4287. memset (key, 0, sizeof (key));
  4288. snprintf (key, sizeof (key), "brick%d.conn%d.fdtable",
  4289. i, j);
  4290. cli_print_volume_status_fdtable (dict, key);
  4291. cli_out (" ");
  4292. }
  4293. }
  4294. out:
  4295. cli_out ("----------------------------------------------");
  4296. return;
  4297. }
  4298. void
  4299. cli_print_volume_status_call_frame (dict_t *dict, char *prefix)
  4300. {
  4301. int ret = -1;
  4302. char key[1024] = {0,};
  4303. int ref_count = 0;
  4304. char *translator = 0;
  4305. int complete = 0;
  4306. char *parent = NULL;
  4307. char *wind_from = NULL;
  4308. char *wind_to = NULL;
  4309. char *unwind_from = NULL;
  4310. char *unwind_to = NULL;
  4311. if (!dict || !prefix)
  4312. return;
  4313. memset (key, 0, sizeof (key));
  4314. snprintf (key, sizeof (key), "%s.refcount", prefix);
  4315. ret = dict_get_int32 (dict, key, &ref_count);
  4316. if (ret)
  4317. return;
  4318. memset (key, 0, sizeof (key));
  4319. snprintf (key, sizeof (key), "%s.translator", prefix);
  4320. ret = dict_get_str (dict, key, &translator);
  4321. if (ret)
  4322. return;
  4323. memset (key, 0, sizeof (key));
  4324. snprintf (key, sizeof (key), "%s.complete", prefix);
  4325. ret = dict_get_int32 (dict, key, &complete);
  4326. if (ret)
  4327. return;
  4328. cli_out (" Ref Count = %d", ref_count);
  4329. cli_out (" Translator = %s", translator);
  4330. cli_out (" Completed = %s", (complete ? "Yes" : "No"));
  4331. memset (key, 0, sizeof (key));
  4332. snprintf (key, sizeof (key), "%s.parent", prefix);
  4333. ret = dict_get_str (dict, key, &parent);
  4334. if (!ret)
  4335. cli_out (" Parent = %s", parent);
  4336. memset (key, 0, sizeof (key));
  4337. snprintf (key, sizeof (key), "%s.windfrom", prefix);
  4338. ret = dict_get_str (dict, key, &wind_from);
  4339. if (!ret)
  4340. cli_out (" Wind From = %s", wind_from);
  4341. memset (key, 0, sizeof (key));
  4342. snprintf (key, sizeof (key), "%s.windto", prefix);
  4343. ret = dict_get_str (dict, key, &wind_to);
  4344. if (!ret)
  4345. cli_out (" Wind To = %s", wind_to);
  4346. memset (key, 0, sizeof (key));
  4347. snprintf (key, sizeof (key), "%s.unwindfrom", prefix);
  4348. ret = dict_get_str (dict, key, &unwind_from);
  4349. if (!ret)
  4350. cli_out (" Unwind From = %s", unwind_from);
  4351. memset (key, 0, sizeof (key));
  4352. snprintf (key, sizeof (key), "%s.unwindto", prefix);
  4353. ret = dict_get_str (dict, key, &unwind_to);
  4354. if (!ret)
  4355. cli_out (" Unwind To = %s", unwind_to);
  4356. }
  4357. void
  4358. cli_print_volume_status_call_stack (dict_t *dict, char *prefix)
  4359. {
  4360. int ret = -1;
  4361. char key[1024] = {0,};
  4362. int uid = 0;
  4363. int gid = 0;
  4364. int pid = 0;
  4365. uint64_t unique = 0;
  4366. //char *op = NULL;
  4367. int count = 0;
  4368. int i = 0;
  4369. if (!dict || !prefix)
  4370. return;
  4371. memset (key, 0, sizeof (key));
  4372. snprintf (key, sizeof (key), "%s.uid", prefix);
  4373. ret = dict_get_int32 (dict, key, &uid);
  4374. if (ret)
  4375. return;
  4376. memset (key, 0, sizeof (key));
  4377. snprintf (key, sizeof (key), "%s.gid", prefix);
  4378. ret = dict_get_int32 (dict, key, &gid);
  4379. if (ret)
  4380. return;
  4381. memset (key, 0, sizeof (key));
  4382. snprintf (key, sizeof (key), "%s.pid", prefix);
  4383. ret = dict_get_int32 (dict, key, &pid);
  4384. if (ret)
  4385. return;
  4386. memset (key, 0, sizeof (key));
  4387. snprintf (key, sizeof (key), "%s.unique", prefix);
  4388. ret = dict_get_uint64 (dict, key, &unique);
  4389. if (ret)
  4390. return;
  4391. /*
  4392. memset (key, 0, sizeof (key));
  4393. snprintf (key, sizeof (key), "%s.op", prefix);
  4394. ret = dict_get_str (dict, key, &op);
  4395. if (ret)
  4396. return;
  4397. */
  4398. memset (key, 0, sizeof (key));
  4399. snprintf (key, sizeof (key), "%s.count", prefix);
  4400. ret = dict_get_int32 (dict, key, &count);
  4401. if (ret)
  4402. return;
  4403. cli_out (" UID : %d", uid);
  4404. cli_out (" GID : %d", gid);
  4405. cli_out (" PID : %d", pid);
  4406. cli_out (" Unique : %"PRIu64, unique);
  4407. //cli_out ("\tOp : %s", op);
  4408. cli_out (" Frames : %d", count);
  4409. for (i = 0; i < count; i++) {
  4410. cli_out (" Frame %d", i+1);
  4411. memset (key, 0, sizeof (key));
  4412. snprintf (key, sizeof (key), "%s.frame%d", prefix, i);
  4413. cli_print_volume_status_call_frame (dict, key);
  4414. }
  4415. cli_out (" ");
  4416. }
  4417. void
  4418. cli_print_volume_status_callpool (dict_t *dict, gf_boolean_t notbrick)
  4419. {
  4420. int ret = -1;
  4421. char *volname = NULL;
  4422. int brick_index_max = -1;
  4423. int other_count = 0;
  4424. int index_max = 0;
  4425. char *hostname = NULL;
  4426. char *path = NULL;
  4427. int online = -1;
  4428. int call_count = 0;
  4429. char key[1024] = {0,};
  4430. int i = 0;
  4431. int j = 0;
  4432. GF_ASSERT (dict);
  4433. ret = dict_get_str (dict, "volname", &volname);
  4434. if (ret)
  4435. goto out;
  4436. cli_out ("Pending calls for volume %s", volname);
  4437. ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
  4438. if (ret)
  4439. goto out;
  4440. ret = dict_get_int32 (dict, "other-count", &other_count);
  4441. if (ret)
  4442. goto out;
  4443. index_max = brick_index_max + other_count;
  4444. for (i = 0; i <= index_max; i++) {
  4445. cli_out ("----------------------------------------------");
  4446. memset (key, 0, sizeof (key));
  4447. snprintf (key, sizeof (key), "brick%d.hostname", i);
  4448. ret = dict_get_str (dict, key, &hostname);
  4449. if (ret)
  4450. goto out;
  4451. memset (key, 0, sizeof (key));
  4452. snprintf (key, sizeof (key), "brick%d.path", i);
  4453. ret = dict_get_str (dict, key, &path);
  4454. if (ret)
  4455. goto out;
  4456. if (notbrick)
  4457. cli_out ("%s : %s", hostname, path);
  4458. else
  4459. cli_out ("Brick : %s:%s", hostname, path);
  4460. memset (key, 0, sizeof (key));
  4461. snprintf (key, sizeof (key), "brick%d.status", i);
  4462. ret = dict_get_int32 (dict, key, &online);
  4463. if (ret)
  4464. goto out;
  4465. if (!online) {
  4466. if (notbrick)
  4467. cli_out ("%s is offline", hostname);
  4468. else
  4469. cli_out ("Brick is offline");
  4470. continue;
  4471. }
  4472. memset (key, 0, sizeof (key));
  4473. snprintf (key, sizeof (key), "brick%d.callpool.count", i);
  4474. ret = dict_get_int32 (dict, key, &call_count);
  4475. if (ret)
  4476. goto out;
  4477. cli_out ("Pending calls: %d", call_count);
  4478. if (0 == call_count)
  4479. continue;
  4480. for (j = 0; j < call_count; j++) {
  4481. cli_out ("Call Stack%d", j+1);
  4482. memset (key, 0, sizeof (key));
  4483. snprintf (key, sizeof (key),
  4484. "brick%d.callpool.stack%d", i, j);
  4485. cli_print_volume_status_call_stack (dict, key);
  4486. }
  4487. }
  4488. out:
  4489. cli_out ("----------------------------------------------");
  4490. return;
  4491. }
  4492. static void
  4493. cli_print_volume_tasks (dict_t *dict) {
  4494. int ret = -1;
  4495. int tasks = 0;
  4496. char *op = 0;
  4497. char *task_id_str = NULL;
  4498. int status = 0;
  4499. char key[1024] = {0,};
  4500. int i = 0;
  4501. ret = dict_get_int32 (dict, "tasks", &tasks);
  4502. if (ret) {
  4503. gf_log ("cli", GF_LOG_ERROR,
  4504. "Failed to get tasks count");
  4505. return;
  4506. }
  4507. if (tasks == 0) {
  4508. cli_out ("There are no active volume tasks");
  4509. return;
  4510. }
  4511. cli_out ("%15s%40s%15s", "Task", "ID", "Status");
  4512. cli_out ("%15s%40s%15s", "----", "--", "------");
  4513. for (i = 0; i < tasks; i++) {
  4514. memset (key, 0, sizeof (key));
  4515. snprintf (key, sizeof (key), "task%d.type", i);
  4516. ret = dict_get_str(dict, key, &op);
  4517. if (ret)
  4518. return;
  4519. memset (key, 0, sizeof (key));
  4520. snprintf (key, sizeof (key), "task%d.id", i);
  4521. ret = dict_get_str (dict, key, &task_id_str);
  4522. if (ret)
  4523. return;
  4524. memset (key, 0, sizeof (key));
  4525. snprintf (key, sizeof (key), "task%d.status", i);
  4526. ret = dict_get_int32 (dict, key, &status);
  4527. if (ret)
  4528. return;
  4529. cli_out ("%15s%40s%15d", op, task_id_str, status);
  4530. }
  4531. }
  4532. static int
  4533. gf_cli_status_cbk (struct rpc_req *req, struct iovec *iov,
  4534. int count, void *myframe)
  4535. {
  4536. int ret = -1;
  4537. int brick_index_max = -1;
  4538. int other_count = 0;
  4539. int index_max = 0;
  4540. int i = 0;
  4541. int pid = -1;
  4542. uint32_t cmd = 0;
  4543. gf_boolean_t notbrick = _gf_false;
  4544. char key[1024] = {0,};
  4545. char *hostname = NULL;
  4546. char *path = NULL;
  4547. char *volname = NULL;
  4548. dict_t *dict = NULL;
  4549. gf_cli_rsp rsp = {0,};
  4550. cli_volume_status_t status = {0};
  4551. cli_local_t *local = NULL;
  4552. gf_boolean_t wipe_local = _gf_false;
  4553. char msg[1024] = {0,};
  4554. if (req->rpc_status == -1)
  4555. goto out;
  4556. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  4557. if (ret < 0) {
  4558. gf_log ("cli", GF_LOG_ERROR, "Volume status response error");
  4559. goto out;
  4560. }
  4561. gf_log ("cli", GF_LOG_DEBUG, "Received response to status cmd");
  4562. local = ((call_frame_t *)myframe)->local;
  4563. if (!local) {
  4564. local = cli_local_get ();
  4565. if (!local) {
  4566. ret = -1;
  4567. gf_log ("cli", GF_LOG_ERROR, "Failed to get local");
  4568. goto out;
  4569. }
  4570. wipe_local = _gf_true;
  4571. }
  4572. if (rsp.op_ret) {
  4573. if (strcmp (rsp.op_errstr, ""))
  4574. snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
  4575. else
  4576. snprintf (msg, sizeof (msg), "Unable to obtain volume "
  4577. "status information.");
  4578. if (global_state->mode & GLUSTER_MODE_XML) {
  4579. cli_xml_output_str ("volStatus", msg, rsp.op_ret,
  4580. rsp.op_errno, rsp.op_errstr);
  4581. ret = 0;
  4582. goto out;
  4583. }
  4584. cli_err ("%s", msg);
  4585. if (local && local->all) {
  4586. ret = 0;
  4587. cli_out (" ");
  4588. } else
  4589. ret = -1;
  4590. goto out;
  4591. }
  4592. dict = dict_new ();
  4593. if (!dict)
  4594. goto out;
  4595. ret = dict_unserialize (rsp.dict.dict_val,
  4596. rsp.dict.dict_len,
  4597. &dict);
  4598. if (ret)
  4599. goto out;
  4600. ret = dict_get_uint32 (dict, "cmd", &cmd);
  4601. if (ret)
  4602. goto out;
  4603. if ((cmd & GF_CLI_STATUS_ALL)) {
  4604. if (local && local->dict) {
  4605. dict_ref (dict);
  4606. ret = dict_set_static_ptr (local->dict, "rsp-dict", dict);
  4607. ret = 0;
  4608. } else {
  4609. gf_log ("cli", GF_LOG_ERROR, "local not found");
  4610. ret = -1;
  4611. }
  4612. goto out;
  4613. }
  4614. if ((cmd & GF_CLI_STATUS_NFS) || (cmd & GF_CLI_STATUS_SHD))
  4615. notbrick = _gf_true;
  4616. ret = dict_get_int32 (dict, "count", &count);
  4617. if (ret)
  4618. goto out;
  4619. if (count == 0) {
  4620. ret = -1;
  4621. goto out;
  4622. }
  4623. ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
  4624. if (ret)
  4625. goto out;
  4626. ret = dict_get_int32 (dict, "other-count", &other_count);
  4627. if (ret)
  4628. goto out;
  4629. index_max = brick_index_max + other_count;
  4630. if (global_state->mode & GLUSTER_MODE_XML) {
  4631. if (!local->all) {
  4632. ret = cli_xml_output_vol_status_begin (local,
  4633. rsp.op_ret,
  4634. rsp.op_errno,
  4635. rsp.op_errstr);
  4636. if (ret) {
  4637. gf_log ("cli", GF_LOG_ERROR,
  4638. "Error outputting to xml");
  4639. goto out;
  4640. }
  4641. }
  4642. ret = cli_xml_output_vol_status (local, dict);
  4643. if (ret) {
  4644. gf_log ("cli", GF_LOG_ERROR,
  4645. "Error outputting to xml");
  4646. goto out;
  4647. }
  4648. if (!local->all) {
  4649. ret = cli_xml_output_vol_status_end (local);
  4650. if (ret) {
  4651. gf_log ("cli", GF_LOG_ERROR,
  4652. "Error outputting to xml");
  4653. }
  4654. }
  4655. goto out;
  4656. }
  4657. status.brick = GF_CALLOC (1, PATH_MAX + 256, gf_common_mt_strdup);
  4658. switch (cmd & GF_CLI_STATUS_MASK) {
  4659. case GF_CLI_STATUS_MEM:
  4660. cli_print_volume_status_mem (dict, notbrick);
  4661. goto cont;
  4662. break;
  4663. case GF_CLI_STATUS_CLIENTS:
  4664. cli_print_volume_status_clients (dict, notbrick);
  4665. goto cont;
  4666. break;
  4667. case GF_CLI_STATUS_INODE:
  4668. cli_print_volume_status_inode (dict, notbrick);
  4669. goto cont;
  4670. break;
  4671. case GF_CLI_STATUS_FD:
  4672. cli_print_volume_status_fd (dict, notbrick);
  4673. goto cont;
  4674. break;
  4675. case GF_CLI_STATUS_CALLPOOL:
  4676. cli_print_volume_status_callpool (dict, notbrick);
  4677. goto cont;
  4678. break;
  4679. default:
  4680. break;
  4681. }
  4682. ret = dict_get_str (dict, "volname", &volname);
  4683. if (ret)
  4684. goto out;
  4685. cli_out ("Status of volume: %s", volname);
  4686. if ((cmd & GF_CLI_STATUS_DETAIL) == 0) {
  4687. cli_out ("Gluster process\t\t\t\t\t\tPort\tOnline\tPid");
  4688. cli_print_line (CLI_BRICK_STATUS_LINE_LEN);
  4689. }
  4690. for (i = 0; i <= index_max; i++) {
  4691. memset (key, 0, sizeof (key));
  4692. snprintf (key, sizeof (key), "brick%d.hostname", i);
  4693. ret = dict_get_str (dict, key, &hostname);
  4694. if (ret)
  4695. continue;
  4696. memset (key, 0, sizeof (key));
  4697. snprintf (key, sizeof (key), "brick%d.path", i);
  4698. ret = dict_get_str (dict, key, &path);
  4699. if (ret)
  4700. continue;
  4701. /* Brick/not-brick is handled seperately here as all
  4702. * types of nodes are contained in the default output
  4703. */
  4704. memset (status.brick, 0, PATH_MAX + 255);
  4705. if (!strcmp (hostname, "NFS Server") ||
  4706. !strcmp (hostname, "Self-heal Daemon"))
  4707. snprintf (status.brick, PATH_MAX + 255, "%s on %s",
  4708. hostname, path);
  4709. else
  4710. snprintf (status.brick, PATH_MAX + 255, "Brick %s:%s",
  4711. hostname, path);
  4712. memset (key, 0, sizeof (key));
  4713. snprintf (key, sizeof (key), "brick%d.port", i);
  4714. ret = dict_get_int32 (dict, key, &(status.port));
  4715. if (ret)
  4716. continue;
  4717. memset (key, 0, sizeof (key));
  4718. snprintf (key, sizeof (key), "brick%d.status", i);
  4719. ret = dict_get_int32 (dict, key, &(status.online));
  4720. if (ret)
  4721. continue;
  4722. memset (key, 0, sizeof (key));
  4723. snprintf (key, sizeof (key), "brick%d.pid", i);
  4724. ret = dict_get_int32 (dict, key, &pid);
  4725. if (ret)
  4726. continue;
  4727. if (pid == -1)
  4728. ret = gf_asprintf (&(status.pid_str), "%s", "N/A");
  4729. else
  4730. ret = gf_asprintf (&(status.pid_str), "%d", pid);
  4731. if (ret == -1)
  4732. goto out;
  4733. if ((cmd & GF_CLI_STATUS_DETAIL)) {
  4734. ret = cli_get_detail_status (dict, i, &status);
  4735. if (ret)
  4736. goto out;
  4737. cli_print_line (CLI_BRICK_STATUS_LINE_LEN);
  4738. cli_print_detailed_status (&status);
  4739. } else {
  4740. cli_print_brick_status (&status);
  4741. }
  4742. }
  4743. cli_out (" ");
  4744. if ((cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE)
  4745. cli_print_volume_tasks (dict);
  4746. cont:
  4747. ret = rsp.op_ret;
  4748. out:
  4749. if (dict)
  4750. dict_unref (dict);
  4751. GF_FREE (status.brick);
  4752. if (local && wipe_local) {
  4753. cli_local_wipe (local);
  4754. }
  4755. cli_cmd_broadcast_response (ret);
  4756. return ret;
  4757. }
  4758. int32_t
  4759. gf_cli_status_volume (call_frame_t *frame, xlator_t *this,
  4760. void *data)
  4761. {
  4762. gf_cli_req req = {{0,}};
  4763. int ret = -1;
  4764. dict_t *dict = NULL;
  4765. if (!frame || !this || !data)
  4766. goto out;
  4767. dict = data;
  4768. ret = cli_to_glusterd (&req, frame, gf_cli_status_cbk,
  4769. (xdrproc_t) xdr_gf_cli_req, dict,
  4770. GLUSTER_CLI_STATUS_VOLUME, this, cli_rpc_prog,
  4771. NULL);
  4772. out:
  4773. gf_log ("cli", GF_LOG_DEBUG, "Returning: %d", ret);
  4774. return ret;
  4775. }
  4776. int
  4777. gf_cli_status_volume_all (call_frame_t *frame, xlator_t *this, void *data)
  4778. {
  4779. int i = 0;
  4780. int ret = -1;
  4781. int vol_count = -1;
  4782. uint32_t cmd = 0;
  4783. char key[1024] = {0};
  4784. char *volname = NULL;
  4785. void *vol_dict = NULL;
  4786. dict_t *dict = NULL;
  4787. cli_local_t *local = NULL;
  4788. if (frame->local) {
  4789. local = frame->local;
  4790. local->all = _gf_true;
  4791. } else
  4792. goto out;
  4793. ret = dict_get_uint32 (local->dict, "cmd", &cmd);
  4794. if (ret)
  4795. goto out;
  4796. ret = gf_cli_status_volume (frame, this, data);
  4797. if (ret)
  4798. goto out;
  4799. ret = dict_get_ptr (local->dict, "rsp-dict", &vol_dict);
  4800. if (ret)
  4801. goto out;
  4802. ret = dict_get_int32 ((dict_t *)vol_dict, "vol_count", &vol_count);
  4803. if (ret) {
  4804. cli_err ("Failed to get names of volumes");
  4805. goto out;
  4806. }
  4807. if (vol_count == 0) {
  4808. cli_err ("No volumes present");
  4809. ret = 0;
  4810. goto out;
  4811. }
  4812. /* remove the "all" flag in cmd */
  4813. cmd &= ~GF_CLI_STATUS_ALL;
  4814. cmd |= GF_CLI_STATUS_VOL;
  4815. if (global_state->mode & GLUSTER_MODE_XML) {
  4816. //TODO: Pass proper op_* values
  4817. ret = cli_xml_output_vol_status_begin (local, 0,0, NULL);
  4818. if (ret) {
  4819. gf_log ("cli", GF_LOG_ERROR,
  4820. "Error outputting to xml");
  4821. goto out;
  4822. }
  4823. }
  4824. for (i = 0; i < vol_count; i++) {
  4825. dict = dict_new ();
  4826. if (!dict)
  4827. goto out;
  4828. memset (key, 0, sizeof (key));
  4829. snprintf (key, sizeof (key), "vol%d", i);
  4830. ret = dict_get_str (vol_dict, key, &volname);
  4831. if (ret)
  4832. goto out;
  4833. ret = dict_set_str (dict, "volname", volname);
  4834. if (ret)
  4835. goto out;
  4836. ret = dict_set_uint32 (dict, "cmd", cmd);
  4837. if (ret)
  4838. goto out;
  4839. ret = gf_cli_status_volume (frame, this, dict);
  4840. if (ret)
  4841. goto out;
  4842. dict_unref (dict);
  4843. }
  4844. if (global_state->mode & GLUSTER_MODE_XML) {
  4845. ret = cli_xml_output_vol_status_end (local);
  4846. }
  4847. out:
  4848. if (ret)
  4849. gf_log ("cli", GF_LOG_ERROR, "status all failed");
  4850. if (vol_dict)
  4851. dict_unref (vol_dict);
  4852. if (ret && dict)
  4853. dict_unref (dict);
  4854. if (local)
  4855. cli_local_wipe (local);
  4856. if (frame)
  4857. frame->local = NULL;
  4858. return ret;
  4859. }
  4860. static int
  4861. gf_cli_mount_cbk (struct rpc_req *req, struct iovec *iov,
  4862. int count, void *myframe)
  4863. {
  4864. gf1_cli_mount_rsp rsp = {0,};
  4865. int ret = -1;
  4866. if (-1 == req->rpc_status) {
  4867. goto out;
  4868. }
  4869. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_mount_rsp);
  4870. if (ret < 0) {
  4871. gf_log ("", GF_LOG_ERROR, "error");
  4872. goto out;
  4873. }
  4874. gf_log ("cli", GF_LOG_INFO, "Received resp to mount");
  4875. if (rsp.op_ret == 0) {
  4876. ret = 0;
  4877. cli_out ("%s", rsp.path);
  4878. } else {
  4879. /* weird sounding but easy to parse... */
  4880. cli_err ("%d : failed with this errno (%s)",
  4881. rsp.op_errno, strerror (rsp.op_errno));
  4882. ret = -1;
  4883. }
  4884. out:
  4885. cli_cmd_broadcast_response (ret);
  4886. return ret;
  4887. }
  4888. int32_t
  4889. gf_cli_mount (call_frame_t *frame, xlator_t *this, void *data)
  4890. {
  4891. gf1_cli_mount_req req = {0,};
  4892. int ret = -1;
  4893. void **dataa = data;
  4894. char *label = NULL;
  4895. dict_t *dict = NULL;
  4896. if (!frame || !this || !data)
  4897. goto out;
  4898. label = dataa[0];
  4899. dict = dataa[1];
  4900. req.label = label;
  4901. ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
  4902. &req.dict.dict_len);
  4903. if (ret) {
  4904. ret = -1;
  4905. goto out;
  4906. }
  4907. ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
  4908. GLUSTER_CLI_MOUNT, NULL,
  4909. this, gf_cli_mount_cbk,
  4910. (xdrproc_t)xdr_gf1_cli_mount_req);
  4911. out:
  4912. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  4913. return ret;
  4914. }
  4915. static int
  4916. gf_cli_umount_cbk (struct rpc_req *req, struct iovec *iov,
  4917. int count, void *myframe)
  4918. {
  4919. gf1_cli_umount_rsp rsp = {0,};
  4920. int ret = -1;
  4921. if (-1 == req->rpc_status) {
  4922. goto out;
  4923. }
  4924. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_umount_rsp);
  4925. if (ret < 0) {
  4926. gf_log ("", GF_LOG_ERROR, "error");
  4927. goto out;
  4928. }
  4929. gf_log ("cli", GF_LOG_INFO, "Received resp to mount");
  4930. if (rsp.op_ret == 0)
  4931. ret = 0;
  4932. else {
  4933. cli_err ("umount failed");
  4934. ret = -1;
  4935. }
  4936. out:
  4937. cli_cmd_broadcast_response (ret);
  4938. return ret;
  4939. }
  4940. int32_t
  4941. gf_cli_umount (call_frame_t *frame, xlator_t *this, void *data)
  4942. {
  4943. gf1_cli_umount_req req = {0,};
  4944. int ret = -1;
  4945. dict_t *dict = NULL;
  4946. if (!frame || !this || !data)
  4947. goto out;
  4948. dict = data;
  4949. ret = dict_get_str (dict, "path", &req.path);
  4950. if (ret == 0)
  4951. ret = dict_get_int32 (dict, "lazy", &req.lazy);
  4952. if (ret) {
  4953. ret = -1;
  4954. goto out;
  4955. }
  4956. ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
  4957. GLUSTER_CLI_UMOUNT, NULL,
  4958. this, gf_cli_umount_cbk,
  4959. (xdrproc_t)xdr_gf1_cli_umount_req);
  4960. out:
  4961. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  4962. return ret;
  4963. }
  4964. void
  4965. cmd_heal_volume_brick_out (dict_t *dict, int brick)
  4966. {
  4967. uint64_t num_entries = 0;
  4968. int ret = 0;
  4969. char key[256] = {0};
  4970. char *hostname = NULL;
  4971. char *path = NULL;
  4972. char *status = NULL;
  4973. uint64_t i = 0;
  4974. uint32_t time = 0;
  4975. char timestr[32] = {0};
  4976. snprintf (key, sizeof key, "%d-hostname", brick);
  4977. ret = dict_get_str (dict, key, &hostname);
  4978. if (ret)
  4979. goto out;
  4980. snprintf (key, sizeof key, "%d-path", brick);
  4981. ret = dict_get_str (dict, key, &path);
  4982. if (ret)
  4983. goto out;
  4984. cli_out ("\nBrick %s:%s", hostname, path);
  4985. snprintf (key, sizeof key, "%d-count", brick);
  4986. ret = dict_get_uint64 (dict, key, &num_entries);
  4987. cli_out ("Number of entries: %"PRIu64, num_entries);
  4988. snprintf (key, sizeof key, "%d-status", brick);
  4989. ret = dict_get_str (dict, key, &status);
  4990. if (status && strlen (status))
  4991. cli_out ("Status: %s", status);
  4992. for (i = 0; i < num_entries; i++) {
  4993. snprintf (key, sizeof key, "%d-%"PRIu64, brick, i);
  4994. ret = dict_get_str (dict, key, &path);
  4995. if (ret)
  4996. continue;
  4997. time = 0;
  4998. snprintf (key, sizeof key, "%d-%"PRIu64"-time", brick, i);
  4999. ret = dict_get_uint32 (dict, key, &time);
  5000. if (!time) {
  5001. cli_out ("%s", path);
  5002. } else {
  5003. gf_time_fmt (timestr, sizeof timestr,
  5004. time, gf_timefmt_FT);
  5005. if (i == 0) {
  5006. cli_out ("at path on brick");
  5007. cli_out ("-----------------------------------");
  5008. }
  5009. cli_out ("%s %s", timestr, path);
  5010. }
  5011. }
  5012. out:
  5013. return;
  5014. }
  5015. int
  5016. gf_cli_heal_volume_cbk (struct rpc_req *req, struct iovec *iov,
  5017. int count, void *myframe)
  5018. {
  5019. gf_cli_rsp rsp = {0,};
  5020. int ret = -1;
  5021. cli_local_t *local = NULL;
  5022. char *volname = NULL;
  5023. call_frame_t *frame = NULL;
  5024. dict_t *input_dict = NULL;
  5025. dict_t *dict = NULL;
  5026. int brick_count = 0;
  5027. int i = 0;
  5028. gf_xl_afr_op_t heal_op = GF_AFR_OP_INVALID;
  5029. char *operation = NULL;
  5030. char *substr = NULL;
  5031. if (-1 == req->rpc_status) {
  5032. goto out;
  5033. }
  5034. ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  5035. if (ret < 0) {
  5036. gf_log ("", GF_LOG_ERROR, "error");
  5037. goto out;
  5038. }
  5039. frame = myframe;
  5040. if (frame)
  5041. local = frame->local;
  5042. if (local) {
  5043. input_dict = local->dict;
  5044. ret = dict_get_int32 (input_dict, "heal-op",
  5045. (int32_t*)&heal_op);
  5046. }
  5047. //TODO: Proper XML output
  5048. //#if (HAVE_LIB_XML)
  5049. // if (global_state->mode & GLUSTER_MODE_XML) {
  5050. // ret = cli_xml_output_dict ("volHeal", dict, rsp.op_ret,
  5051. // rsp.op_errno, rsp.op_errstr);
  5052. // if (ret)
  5053. // gf_log ("cli", GF_LOG_ERROR,
  5054. // "Error outputting to xml");
  5055. // goto out;
  5056. // }
  5057. //#endif
  5058. ret = dict_get_str (input_dict, "volname", &volname);
  5059. if (ret) {
  5060. gf_log (THIS->name, GF_LOG_ERROR, "failed to get volname");
  5061. goto out;
  5062. }
  5063. gf_log ("cli", GF_LOG_INFO, "Received resp to heal volume");
  5064. if ((heal_op == GF_AFR_OP_HEAL_FULL) ||
  5065. (heal_op == GF_AFR_OP_HEAL_INDEX)) {
  5066. operation = "Launching Heal operation";
  5067. substr = "\nUse heal info commands to check status";
  5068. } else {
  5069. operation = "Gathering Heal info";
  5070. substr = "";
  5071. }
  5072. if (rsp.op_ret) {
  5073. if (strcmp (rsp.op_errstr, "")) {
  5074. cli_err ("%s", rsp.op_errstr);
  5075. } else {
  5076. cli_err ("%s on volume %s has been unsuccessful",
  5077. operation, volname);
  5078. }
  5079. ret = rsp.op_ret;
  5080. goto out;
  5081. } else {
  5082. cli_out ("%s on volume %s has been successful%s", operation,
  5083. volname, substr);
  5084. }
  5085. ret = rsp.op_ret;
  5086. if ((heal_op == GF_AFR_OP_HEAL_FULL) ||
  5087. (heal_op == GF_AFR_OP_HEAL_INDEX))
  5088. goto out;
  5089. dict = dict_new ();
  5090. if (!dict) {
  5091. ret = -1;
  5092. goto out;
  5093. }
  5094. ret = dict_unserialize (rsp.dict.dict_val,
  5095. rsp.dict.dict_len,
  5096. &dict);
  5097. if (ret) {
  5098. gf_log ("", GF_LOG_ERROR,
  5099. "Unable to allocate memory");
  5100. goto out;
  5101. } else {
  5102. dict->extra_stdfree = rsp.dict.dict_val;
  5103. }
  5104. ret = dict_get_int32 (dict, "count", &brick_count);
  5105. if (ret)
  5106. goto out;
  5107. if (!brick_count) {
  5108. cli_err ("All bricks of volume %s are down.", volname);
  5109. goto out;
  5110. }
  5111. for (i = 0; i < brick_count; i++)
  5112. cmd_heal_volume_brick_out (dict, i);
  5113. ret = rsp.op_ret;
  5114. out:
  5115. cli_cmd_broadcast_response (ret);
  5116. free (rsp.op_errstr);
  5117. if (dict)
  5118. dict_unref (dict);
  5119. return ret;
  5120. }
  5121. int32_t
  5122. gf_cli_heal_volume (call_frame_t *frame, xlator_t *this,
  5123. void *data)
  5124. {
  5125. gf_cli_req req = {{0,}};
  5126. int ret = 0;
  5127. dict_t *dict = NULL;
  5128. if (!frame || !this || !data) {
  5129. ret = -1;
  5130. goto out;
  5131. }
  5132. dict = data;
  5133. ret = cli_to_glusterd (&req, frame, gf_cli_heal_volume_cbk,
  5134. (xdrproc_t) xdr_gf_cli_req, dict,
  5135. GLUSTER_CLI_HEAL_VOLUME, this, cli_rpc_prog,
  5136. NULL);
  5137. out:
  5138. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  5139. GF_FREE (req.dict.dict_val);
  5140. return ret;
  5141. }
  5142. int32_t
  5143. gf_cli_statedump_volume_cbk (struct rpc_req *req, struct iovec *iov,
  5144. int count, void *myframe)
  5145. {
  5146. gf_cli_rsp rsp = {0,};
  5147. int ret = -1;
  5148. char msg[1024] = {0,};
  5149. if (-1 == req->rpc_status)
  5150. goto out;
  5151. ret = xdr_to_generic (*iov, &rsp,
  5152. (xdrproc_t)xdr_gf_cli_rsp);
  5153. if (ret < 0) {
  5154. gf_log (THIS->name, GF_LOG_ERROR, "XDR decoding failed");
  5155. goto out;
  5156. }
  5157. gf_log ("cli", GF_LOG_DEBUG, "Received response to statedump");
  5158. if (rsp.op_ret)
  5159. snprintf (msg, sizeof(msg), "%s", rsp.op_errstr);
  5160. else
  5161. snprintf (msg, sizeof (msg), "Volume statedump successful");
  5162. if (global_state->mode & GLUSTER_MODE_XML) {
  5163. ret = cli_xml_output_str ("volStatedump", msg, rsp.op_ret,
  5164. rsp.op_errno, rsp.op_errstr);
  5165. if (ret)
  5166. gf_log ("cli", GF_LOG_ERROR,
  5167. "Error outputting to xml");
  5168. goto out;
  5169. }
  5170. if (rsp.op_ret)
  5171. cli_err ("volume statedump: failed: %s", msg);
  5172. else
  5173. cli_out ("volume statedump: success");
  5174. ret = rsp.op_ret;
  5175. out:
  5176. cli_cmd_broadcast_response (ret);
  5177. return ret;
  5178. }
  5179. int32_t
  5180. gf_cli_statedump_volume (call_frame_t *frame, xlator_t *this,
  5181. void *data)
  5182. {
  5183. gf_cli_req req = {{0,}};
  5184. dict_t *options = NULL;
  5185. int ret = -1;
  5186. if (!frame || !this || !data)
  5187. goto out;
  5188. options = data;
  5189. ret = cli_to_glusterd (&req, frame, gf_cli_statedump_volume_cbk,
  5190. (xdrproc_t) xdr_gf_cli_req, options,
  5191. GLUSTER_CLI_STATEDUMP_VOLUME, this, cli_rpc_prog,
  5192. NULL);
  5193. out:
  5194. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  5195. GF_FREE (req.dict.dict_val);
  5196. return ret;
  5197. }
  5198. int32_t
  5199. gf_cli_list_volume_cbk (struct rpc_req *req, struct iovec *iov,
  5200. int count, void *myframe)
  5201. {
  5202. int ret = -1;
  5203. gf_cli_rsp rsp = {0,};
  5204. dict_t *dict = NULL;
  5205. int vol_count = 0;;
  5206. char *volname = NULL;
  5207. char key[1024] = {0,};
  5208. int i = 0;
  5209. if (-1 == req->rpc_status)
  5210. goto out;
  5211. ret = xdr_to_generic (*iov, &rsp,
  5212. (xdrproc_t)xdr_gf_cli_rsp);
  5213. if (ret < 0) {
  5214. gf_log (THIS->name, GF_LOG_ERROR, "XDR decoding failed");
  5215. goto out;
  5216. }
  5217. dict = dict_new ();
  5218. if (!dict) {
  5219. ret = -1;
  5220. goto out;
  5221. }
  5222. ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
  5223. if (ret) {
  5224. gf_log ("cli", GF_LOG_ERROR, "Unable to allocate memory");
  5225. goto out;
  5226. }
  5227. if (global_state->mode & GLUSTER_MODE_XML) {
  5228. ret = cli_xml_output_vol_list (dict, rsp.op_ret, rsp.op_errno,
  5229. rsp.op_errstr);
  5230. if (ret)
  5231. gf_log ("cli", GF_LOG_ERROR,
  5232. "Error outputting to xml");
  5233. goto out;
  5234. }
  5235. if (rsp.op_ret)
  5236. cli_err ("%s", rsp.op_errstr);
  5237. else {
  5238. ret = dict_get_int32 (dict, "count", &vol_count);
  5239. if (ret)
  5240. goto out;
  5241. if (vol_count == 0) {
  5242. cli_err ("No volumes present in cluster");
  5243. goto out;
  5244. }
  5245. for (i = 0; i < vol_count; i++) {
  5246. memset (key, 0, sizeof (key));
  5247. snprintf (key, sizeof (key), "volume%d", i);
  5248. ret = dict_get_str (dict, key, &volname);
  5249. if (ret)
  5250. goto out;
  5251. cli_out ("%s", volname);
  5252. }
  5253. }
  5254. ret = rsp.op_ret;
  5255. out:
  5256. cli_cmd_broadcast_response (ret);
  5257. return ret;
  5258. }
  5259. int32_t
  5260. gf_cli_list_volume (call_frame_t *frame, xlator_t *this, void *data)
  5261. {
  5262. int ret = -1;
  5263. gf_cli_req req = {{0,}};
  5264. if (!frame || !this)
  5265. goto out;
  5266. ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
  5267. GLUSTER_CLI_LIST_VOLUME, NULL,
  5268. this, gf_cli_list_volume_cbk,
  5269. (xdrproc_t)xdr_gf_cli_req);
  5270. out:
  5271. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  5272. return ret;
  5273. }
  5274. int32_t
  5275. gf_cli_clearlocks_volume_cbk (struct rpc_req *req, struct iovec *iov,
  5276. int count, void *myframe)
  5277. {
  5278. gf_cli_rsp rsp = {0,};
  5279. int ret = -1;
  5280. char *lk_summary = NULL;
  5281. char *volname = NULL;
  5282. dict_t *dict = NULL;
  5283. if (-1 == req->rpc_status)
  5284. goto out;
  5285. ret = xdr_to_generic (*iov, &rsp,
  5286. (xdrproc_t)xdr_gf_cli_rsp);
  5287. if (ret < 0) {
  5288. gf_log ("cli", GF_LOG_ERROR, "XDR decoding failed");
  5289. goto out;
  5290. }
  5291. gf_log ("cli", GF_LOG_DEBUG, "Received response to clear-locks");
  5292. if (rsp.op_ret) {
  5293. cli_err ("Volume clear-locks unsuccessful");
  5294. cli_err ("%s", rsp.op_errstr);
  5295. } else {
  5296. if (!rsp.dict.dict_len) {
  5297. cli_err ("Possibly no locks cleared");
  5298. ret = 0;
  5299. goto out;
  5300. }
  5301. dict = dict_new ();
  5302. if (!dict) {
  5303. ret = -1;
  5304. goto out;
  5305. }
  5306. ret = dict_unserialize (rsp.dict.dict_val,
  5307. rsp.dict.dict_len,
  5308. &dict);
  5309. if (ret) {
  5310. gf_log ("cli", GF_LOG_ERROR,
  5311. "Unable to serialize response dictionary");
  5312. goto out;
  5313. }
  5314. ret = dict_get_str (dict, "volname", &volname);
  5315. if (ret) {
  5316. gf_log ("cli", GF_LOG_ERROR, "Unable to get volname "
  5317. "from dictionary");
  5318. goto out;
  5319. }
  5320. ret = dict_get_str (dict, "lk-summary", &lk_summary);
  5321. if (ret) {
  5322. gf_log ("cli", GF_LOG_ERROR, "Unable to get lock "
  5323. "summary from dictionary");
  5324. goto out;
  5325. }
  5326. cli_out ("Volume clear-locks successful");
  5327. cli_out ("%s", lk_summary);
  5328. }
  5329. ret = rsp.op_ret;
  5330. out:
  5331. if (dict)
  5332. dict_unref (dict);
  5333. cli_cmd_broadcast_response (ret);
  5334. return ret;
  5335. }
  5336. int32_t
  5337. gf_cli_clearlocks_volume (call_frame_t *frame, xlator_t *this,
  5338. void *data)
  5339. {
  5340. gf_cli_req req = {{0,}};
  5341. dict_t *options = NULL;
  5342. int ret = -1;
  5343. if (!frame || !this || !data)
  5344. goto out;
  5345. options = data;
  5346. ret = cli_to_glusterd (&req, frame, gf_cli_clearlocks_volume_cbk,
  5347. (xdrproc_t) xdr_gf_cli_req, options,
  5348. GLUSTER_CLI_CLRLOCKS_VOLUME, this, cli_rpc_prog,
  5349. NULL);
  5350. out:
  5351. gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
  5352. GF_FREE (req.dict.dict_val);
  5353. return ret;
  5354. }
  5355. int
  5356. cli_to_glusterd (gf_cli_req *req, call_frame_t *frame,
  5357. fop_cbk_fn_t cbkfn, xdrproc_t xdrproc, dict_t *dict,
  5358. int procnum, xlator_t *this, rpc_clnt_prog_t *prog,
  5359. struct iobref *iobref)
  5360. {
  5361. int ret = 0;
  5362. size_t len = 0;
  5363. char *cmd = NULL;
  5364. int i = 0;
  5365. const char **words = NULL;
  5366. cli_local_t *local = NULL;
  5367. if (!this || !frame || !dict) {
  5368. ret = -1;
  5369. goto out;
  5370. }
  5371. if (!frame->local) {
  5372. ret = -1;
  5373. goto out;
  5374. }
  5375. local = frame->local;
  5376. if (!local->words) {
  5377. ret = -1;
  5378. goto out;
  5379. }
  5380. words = local->words;
  5381. while (words[i])
  5382. len += strlen (words[i++]) + 1;
  5383. cmd = GF_CALLOC (1, len, gf_common_mt_char);
  5384. if (!cmd) {
  5385. ret = -1;
  5386. goto out;
  5387. }
  5388. for (i = 0; words[i]; i++) {
  5389. strncat (cmd, words[i], strlen (words[i]));
  5390. if (words[i+1] != NULL)
  5391. strncat (cmd, " ", strlen (" "));
  5392. }
  5393. cmd [len - 1] = '\0';
  5394. ret = dict_set_dynstr (dict, "cmd-str", cmd);
  5395. if (ret)
  5396. goto out;
  5397. ret = dict_allocate_and_serialize (dict, &(req->dict).dict_val,
  5398. &(req->dict).dict_len);
  5399. if (ret < 0) {
  5400. gf_log (this->name, GF_LOG_DEBUG,
  5401. "failed to get serialized length of dict");
  5402. goto out;
  5403. }
  5404. ret = cli_cmd_submit (req, frame, prog, procnum, iobref, this,
  5405. cbkfn, (xdrproc_t) xdrproc);
  5406. out:
  5407. return ret;
  5408. }
  5409. struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {
  5410. [GLUSTER_CLI_NULL] = {"NULL", NULL },
  5411. [GLUSTER_CLI_PROBE] = {"PROBE_QUERY", gf_cli_probe},
  5412. [GLUSTER_CLI_DEPROBE] = {"DEPROBE_QUERY", gf_cli_deprobe},
  5413. [GLUSTER_CLI_LIST_FRIENDS] = {"LIST_FRIENDS", gf_cli_list_friends},
  5414. [GLUSTER_CLI_UUID_RESET] = {"UUID_RESET", gf_cli3_1_uuid_reset},
  5415. [GLUSTER_CLI_CREATE_VOLUME] = {"CREATE_VOLUME", gf_cli_create_volume},
  5416. [GLUSTER_CLI_DELETE_VOLUME] = {"DELETE_VOLUME", gf_cli_delete_volume},
  5417. [GLUSTER_CLI_START_VOLUME] = {"START_VOLUME", gf_cli_start_volume},
  5418. [GLUSTER_CLI_STOP_VOLUME] = {"STOP_VOLUME", gf_cli_stop_volume},
  5419. [GLUSTER_CLI_RENAME_VOLUME] = {"RENAME_VOLUME", gf_cli_rename_volume},
  5420. [GLUSTER_CLI_DEFRAG_VOLUME] = {"DEFRAG_VOLUME", gf_cli_defrag_volume},
  5421. [GLUSTER_CLI_GET_VOLUME] = {"GET_VOLUME", gf_cli_get_volume},
  5422. [GLUSTER_CLI_GET_NEXT_VOLUME] = {"GET_NEXT_VOLUME", gf_cli_get_next_volume},
  5423. [GLUSTER_CLI_SET_VOLUME] = {"SET_VOLUME", gf_cli_set_volume},
  5424. [GLUSTER_CLI_ADD_BRICK] = {"ADD_BRICK", gf_cli_add_brick},
  5425. [GLUSTER_CLI_REMOVE_BRICK] = {"REMOVE_BRICK", gf_cli_remove_brick},
  5426. [GLUSTER_CLI_REPLACE_BRICK] = {"REPLACE_BRICK", gf_cli_replace_brick},
  5427. [GLUSTER_CLI_LOG_ROTATE] = {"LOG ROTATE", gf_cli_log_rotate},
  5428. [GLUSTER_CLI_GETSPEC] = {"GETSPEC", gf_cli_getspec},
  5429. [GLUSTER_CLI_PMAP_PORTBYBRICK] = {"PMAP PORTBYBRICK", gf_cli_pmap_b2p},
  5430. [GLUSTER_CLI_SYNC_VOLUME] = {"SYNC_VOLUME", gf_cli_sync_volume},
  5431. [GLUSTER_CLI_RESET_VOLUME] = {"RESET_VOLUME", gf_cli_reset_volume},
  5432. [GLUSTER_CLI_FSM_LOG] = {"FSM_LOG", gf_cli_fsm_log},
  5433. [GLUSTER_CLI_GSYNC_SET] = {"GSYNC_SET", gf_cli_gsync_set},
  5434. [GLUSTER_CLI_PROFILE_VOLUME] = {"PROFILE_VOLUME", gf_cli_profile_volume},
  5435. [GLUSTER_CLI_QUOTA] = {"QUOTA", gf_cli_quota},
  5436. [GLUSTER_CLI_TOP_VOLUME] = {"TOP_VOLUME", gf_cli_top_volume},
  5437. [GLUSTER_CLI_GETWD] = {"GETWD", gf_cli_getwd},
  5438. [GLUSTER_CLI_STATUS_VOLUME] = {"STATUS_VOLUME", gf_cli_status_volume},
  5439. [GLUSTER_CLI_STATUS_ALL] = {"STATUS_ALL", gf_cli_status_volume_all},
  5440. [GLUSTER_CLI_MOUNT] = {"MOUNT", gf_cli_mount},
  5441. [GLUSTER_CLI_UMOUNT] = {"UMOUNT", gf_cli_umount},
  5442. [GLUSTER_CLI_HEAL_VOLUME] = {"HEAL_VOLUME", gf_cli_heal_volume},
  5443. [GLUSTER_CLI_STATEDUMP_VOLUME] = {"STATEDUMP_VOLUME", gf_cli_statedump_volume},
  5444. [GLUSTER_CLI_LIST_VOLUME] = {"LIST_VOLUME", gf_cli_list_volume},
  5445. [GLUSTER_CLI_CLRLOCKS_VOLUME] = {"CLEARLOCKS_VOLUME", gf_cli_clearlocks_volume},
  5446. #ifdef HAVE_BD_XLATOR
  5447. [GLUSTER_CLI_BD_OP] = {"BD_OP", gf_cli_bd_op},
  5448. #endif
  5449. };
  5450. struct rpc_clnt_program cli_prog = {
  5451. .progname = "Gluster CLI",
  5452. .prognum = GLUSTER_CLI_PROGRAM,
  5453. .progver = GLUSTER_CLI_VERSION,
  5454. .numproc = GLUSTER_CLI_MAXVALUE,
  5455. .proctable = gluster_cli_actors,
  5456. };