PageRenderTime 62ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/usr/src/cmd/sbdadm/sbdadm.c

https://bitbucket.org/illumos/illumos-gate/
C | 752 lines | 639 code | 66 blank | 47 comment | 93 complexity | f75576494d547266f7e7514043a7b467 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.0, BSD-3-Clause-No-Nuclear-License-2014, AGPL-1.0, AGPL-3.0, BSD-3-Clause, GPL-3.0, LGPL-2.1, BSD-2-Clause, MPL-2.0-no-copyleft-exception, GPL-2.0, 0BSD
  1. /*
  2. * CDDL HEADER START
  3. *
  4. * The contents of this file are subject to the terms of the
  5. * Common Development and Distribution License (the "License").
  6. * You may not use this file except in compliance with the License.
  7. *
  8. * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  9. * or http://www.opensolaris.org/os/licensing.
  10. * See the License for the specific language governing permissions
  11. * and limitations under the License.
  12. *
  13. * When distributing Covered Code, include this CDDL HEADER in each
  14. * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15. * If applicable, add the following below this CDDL HEADER, with the
  16. * fields enclosed by brackets "[]" replaced with your own identifying
  17. * information: Portions Copyright [yyyy] [name of copyright owner]
  18. *
  19. * CDDL HEADER END
  20. */
  21. /*
  22. * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
  23. * Use is subject to license terms.
  24. * Copyright 2012 Milan Jurik. All rights reserved.
  25. */
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #include <fcntl.h>
  31. #include <unistd.h>
  32. #include <libintl.h>
  33. #include <errno.h>
  34. #include <string.h>
  35. #include <assert.h>
  36. #include <getopt.h>
  37. #include <strings.h>
  38. #include <ctype.h>
  39. #include <libnvpair.h>
  40. #include <locale.h>
  41. #include <cmdparse.h>
  42. #include <sys/stmf_defines.h>
  43. #include <libstmf.h>
  44. #include <sys/stmf_sbd_ioctl.h>
  45. #define MAX_LU_LIST 8192
  46. #define LU_LIST_MAX_RETRIES 3
  47. #define GUID_INPUT 32
  48. #define VERSION_STRING_MAJOR "1"
  49. #define VERSION_STRING_MINOR "0"
  50. #define VERSION_STRING_MAX_LEN 10
  51. char *cmdName;
  52. static char *getExecBasename(char *);
  53. int delete_lu(int argc, char *argv[], cmdOptions_t *options,
  54. void *callData);
  55. int create_lu(int argc, char *argv[], cmdOptions_t *options, void *callData);
  56. int list_lus(int argc, char *argv[], cmdOptions_t *options, void *callData);
  57. int modify_lu(int argc, char *argv[], cmdOptions_t *options, void *callData);
  58. int import_lu(int argc, char *argv[], cmdOptions_t *options, void *callData);
  59. static int callModify(char *, stmfGuid *, uint32_t, const char *, const char *);
  60. int print_lu_attr(stmfGuid *);
  61. void print_guid(uint8_t *g, FILE *f);
  62. void print_attr_header();
  63. optionTbl_t options[] = {
  64. { "disk-size", required_argument, 's',
  65. "Size with <none>/k/m/g/t/p/e modifier" },
  66. { "keep-views", no_arg, 'k',
  67. "Dont delete view entries related to the LU" },
  68. { NULL, 0, 0 }
  69. };
  70. subCommandProps_t subCommands[] = {
  71. { "create-lu", create_lu, "s", NULL, NULL,
  72. OPERAND_MANDATORY_SINGLE,
  73. "Full path of the file to initialize" },
  74. { "delete-lu", delete_lu, "k", NULL, NULL,
  75. OPERAND_MANDATORY_SINGLE, "GUID of the LU to deregister" },
  76. { "import-lu", import_lu, NULL, NULL, NULL,
  77. OPERAND_MANDATORY_SINGLE, "filename of the LU to import" },
  78. { "list-lu", list_lus, NULL, NULL, NULL,
  79. OPERAND_NONE, "List all the exported LUs" },
  80. { "modify-lu", modify_lu, "s", "s", NULL,
  81. OPERAND_MANDATORY_SINGLE,
  82. "Full path of the LU or GUID of a registered LU" },
  83. { NULL, 0, 0, NULL, 0, NULL}
  84. };
  85. /*ARGSUSED*/
  86. int
  87. create_lu(int argc, char *operands[], cmdOptions_t *options, void *callData)
  88. {
  89. luResource hdl = NULL;
  90. int ret = 0;
  91. stmfGuid createdGuid;
  92. ret = stmfCreateLuResource(STMF_DISK, &hdl);
  93. if (ret != STMF_STATUS_SUCCESS) {
  94. (void) fprintf(stderr, "%s: %s\n",
  95. cmdName, gettext("Failure to create lu resource\n"));
  96. return (1);
  97. }
  98. for (; options->optval; options++) {
  99. switch (options->optval) {
  100. case 's':
  101. ret = stmfSetLuProp(hdl, STMF_LU_PROP_SIZE,
  102. options->optarg);
  103. if (ret != STMF_STATUS_SUCCESS) {
  104. (void) fprintf(stderr, "%s: %c: %s\n",
  105. cmdName, options->optval,
  106. gettext("size param invalid"));
  107. (void) stmfFreeLuResource(hdl);
  108. return (1);
  109. }
  110. break;
  111. default:
  112. (void) fprintf(stderr, "%s: %c: %s\n",
  113. cmdName, options->optval,
  114. gettext("unknown option"));
  115. return (1);
  116. }
  117. }
  118. ret = stmfSetLuProp(hdl, STMF_LU_PROP_FILENAME, operands[0]);
  119. if (ret != STMF_STATUS_SUCCESS) {
  120. (void) fprintf(stderr, "%s: %s\n",
  121. cmdName, gettext("could not set filename"));
  122. return (1);
  123. }
  124. ret = stmfCreateLu(hdl, &createdGuid);
  125. switch (ret) {
  126. case STMF_STATUS_SUCCESS:
  127. break;
  128. case STMF_ERROR_BUSY:
  129. case STMF_ERROR_LU_BUSY:
  130. (void) fprintf(stderr, "%s: %s\n", cmdName,
  131. gettext("resource busy"));
  132. ret++;
  133. break;
  134. case STMF_ERROR_PERM:
  135. (void) fprintf(stderr, "%s: %s\n", cmdName,
  136. gettext("permission denied"));
  137. ret++;
  138. break;
  139. case STMF_ERROR_FILE_IN_USE:
  140. (void) fprintf(stderr, "%s: filename %s: %s\n", cmdName,
  141. operands[0], gettext("in use"));
  142. ret++;
  143. break;
  144. case STMF_ERROR_INVALID_BLKSIZE:
  145. (void) fprintf(stderr, "%s: %s\n", cmdName,
  146. gettext("invalid block size"));
  147. ret++;
  148. break;
  149. case STMF_ERROR_GUID_IN_USE:
  150. (void) fprintf(stderr, "%s: %s\n", cmdName,
  151. gettext("guid in use"));
  152. ret++;
  153. break;
  154. case STMF_ERROR_META_FILE_NAME:
  155. (void) fprintf(stderr, "%s: %s\n", cmdName,
  156. gettext("meta file error"));
  157. ret++;
  158. break;
  159. case STMF_ERROR_DATA_FILE_NAME:
  160. (void) fprintf(stderr, "%s: %s\n", cmdName,
  161. gettext("data file error"));
  162. ret++;
  163. break;
  164. case STMF_ERROR_SIZE_OUT_OF_RANGE:
  165. (void) fprintf(stderr, "%s: %s\n", cmdName,
  166. gettext("invalid size"));
  167. ret++;
  168. break;
  169. case STMF_ERROR_META_CREATION:
  170. (void) fprintf(stderr, "%s: %s\n", cmdName,
  171. gettext("could not create meta file"));
  172. ret++;
  173. break;
  174. default:
  175. (void) fprintf(stderr, "%s: %s\n", cmdName,
  176. gettext("unknown error"));
  177. ret++;
  178. break;
  179. }
  180. if (ret != STMF_STATUS_SUCCESS) {
  181. goto done;
  182. }
  183. (void) printf("Created the following LU:\n");
  184. print_attr_header();
  185. ret = print_lu_attr(&createdGuid);
  186. done:
  187. (void) stmfFreeLuResource(hdl);
  188. return (ret);
  189. }
  190. /*ARGSUSED*/
  191. int
  192. import_lu(int argc, char *operands[], cmdOptions_t *options, void *callData)
  193. {
  194. int ret = 0;
  195. stmfGuid createdGuid;
  196. ret = stmfImportLu(STMF_DISK, operands[0], &createdGuid);
  197. switch (ret) {
  198. case STMF_STATUS_SUCCESS:
  199. break;
  200. case STMF_ERROR_BUSY:
  201. case STMF_ERROR_LU_BUSY:
  202. (void) fprintf(stderr, "%s: %s\n", cmdName,
  203. gettext("resource busy"));
  204. ret++;
  205. break;
  206. case STMF_ERROR_PERM:
  207. (void) fprintf(stderr, "%s: %s\n", cmdName,
  208. gettext("permission denied"));
  209. ret++;
  210. break;
  211. case STMF_ERROR_FILE_IN_USE:
  212. (void) fprintf(stderr, "%s: filename %s: %s\n", cmdName,
  213. operands[0], gettext("in use"));
  214. ret++;
  215. break;
  216. case STMF_ERROR_GUID_IN_USE:
  217. (void) fprintf(stderr, "%s: %s\n", cmdName,
  218. gettext("guid in use"));
  219. ret++;
  220. break;
  221. case STMF_ERROR_META_FILE_NAME:
  222. (void) fprintf(stderr, "%s: %s\n", cmdName,
  223. gettext("meta file error"));
  224. ret++;
  225. break;
  226. case STMF_ERROR_DATA_FILE_NAME:
  227. (void) fprintf(stderr, "%s: %s\n", cmdName,
  228. gettext("data file error"));
  229. ret++;
  230. break;
  231. case STMF_ERROR_SIZE_OUT_OF_RANGE:
  232. (void) fprintf(stderr, "%s: %s\n", cmdName,
  233. gettext("invalid size"));
  234. ret++;
  235. break;
  236. case STMF_ERROR_META_CREATION:
  237. (void) fprintf(stderr, "%s: %s\n", cmdName,
  238. gettext("could not create meta file"));
  239. ret++;
  240. break;
  241. default:
  242. (void) fprintf(stderr, "%s: %s\n", cmdName,
  243. gettext("unknown error"));
  244. ret++;
  245. break;
  246. }
  247. if (ret != STMF_STATUS_SUCCESS) {
  248. goto done;
  249. }
  250. (void) printf("Imported the following LU:\n");
  251. print_attr_header();
  252. ret = print_lu_attr(&createdGuid);
  253. done:
  254. return (ret);
  255. }
  256. /*ARGSUSED*/
  257. int
  258. delete_lu(int operandLen, char *operands[], cmdOptions_t *options,
  259. void *callData)
  260. {
  261. int i, j;
  262. int ret = 0;
  263. int stmfRet;
  264. unsigned int inGuid[sizeof (stmfGuid)];
  265. stmfGuid delGuid;
  266. boolean_t keepViews = B_FALSE;
  267. boolean_t viewEntriesRemoved = B_FALSE;
  268. boolean_t noLunFound = B_FALSE;
  269. boolean_t views = B_FALSE;
  270. boolean_t notValidHexNumber = B_FALSE;
  271. char sGuid[GUID_INPUT + 1];
  272. stmfViewEntryList *viewEntryList = NULL;
  273. for (; options->optval; options++) {
  274. switch (options->optval) {
  275. /* Keep views for logical unit */
  276. case 'k':
  277. keepViews = B_TRUE;
  278. break;
  279. default:
  280. (void) fprintf(stderr, "%s: %c: %s\n",
  281. cmdName, options->optval,
  282. gettext("unknown option"));
  283. return (1);
  284. }
  285. }
  286. for (i = 0; i < operandLen; i++) {
  287. for (j = 0; j < GUID_INPUT; j++) {
  288. if (!isxdigit(operands[i][j])) {
  289. notValidHexNumber = B_TRUE;
  290. break;
  291. }
  292. sGuid[j] = tolower(operands[i][j]);
  293. }
  294. if ((notValidHexNumber == B_TRUE) ||
  295. (strlen(operands[i]) != GUID_INPUT)) {
  296. (void) fprintf(stderr, "%s: %s: %s%d%s\n",
  297. cmdName, operands[i], gettext("must be "),
  298. GUID_INPUT,
  299. gettext(" hexadecimal digits long"));
  300. notValidHexNumber = B_FALSE;
  301. ret++;
  302. continue;
  303. }
  304. sGuid[j] = 0;
  305. (void) sscanf(sGuid,
  306. "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
  307. &inGuid[0], &inGuid[1], &inGuid[2], &inGuid[3],
  308. &inGuid[4], &inGuid[5], &inGuid[6], &inGuid[7],
  309. &inGuid[8], &inGuid[9], &inGuid[10], &inGuid[11],
  310. &inGuid[12], &inGuid[13], &inGuid[14], &inGuid[15]);
  311. for (j = 0; j < sizeof (stmfGuid); j++) {
  312. delGuid.guid[j] = inGuid[j];
  313. }
  314. stmfRet = stmfDeleteLu(&delGuid);
  315. switch (stmfRet) {
  316. case STMF_STATUS_SUCCESS:
  317. break;
  318. case STMF_ERROR_NOT_FOUND:
  319. noLunFound = B_TRUE;
  320. break;
  321. case STMF_ERROR_BUSY:
  322. (void) fprintf(stderr, "%s: %s\n", cmdName,
  323. gettext("resource busy"));
  324. ret++;
  325. break;
  326. case STMF_ERROR_PERM:
  327. (void) fprintf(stderr, "%s: %s\n", cmdName,
  328. gettext("permission denied"));
  329. ret++;
  330. break;
  331. default:
  332. (void) fprintf(stderr, "%s: %s\n", cmdName,
  333. gettext("unknown error"));
  334. ret++;
  335. break;
  336. }
  337. if (!keepViews) {
  338. stmfRet = stmfGetViewEntryList(&delGuid,
  339. &viewEntryList);
  340. if (stmfRet == STMF_STATUS_SUCCESS) {
  341. for (j = 0; j < viewEntryList->cnt; j++) {
  342. (void) stmfRemoveViewEntry(&delGuid,
  343. viewEntryList->ve[j].veIndex);
  344. }
  345. /* check if viewEntryList is empty */
  346. if (viewEntryList->cnt != 0)
  347. viewEntriesRemoved = B_TRUE;
  348. stmfFreeMemory(viewEntryList);
  349. } else {
  350. (void) fprintf(stderr, "%s: %s\n", cmdName,
  351. gettext("unable to remove view entries\n"));
  352. ret++;
  353. }
  354. }
  355. if (keepViews) {
  356. stmfRet = stmfGetViewEntryList(&delGuid,
  357. &viewEntryList);
  358. if (stmfRet == STMF_STATUS_SUCCESS) {
  359. views = B_TRUE;
  360. stmfFreeMemory(viewEntryList);
  361. }
  362. }
  363. if ((!viewEntriesRemoved && noLunFound && !views) ||
  364. (!views && keepViews && noLunFound)) {
  365. (void) fprintf(stderr, "%s: %s: %s\n",
  366. cmdName, sGuid,
  367. gettext("not found"));
  368. ret++;
  369. }
  370. noLunFound = viewEntriesRemoved = views = B_FALSE;
  371. }
  372. return (ret);
  373. }
  374. /*ARGSUSED*/
  375. int
  376. modify_lu(int operandLen, char *operands[], cmdOptions_t *options,
  377. void *callData)
  378. {
  379. stmfGuid inGuid;
  380. unsigned int guid[sizeof (stmfGuid)];
  381. int ret = 0;
  382. int i;
  383. char *fname = NULL;
  384. char sGuid[GUID_INPUT + 1];
  385. boolean_t fnameUsed = B_FALSE;
  386. if (operands[0][0] == '/') {
  387. fnameUsed = B_TRUE;
  388. fname = operands[0];
  389. }
  390. /* check input length */
  391. if (!fnameUsed && strlen(operands[0]) != GUID_INPUT) {
  392. (void) fprintf(stderr, "%s: %s: %s%d%s\n", cmdName, operands[0],
  393. gettext("must be "), GUID_INPUT,
  394. gettext(" hexadecimal digits"));
  395. return (1);
  396. }
  397. if (!fnameUsed) {
  398. /* convert to lower case for scan */
  399. for (i = 0; i < 32; i++)
  400. sGuid[i] = tolower(operands[0][i]);
  401. sGuid[i] = 0;
  402. (void) sscanf(sGuid,
  403. "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
  404. &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], &guid[5],
  405. &guid[6], &guid[7], &guid[8], &guid[9], &guid[10],
  406. &guid[11], &guid[12], &guid[13], &guid[14], &guid[15]);
  407. for (i = 0; i < sizeof (stmfGuid); i++) {
  408. inGuid.guid[i] = guid[i];
  409. }
  410. }
  411. for (; options->optval; options++) {
  412. switch (options->optval) {
  413. case 's':
  414. if (callModify(fname, &inGuid,
  415. STMF_LU_PROP_SIZE, options->optarg,
  416. "size") != 0) {
  417. return (1);
  418. }
  419. break;
  420. default:
  421. (void) fprintf(stderr, "%s: %c: %s\n",
  422. cmdName, options->optval,
  423. gettext("unknown option"));
  424. return (1);
  425. }
  426. }
  427. return (ret);
  428. }
  429. static int
  430. callModify(char *fname, stmfGuid *luGuid, uint32_t prop, const char *propVal,
  431. const char *propString)
  432. {
  433. int ret = 0;
  434. int stmfRet = 0;
  435. if (!fname) {
  436. stmfRet = stmfModifyLu(luGuid, prop, propVal);
  437. } else {
  438. stmfRet = stmfModifyLuByFname(STMF_DISK, fname, prop,
  439. propVal);
  440. }
  441. switch (stmfRet) {
  442. case STMF_STATUS_SUCCESS:
  443. break;
  444. case STMF_ERROR_BUSY:
  445. case STMF_ERROR_LU_BUSY:
  446. (void) fprintf(stderr, "%s: %s\n", cmdName,
  447. gettext("resource busy"));
  448. ret++;
  449. break;
  450. case STMF_ERROR_PERM:
  451. (void) fprintf(stderr, "%s: %s\n", cmdName,
  452. gettext("permission denied"));
  453. ret++;
  454. break;
  455. case STMF_ERROR_INVALID_BLKSIZE:
  456. (void) fprintf(stderr, "%s: %s\n", cmdName,
  457. gettext("invalid block size"));
  458. ret++;
  459. break;
  460. case STMF_ERROR_GUID_IN_USE:
  461. (void) fprintf(stderr, "%s: %s\n", cmdName,
  462. gettext("guid in use"));
  463. ret++;
  464. break;
  465. case STMF_ERROR_META_FILE_NAME:
  466. (void) fprintf(stderr, "%s: %s\n", cmdName,
  467. gettext("meta file error"));
  468. ret++;
  469. break;
  470. case STMF_ERROR_DATA_FILE_NAME:
  471. (void) fprintf(stderr, "%s: %s\n", cmdName,
  472. gettext("data file error"));
  473. ret++;
  474. break;
  475. case STMF_ERROR_FILE_SIZE_INVALID:
  476. (void) fprintf(stderr, "%s: %s\n", cmdName,
  477. gettext("file size invalid"));
  478. ret++;
  479. break;
  480. case STMF_ERROR_SIZE_OUT_OF_RANGE:
  481. (void) fprintf(stderr, "%s: %s\n", cmdName,
  482. gettext("invalid size"));
  483. ret++;
  484. break;
  485. case STMF_ERROR_META_CREATION:
  486. (void) fprintf(stderr, "%s: %s\n", cmdName,
  487. gettext("could not create meta file"));
  488. ret++;
  489. break;
  490. default:
  491. (void) fprintf(stderr, "%s: %s: %s: %d\n", cmdName,
  492. gettext("could not set property"), propString,
  493. stmfRet);
  494. ret++;
  495. break;
  496. }
  497. return (ret);
  498. }
  499. /*ARGSUSED*/
  500. int
  501. list_lus(int argc, char *argv[], cmdOptions_t *options, void *callData)
  502. {
  503. int stmfRet;
  504. stmfGuidList *luList;
  505. stmfLogicalUnitProperties luProps;
  506. int sbdLuCnt = 0;
  507. int i;
  508. if ((stmfRet = stmfGetLogicalUnitList(&luList))
  509. != STMF_STATUS_SUCCESS) {
  510. switch (stmfRet) {
  511. case STMF_ERROR_SERVICE_NOT_FOUND:
  512. (void) fprintf(stderr, "%s: %s\n", cmdName,
  513. gettext("STMF service not found"));
  514. break;
  515. case STMF_ERROR_BUSY:
  516. (void) fprintf(stderr, "%s: %s\n", cmdName,
  517. gettext("resource busy"));
  518. break;
  519. case STMF_ERROR_PERM:
  520. (void) fprintf(stderr, "%s: %s\n", cmdName,
  521. gettext("permission denied"));
  522. break;
  523. case STMF_ERROR_SERVICE_DATA_VERSION:
  524. (void) fprintf(stderr, "%s: %s\n", cmdName,
  525. gettext("STMF service version incorrect"));
  526. break;
  527. default:
  528. (void) fprintf(stderr, "%s: %s\n", cmdName,
  529. gettext("list failed"));
  530. break;
  531. }
  532. return (1);
  533. }
  534. for (i = 0; i < luList->cnt; i++) {
  535. stmfRet = stmfGetLogicalUnitProperties(&luList->guid[i],
  536. &luProps);
  537. if (stmfRet != STMF_STATUS_SUCCESS) {
  538. (void) fprintf(stderr, "%s: %s\n", cmdName,
  539. gettext("list failed"));
  540. return (1);
  541. }
  542. if (strcmp(luProps.providerName, "sbd") == 0) {
  543. sbdLuCnt++;
  544. }
  545. }
  546. if (sbdLuCnt == 0)
  547. return (0);
  548. (void) printf("\nFound %d LU(s)\n", sbdLuCnt);
  549. print_attr_header();
  550. for (i = 0; i < luList->cnt; i++) {
  551. stmfRet = stmfGetLogicalUnitProperties(&luList->guid[i],
  552. &luProps);
  553. if (stmfRet != STMF_STATUS_SUCCESS) {
  554. (void) fprintf(stderr, "%s: %s\n", cmdName,
  555. gettext("list failed"));
  556. return (1);
  557. }
  558. if (strcmp(luProps.providerName, "sbd") == 0) {
  559. (void) print_lu_attr(&luList->guid[i]);
  560. }
  561. }
  562. return (0);
  563. }
  564. void
  565. print_attr_header()
  566. {
  567. (void) printf("\n");
  568. (void) printf(" GUID DATA SIZE "
  569. " SOURCE\n");
  570. (void) printf("-------------------------------- -------------------"
  571. " ----------------\n");
  572. }
  573. void
  574. print_guid(uint8_t *g, FILE *f)
  575. {
  576. int i;
  577. for (i = 0; i < 16; i++) {
  578. (void) fprintf(f, "%02x", g[i]);
  579. }
  580. }
  581. int
  582. print_lu_attr(stmfGuid *guid)
  583. {
  584. luResource hdl = NULL;
  585. int stmfRet = 0;
  586. int ret = 0;
  587. char propVal[MAXPATHLEN];
  588. size_t propValSize = sizeof (propVal);
  589. if ((stmfRet = stmfGetLuResource(guid, &hdl)) != STMF_STATUS_SUCCESS) {
  590. switch (stmfRet) {
  591. case STMF_ERROR_BUSY:
  592. (void) fprintf(stderr, "%s: %s\n", cmdName,
  593. gettext("resource busy"));
  594. break;
  595. case STMF_ERROR_PERM:
  596. (void) fprintf(stderr, "%s: %s\n", cmdName,
  597. gettext("permission denied"));
  598. break;
  599. case STMF_ERROR_NOT_FOUND:
  600. /* No error here */
  601. return (0);
  602. default:
  603. (void) fprintf(stderr, "%s: %s\n", cmdName,
  604. gettext("get extended properties failed"));
  605. break;
  606. }
  607. return (1);
  608. }
  609. print_guid((uint8_t *)guid, stdout);
  610. stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_SIZE, propVal,
  611. &propValSize);
  612. if (stmfRet == STMF_STATUS_SUCCESS) {
  613. (void) printf(" %-19s ", propVal);
  614. } else if (stmfRet == STMF_ERROR_NO_PROP) {
  615. (void) printf("not set\n");
  616. } else {
  617. (void) printf("<error retrieving property>\n");
  618. ret++;
  619. }
  620. stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_FILENAME, propVal,
  621. &propValSize);
  622. if (stmfRet == STMF_STATUS_SUCCESS) {
  623. (void) printf("%s\n", propVal);
  624. } else if (stmfRet == STMF_ERROR_NO_PROP) {
  625. (void) printf("not set\n");
  626. } else {
  627. (void) printf("<error retrieving property>\n");
  628. ret++;
  629. }
  630. (void) stmfFreeLuResource(hdl);
  631. return (ret);
  632. }
  633. /*
  634. * input:
  635. * execFullName - exec name of program (argv[0])
  636. *
  637. * copied from usr/src/cmd/zoneadm/zoneadm.c in OS/Net
  638. * (changed name to lowerCamelCase to keep consistent with this file)
  639. *
  640. * Returns:
  641. * command name portion of execFullName
  642. */
  643. static char *
  644. getExecBasename(char *execFullname)
  645. {
  646. char *lastSlash, *execBasename;
  647. /* guard against '/' at end of command invocation */
  648. for (;;) {
  649. lastSlash = strrchr(execFullname, '/');
  650. if (lastSlash == NULL) {
  651. execBasename = execFullname;
  652. break;
  653. } else {
  654. execBasename = lastSlash + 1;
  655. if (*execBasename == '\0') {
  656. *lastSlash = '\0';
  657. continue;
  658. }
  659. break;
  660. }
  661. }
  662. return (execBasename);
  663. }
  664. int
  665. main(int argc, char *argv[])
  666. {
  667. synTables_t synTables;
  668. char versionString[VERSION_STRING_MAX_LEN];
  669. int ret;
  670. int funcRet;
  671. void *subcommandArgs = NULL;
  672. (void) setlocale(LC_ALL, "");
  673. (void) textdomain(TEXT_DOMAIN);
  674. /* set global command name */
  675. cmdName = getExecBasename(argv[0]);
  676. (void) snprintf(versionString, VERSION_STRING_MAX_LEN, "%s.%s",
  677. VERSION_STRING_MAJOR, VERSION_STRING_MINOR);
  678. synTables.versionString = versionString;
  679. synTables.longOptionTbl = options;
  680. synTables.subCommandPropsTbl = subCommands;
  681. ret = cmdParse(argc, argv, synTables, subcommandArgs, &funcRet);
  682. if (ret != 0) {
  683. return (ret);
  684. }
  685. return (funcRet);
  686. } /* end main */