xref: /titanic_54/usr/src/cmd/sbdadm/sbdadm.c (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte  * CDDL HEADER START
3*fcf3ce44SJohn Forte  *
4*fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte  *
8*fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte  * and limitations under the License.
12*fcf3ce44SJohn Forte  *
13*fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte  *
19*fcf3ce44SJohn Forte  * CDDL HEADER END
20*fcf3ce44SJohn Forte  */
21*fcf3ce44SJohn Forte /*
22*fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*fcf3ce44SJohn Forte  * Use is subject to license terms.
24*fcf3ce44SJohn Forte  */
25*fcf3ce44SJohn Forte #include <stdlib.h>
26*fcf3ce44SJohn Forte #include <stdio.h>
27*fcf3ce44SJohn Forte #include <sys/types.h>
28*fcf3ce44SJohn Forte #include <sys/stat.h>
29*fcf3ce44SJohn Forte #include <fcntl.h>
30*fcf3ce44SJohn Forte #include <unistd.h>
31*fcf3ce44SJohn Forte #include <libintl.h>
32*fcf3ce44SJohn Forte #include <errno.h>
33*fcf3ce44SJohn Forte #include <string.h>
34*fcf3ce44SJohn Forte #include <assert.h>
35*fcf3ce44SJohn Forte #include <getopt.h>
36*fcf3ce44SJohn Forte #include <strings.h>
37*fcf3ce44SJohn Forte #include <ctype.h>
38*fcf3ce44SJohn Forte #include <libnvpair.h>
39*fcf3ce44SJohn Forte 
40*fcf3ce44SJohn Forte #include <cmdparse.h>
41*fcf3ce44SJohn Forte #include <sys/stmf_defines.h>
42*fcf3ce44SJohn Forte #include <libstmf.h>
43*fcf3ce44SJohn Forte #include <sys/stmf_sbd_ioctl.h>
44*fcf3ce44SJohn Forte 
45*fcf3ce44SJohn Forte #define	BIG_BUF_SIZE	512
46*fcf3ce44SJohn Forte #define	MAX_LU_LIST	8192
47*fcf3ce44SJohn Forte #define	LU_LIST_MAX_RETRIES 3
48*fcf3ce44SJohn Forte 
49*fcf3ce44SJohn Forte uint8_t big_buf[BIG_BUF_SIZE];
50*fcf3ce44SJohn Forte 
51*fcf3ce44SJohn Forte int delete_lu(int argc, char *argv[], cmdOptions_t *options,
52*fcf3ce44SJohn Forte     void *callData);
53*fcf3ce44SJohn Forte int create_lu(int argc, char *argv[], cmdOptions_t *options, void *callData);
54*fcf3ce44SJohn Forte int import_lu(int argc, char *argv[], cmdOptions_t *options, void *callData);
55*fcf3ce44SJohn Forte int list_lus(int argc, char *argv[], cmdOptions_t *options, void *callData);
56*fcf3ce44SJohn Forte int modify_lu(int argc, char *argv[], cmdOptions_t *options, void *callData);
57*fcf3ce44SJohn Forte static int persist_lu_register(char *, char *);
58*fcf3ce44SJohn Forte int print_lu_attr(uint64_t handle, char **s);
59*fcf3ce44SJohn Forte void print_guid(uint8_t *g, FILE *f);
60*fcf3ce44SJohn Forte void print_attr_header();
61*fcf3ce44SJohn Forte 
62*fcf3ce44SJohn Forte char	*rlc_ret[] = {	"", "Metadata creation failed",
63*fcf3ce44SJohn Forte 	"LU is not initialized",
64*fcf3ce44SJohn Forte 	"File is already loaded",
65*fcf3ce44SJohn Forte 	"GUID in the file is already registered",
66*fcf3ce44SJohn Forte 	"Registration with framework failed",
67*fcf3ce44SJohn Forte 	"Deregistration with stmf failed",
68*fcf3ce44SJohn Forte 	"Unable to lookup file",
69*fcf3ce44SJohn Forte 	"Incorrect file type to export as LU. Only regular \n"
70*fcf3ce44SJohn Forte 	    "files and raw storage devices (disks/volumes) can be exported "
71*fcf3ce44SJohn Forte 	    "as LUs",
72*fcf3ce44SJohn Forte 	"Unable to open file",
73*fcf3ce44SJohn Forte 	"Unable to get file attributes",
74*fcf3ce44SJohn Forte 	"File size has to be at least 1M",
75*fcf3ce44SJohn Forte 	"File size is not a multiple of blocksize",
76*fcf3ce44SJohn Forte 	"LU size is out of range",
77*fcf3ce44SJohn Forte 	"LU size is not supported by underlying Filesystem"
78*fcf3ce44SJohn Forte };
79*fcf3ce44SJohn Forte 
80*fcf3ce44SJohn Forte char sbdadm_ver[] = "sbdadm version 1.0";
81*fcf3ce44SJohn Forte 
82*fcf3ce44SJohn Forte optionTbl_t options[] = {
83*fcf3ce44SJohn Forte 	{ "disk-size", required_argument, 's',
84*fcf3ce44SJohn Forte 			"Size with <none>/k/m/g/t/p/e modifier" },
85*fcf3ce44SJohn Forte 	{ "keep-views", no_arg, 'k',
86*fcf3ce44SJohn Forte 			"Dont delete view entries related to the LU" },
87*fcf3ce44SJohn Forte 	{ NULL, 0, 0 }
88*fcf3ce44SJohn Forte };
89*fcf3ce44SJohn Forte 
90*fcf3ce44SJohn Forte subCommandProps_t subCommands[] = {
91*fcf3ce44SJohn Forte 	{ "create-lu", create_lu, "s", NULL, NULL,
92*fcf3ce44SJohn Forte 		OPERAND_MANDATORY_SINGLE,
93*fcf3ce44SJohn Forte 		"Full path of the file to initialize" },
94*fcf3ce44SJohn Forte 	{ "delete-lu", delete_lu, "k", NULL, NULL,
95*fcf3ce44SJohn Forte 		OPERAND_MANDATORY_SINGLE, "GUID of the LU to deregister" },
96*fcf3ce44SJohn Forte 	{ "import-lu", import_lu, NULL, NULL, NULL,
97*fcf3ce44SJohn Forte 		OPERAND_MANDATORY_SINGLE, "filename of the LU to import" },
98*fcf3ce44SJohn Forte 	{ "list-lu", list_lus, NULL, NULL, NULL,
99*fcf3ce44SJohn Forte 		OPERAND_NONE, "List all the exported LUs" },
100*fcf3ce44SJohn Forte 	{ "modify-lu", modify_lu, "s", "s", NULL,
101*fcf3ce44SJohn Forte 		OPERAND_MANDATORY_SINGLE,
102*fcf3ce44SJohn Forte 		"Full path of the LU or GUID of a registered LU" },
103*fcf3ce44SJohn Forte 	{ NULL, 0, 0, NULL, 0, NULL}
104*fcf3ce44SJohn Forte };
105*fcf3ce44SJohn Forte 
106*fcf3ce44SJohn Forte int sbd_fd;
107*fcf3ce44SJohn Forte 
108*fcf3ce44SJohn Forte int
109*fcf3ce44SJohn Forte main(int argc, char *argv[])
110*fcf3ce44SJohn Forte {
111*fcf3ce44SJohn Forte 	int ret, func_ret;
112*fcf3ce44SJohn Forte 	synTables_t sbdt = { sbdadm_ver, options, subCommands };
113*fcf3ce44SJohn Forte 
114*fcf3ce44SJohn Forte 	sbd_fd = open("/devices/pseudo/stmf_sbd@0:admin", O_RDONLY);
115*fcf3ce44SJohn Forte 	if (sbd_fd < 0) {
116*fcf3ce44SJohn Forte 		if (errno == EPERM) {
117*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "Not enough permissions to open "
118*fcf3ce44SJohn Forte 			    "device\n");
119*fcf3ce44SJohn Forte 		} else {
120*fcf3ce44SJohn Forte 			(void) fprintf(stderr,
121*fcf3ce44SJohn Forte 			    "Unable to open device. Is the driver "
122*fcf3ce44SJohn Forte 			    "attached ?\n");
123*fcf3ce44SJohn Forte 		}
124*fcf3ce44SJohn Forte 		exit(1);
125*fcf3ce44SJohn Forte 	}
126*fcf3ce44SJohn Forte 	ret = cmdParse(argc, argv, sbdt, NULL, &func_ret);
127*fcf3ce44SJohn Forte 
128*fcf3ce44SJohn Forte 	if (ret)
129*fcf3ce44SJohn Forte 		return (ret);
130*fcf3ce44SJohn Forte 	return (func_ret);
131*fcf3ce44SJohn Forte }
132*fcf3ce44SJohn Forte 
133*fcf3ce44SJohn Forte /*
134*fcf3ce44SJohn Forte  * Supports upto 8 Exabytes.
135*fcf3ce44SJohn Forte  *
136*fcf3ce44SJohn Forte  * Returns zero upon success and the size in sizep.
137*fcf3ce44SJohn Forte  * returns 2 if the string format is invalid.
138*fcf3ce44SJohn Forte  * returns 1 if the specified size is out of range.
139*fcf3ce44SJohn Forte  */
140*fcf3ce44SJohn Forte int
141*fcf3ce44SJohn Forte str_to_size(char *str, uint64_t *sizep)
142*fcf3ce44SJohn Forte {
143*fcf3ce44SJohn Forte 	uint64_t cur_size, m;
144*fcf3ce44SJohn Forte 	uint64_t new_cur_size;
145*fcf3ce44SJohn Forte 	int i;
146*fcf3ce44SJohn Forte 	char c;
147*fcf3ce44SJohn Forte 
148*fcf3ce44SJohn Forte 	m = 1;
149*fcf3ce44SJohn Forte 	cur_size = 0;
150*fcf3ce44SJohn Forte 
151*fcf3ce44SJohn Forte 	for (i = 0; str[i] != NULL; i++) {
152*fcf3ce44SJohn Forte 		if (m != 1) {
153*fcf3ce44SJohn Forte 			/* We should have been done after the modifier */
154*fcf3ce44SJohn Forte 			return (2);
155*fcf3ce44SJohn Forte 		}
156*fcf3ce44SJohn Forte 		c = str[i];
157*fcf3ce44SJohn Forte 		if (isdigit(c)) {
158*fcf3ce44SJohn Forte 			new_cur_size = (cur_size * 10) +
159*fcf3ce44SJohn Forte 			    (((uint64_t)c) - '0');
160*fcf3ce44SJohn Forte 			if (new_cur_size < cur_size) {
161*fcf3ce44SJohn Forte 				/* Overflow */
162*fcf3ce44SJohn Forte 				return (1);
163*fcf3ce44SJohn Forte 			}
164*fcf3ce44SJohn Forte 			cur_size = new_cur_size;
165*fcf3ce44SJohn Forte 			continue;
166*fcf3ce44SJohn Forte 		}
167*fcf3ce44SJohn Forte 		if (cur_size == 0) {
168*fcf3ce44SJohn Forte 			/* Direct format modifier ?? */
169*fcf3ce44SJohn Forte 			return (2);
170*fcf3ce44SJohn Forte 		}
171*fcf3ce44SJohn Forte 		c = toupper(c);
172*fcf3ce44SJohn Forte 		if (c == 'K') {
173*fcf3ce44SJohn Forte 			m = 1024;
174*fcf3ce44SJohn Forte 		} else if (c == 'M') {
175*fcf3ce44SJohn Forte 			m = 1024 * 1024;
176*fcf3ce44SJohn Forte 		} else if (c == 'G') {
177*fcf3ce44SJohn Forte 			m = 1024 * 1024 * 1024;
178*fcf3ce44SJohn Forte 		} else if (c == 'T') {
179*fcf3ce44SJohn Forte 			m = 1024ll * 1024 * 1024 * 1024;
180*fcf3ce44SJohn Forte 		} else if (c == 'P') {
181*fcf3ce44SJohn Forte 			m = 1024ll * 1024 * 1024 * 1024 * 1024;
182*fcf3ce44SJohn Forte 		} else if (c == 'E') {
183*fcf3ce44SJohn Forte 			m = 1024ll * 1024 * 1024 * 1024 * 1024 * 1024;
184*fcf3ce44SJohn Forte 		} else {
185*fcf3ce44SJohn Forte 			return (2);
186*fcf3ce44SJohn Forte 		}
187*fcf3ce44SJohn Forte 	}
188*fcf3ce44SJohn Forte 
189*fcf3ce44SJohn Forte 	while (m > 1) {
190*fcf3ce44SJohn Forte 		if (cur_size & 0x8000000000000000ull) {
191*fcf3ce44SJohn Forte 			/* Overflow */
192*fcf3ce44SJohn Forte 			return (1);
193*fcf3ce44SJohn Forte 		}
194*fcf3ce44SJohn Forte 		cur_size <<= 1;
195*fcf3ce44SJohn Forte 		m >>= 1;
196*fcf3ce44SJohn Forte 	}
197*fcf3ce44SJohn Forte 
198*fcf3ce44SJohn Forte 	if (cur_size > 0x8000000000000000ull) {
199*fcf3ce44SJohn Forte 		/* We cannot allow more than 8 Exabytes */
200*fcf3ce44SJohn Forte 		return (1);
201*fcf3ce44SJohn Forte 	}
202*fcf3ce44SJohn Forte 
203*fcf3ce44SJohn Forte 	*sizep = cur_size;
204*fcf3ce44SJohn Forte 
205*fcf3ce44SJohn Forte 	return (0);
206*fcf3ce44SJohn Forte }
207*fcf3ce44SJohn Forte 
208*fcf3ce44SJohn Forte static int
209*fcf3ce44SJohn Forte persist_lu_register(char *guid, char *filename)
210*fcf3ce44SJohn Forte {
211*fcf3ce44SJohn Forte 	int ret = 0;
212*fcf3ce44SJohn Forte 	nvlist_t *nvl = NULL;
213*fcf3ce44SJohn Forte 	uint64_t setToken;
214*fcf3ce44SJohn Forte 	boolean_t		retryGetProviderData;
215*fcf3ce44SJohn Forte 
216*fcf3ce44SJohn Forte 	do {
217*fcf3ce44SJohn Forte 		retryGetProviderData = B_FALSE;
218*fcf3ce44SJohn Forte 		ret = stmfGetProviderDataProt("sbd", &nvl,
219*fcf3ce44SJohn Forte 		    STMF_LU_PROVIDER_TYPE, &setToken);
220*fcf3ce44SJohn Forte 		if (ret != STMF_STATUS_SUCCESS) {
221*fcf3ce44SJohn Forte 			if (ret == STMF_ERROR_NOT_FOUND) {
222*fcf3ce44SJohn Forte 				(void) nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);
223*fcf3ce44SJohn Forte 			} else {
224*fcf3ce44SJohn Forte 				(void) fprintf(stderr,
225*fcf3ce44SJohn Forte 				    "could not access persistent store\n");
226*fcf3ce44SJohn Forte 				ret = 1;
227*fcf3ce44SJohn Forte 				goto out;
228*fcf3ce44SJohn Forte 			}
229*fcf3ce44SJohn Forte 		}
230*fcf3ce44SJohn Forte 
231*fcf3ce44SJohn Forte 		ret = nvlist_add_string(nvl, guid, filename);
232*fcf3ce44SJohn Forte 		if (ret != 0) {
233*fcf3ce44SJohn Forte 			(void) fprintf(stderr,
234*fcf3ce44SJohn Forte 			    "could not add data to nvlist\n");
235*fcf3ce44SJohn Forte 			ret = 1;
236*fcf3ce44SJohn Forte 			goto out;
237*fcf3ce44SJohn Forte 		}
238*fcf3ce44SJohn Forte 
239*fcf3ce44SJohn Forte 		ret = stmfSetProviderDataProt("sbd", nvl, STMF_LU_PROVIDER_TYPE,
240*fcf3ce44SJohn Forte 		    &setToken);
241*fcf3ce44SJohn Forte 		if (ret != STMF_STATUS_SUCCESS) {
242*fcf3ce44SJohn Forte 			if (ret == STMF_ERROR_BUSY) {
243*fcf3ce44SJohn Forte 				(void) fprintf(stderr,
244*fcf3ce44SJohn Forte 				    "stmf framework resource busy\n");
245*fcf3ce44SJohn Forte 			} else if (ret == STMF_ERROR_PROV_DATA_STALE) {
246*fcf3ce44SJohn Forte 				nvlist_free(nvl);
247*fcf3ce44SJohn Forte 				nvl = NULL;
248*fcf3ce44SJohn Forte 				retryGetProviderData = B_TRUE;
249*fcf3ce44SJohn Forte 				continue;
250*fcf3ce44SJohn Forte 			} else {
251*fcf3ce44SJohn Forte 				(void) fprintf(stderr,
252*fcf3ce44SJohn Forte 				    "unable to set persistent store data\n");
253*fcf3ce44SJohn Forte 			}
254*fcf3ce44SJohn Forte 			ret = 1;
255*fcf3ce44SJohn Forte 			goto out;
256*fcf3ce44SJohn Forte 		}
257*fcf3ce44SJohn Forte 	} while (retryGetProviderData);
258*fcf3ce44SJohn Forte out:
259*fcf3ce44SJohn Forte 	nvlist_free(nvl);
260*fcf3ce44SJohn Forte 	return (ret);
261*fcf3ce44SJohn Forte }
262*fcf3ce44SJohn Forte 
263*fcf3ce44SJohn Forte /*ARGSUSED*/
264*fcf3ce44SJohn Forte int
265*fcf3ce44SJohn Forte create_lu(int argc, char *argv[], cmdOptions_t *options, void *callData)
266*fcf3ce44SJohn Forte {
267*fcf3ce44SJohn Forte 	register_lu_cmd_t *rlc;
268*fcf3ce44SJohn Forte 	uint32_t fl;
269*fcf3ce44SJohn Forte 	int ret = 0, err;
270*fcf3ce44SJohn Forte 	uint64_t size;
271*fcf3ce44SJohn Forte 	char guidAsciiBuf[33];
272*fcf3ce44SJohn Forte 
273*fcf3ce44SJohn Forte 	/* Check whether this file path is absolute path */
274*fcf3ce44SJohn Forte 	if (argv[argc - 1][0] != '/') {
275*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "File name should be an absolute path"
276*fcf3ce44SJohn Forte 		    " i.e. it should start with a /\n");
277*fcf3ce44SJohn Forte 		return (1);
278*fcf3ce44SJohn Forte 	}
279*fcf3ce44SJohn Forte 
280*fcf3ce44SJohn Forte 	fl = strlen(argv[argc - 1]) + 1;
281*fcf3ce44SJohn Forte 	rlc = (register_lu_cmd_t *)malloc(sizeof (register_lu_cmd_t) + fl - 8);
282*fcf3ce44SJohn Forte 	if (rlc == NULL) {
283*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "Unable to allocate memory\n");
284*fcf3ce44SJohn Forte 		return (1);
285*fcf3ce44SJohn Forte 	}
286*fcf3ce44SJohn Forte 	bzero(rlc, sizeof (register_lu_cmd_t));
287*fcf3ce44SJohn Forte 	rlc->total_struct_size = sizeof (register_lu_cmd_t) + fl - 8;
288*fcf3ce44SJohn Forte 
289*fcf3ce44SJohn Forte 	rlc->flags = RLC_LU_TYPE_FILEDISK | RLC_CREATE_LU | RLC_REGISTER_LU;
290*fcf3ce44SJohn Forte 	for (; options->optval; options++) {
291*fcf3ce44SJohn Forte 		if (options->optval == 's') {
292*fcf3ce44SJohn Forte 			err = str_to_size(options->optarg, &size);
293*fcf3ce44SJohn Forte 			if (err == 1) {
294*fcf3ce44SJohn Forte 				(void) fprintf(stderr,
295*fcf3ce44SJohn Forte 				    "Size out of range: maximum"
296*fcf3ce44SJohn Forte 				    " supported size is 9223372036854710272"
297*fcf3ce44SJohn Forte 				    " (8 Exabytes - 64 Kilobytes)\n");
298*fcf3ce44SJohn Forte 				ret = 1;
299*fcf3ce44SJohn Forte 				goto create_lu_done;
300*fcf3ce44SJohn Forte 			} else if (err == 2) {
301*fcf3ce44SJohn Forte 				(void) fprintf(stderr,
302*fcf3ce44SJohn Forte 				    "Invalid size specified\n");
303*fcf3ce44SJohn Forte 				ret = 1;
304*fcf3ce44SJohn Forte 				goto create_lu_done;
305*fcf3ce44SJohn Forte 			}
306*fcf3ce44SJohn Forte 			rlc->lu_size = size;
307*fcf3ce44SJohn Forte 		}
308*fcf3ce44SJohn Forte 	}
309*fcf3ce44SJohn Forte 	(void) strcpy(rlc->name, argv[argc-1]);
310*fcf3ce44SJohn Forte 	if ((ioctl(sbd_fd, SBD_REGISTER_LU, rlc) < 0) ||
311*fcf3ce44SJohn Forte 	    (rlc->return_code != 0) || (rlc->op_ret != STMF_SUCCESS)) {
312*fcf3ce44SJohn Forte 		if (rlc->return_code && (rlc->return_code < RLC_RET_MAX_VAL)) {
313*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "LU Create failed : %s.\n",
314*fcf3ce44SJohn Forte 			    rlc_ret[rlc->return_code]);
315*fcf3ce44SJohn Forte 			if (rlc->return_code ==
316*fcf3ce44SJohn Forte 			    RLC_RET_SIZE_NOT_SUPPORTED_BY_FS) {
317*fcf3ce44SJohn Forte 				(void) fprintf(stderr, "Maximum LU size on "
318*fcf3ce44SJohn Forte 				    "the underlying filesystem can be %llu "
319*fcf3ce44SJohn Forte 				    "bytes.\n",
320*fcf3ce44SJohn Forte 				    ((((uint64_t)1) << rlc->filesize_nbits)
321*fcf3ce44SJohn Forte 				    - 1 - 64 * 1024) & 0xfffffffffffffe00ull);
322*fcf3ce44SJohn Forte 			}
323*fcf3ce44SJohn Forte 			if (rlc->return_code ==
324*fcf3ce44SJohn Forte 			    RLC_RET_GUID_ALREADY_REGISTERED) {
325*fcf3ce44SJohn Forte 				(void) fprintf(stderr, "Registered GUID is ");
326*fcf3ce44SJohn Forte 				print_guid(rlc->guid, stderr);
327*fcf3ce44SJohn Forte 				(void) fprintf(stderr, "\n");
328*fcf3ce44SJohn Forte 			}
329*fcf3ce44SJohn Forte 		} else {
330*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "LU Create failed(%llx) : %s.\n",
331*fcf3ce44SJohn Forte 			    rlc->op_ret, strerror(errno));
332*fcf3ce44SJohn Forte 		}
333*fcf3ce44SJohn Forte 		ret = 1;
334*fcf3ce44SJohn Forte 	} else {
335*fcf3ce44SJohn Forte 		if (rlc->flags & RLC_REGISTER_LU) {
336*fcf3ce44SJohn Forte 			(void) printf("\nCreated the following LU:\n");
337*fcf3ce44SJohn Forte 			print_attr_header();
338*fcf3ce44SJohn Forte 			(void) print_lu_attr(rlc->lu_handle, NULL);
339*fcf3ce44SJohn Forte 			(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
340*fcf3ce44SJohn Forte 			    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
341*fcf3ce44SJohn Forte 			    "%02x%02x%02x%02x%02x%02x",
342*fcf3ce44SJohn Forte 			    rlc->guid[0], rlc->guid[1], rlc->guid[2],
343*fcf3ce44SJohn Forte 			    rlc->guid[3], rlc->guid[4], rlc->guid[5],
344*fcf3ce44SJohn Forte 			    rlc->guid[6], rlc->guid[7], rlc->guid[8],
345*fcf3ce44SJohn Forte 			    rlc->guid[9], rlc->guid[10], rlc->guid[11],
346*fcf3ce44SJohn Forte 			    rlc->guid[12], rlc->guid[13], rlc->guid[14],
347*fcf3ce44SJohn Forte 			    rlc->guid[15]);
348*fcf3ce44SJohn Forte 
349*fcf3ce44SJohn Forte 			ret = persist_lu_register(guidAsciiBuf, argv[argc - 1]);
350*fcf3ce44SJohn Forte 		}
351*fcf3ce44SJohn Forte 	}
352*fcf3ce44SJohn Forte 
353*fcf3ce44SJohn Forte create_lu_done:;
354*fcf3ce44SJohn Forte 	free(rlc);
355*fcf3ce44SJohn Forte 	return (ret);
356*fcf3ce44SJohn Forte }
357*fcf3ce44SJohn Forte 
358*fcf3ce44SJohn Forte /*ARGSUSED*/
359*fcf3ce44SJohn Forte int
360*fcf3ce44SJohn Forte import_lu(int argc, char *argv[], cmdOptions_t *options, void *callData)
361*fcf3ce44SJohn Forte {
362*fcf3ce44SJohn Forte 	register_lu_cmd_t *rlc;
363*fcf3ce44SJohn Forte 	uint32_t fl;
364*fcf3ce44SJohn Forte 	int ret = 0;
365*fcf3ce44SJohn Forte 	char guidAsciiBuf[33];
366*fcf3ce44SJohn Forte 
367*fcf3ce44SJohn Forte 	/* Check whether this file path is absolute path */
368*fcf3ce44SJohn Forte 	if (argv[argc - 1][0] != '/') {
369*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "File name should be an absolute path"
370*fcf3ce44SJohn Forte 		    " i.e. it should start with a /\n");
371*fcf3ce44SJohn Forte 		return (1);
372*fcf3ce44SJohn Forte 	}
373*fcf3ce44SJohn Forte 
374*fcf3ce44SJohn Forte 	fl = strlen(argv[argc - 1]) + 1;
375*fcf3ce44SJohn Forte 	rlc = (register_lu_cmd_t *)malloc(sizeof (register_lu_cmd_t) + fl - 8);
376*fcf3ce44SJohn Forte 	if (rlc == NULL) {
377*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "Unable to allocate memory\n");
378*fcf3ce44SJohn Forte 		return (1);
379*fcf3ce44SJohn Forte 	}
380*fcf3ce44SJohn Forte 	bzero(rlc, sizeof (register_lu_cmd_t));
381*fcf3ce44SJohn Forte 	rlc->total_struct_size = sizeof (register_lu_cmd_t) + fl - 8;
382*fcf3ce44SJohn Forte 
383*fcf3ce44SJohn Forte 	rlc->flags = RLC_LU_TYPE_FILEDISK | RLC_REGISTER_LU;
384*fcf3ce44SJohn Forte 	(void) strcpy(rlc->name, argv[argc-1]);
385*fcf3ce44SJohn Forte 	if ((ioctl(sbd_fd, SBD_REGISTER_LU, rlc) < 0) ||
386*fcf3ce44SJohn Forte 	    (rlc->return_code != 0) || (rlc->op_ret != STMF_SUCCESS)) {
387*fcf3ce44SJohn Forte 		if (rlc->return_code && (rlc->return_code < RLC_RET_MAX_VAL)) {
388*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "LU import failed : %s.\n",
389*fcf3ce44SJohn Forte 			    rlc_ret[rlc->return_code]);
390*fcf3ce44SJohn Forte 			if (rlc->return_code ==
391*fcf3ce44SJohn Forte 			    RLC_RET_SIZE_NOT_SUPPORTED_BY_FS) {
392*fcf3ce44SJohn Forte 				(void) fprintf(stderr, "Maximum LU size on "
393*fcf3ce44SJohn Forte 				    "the underlying filesystem can be %llu "
394*fcf3ce44SJohn Forte 				    "bytes.\n",
395*fcf3ce44SJohn Forte 				    ((((uint64_t)1) << rlc->filesize_nbits)
396*fcf3ce44SJohn Forte 				    - 1 - 64 * 1024) & 0xfffffffffffffe00ull);
397*fcf3ce44SJohn Forte 			}
398*fcf3ce44SJohn Forte 			if (rlc->return_code ==
399*fcf3ce44SJohn Forte 			    RLC_RET_GUID_ALREADY_REGISTERED) {
400*fcf3ce44SJohn Forte 				(void) fprintf(stderr, "Registered GUID is ");
401*fcf3ce44SJohn Forte 				print_guid(rlc->guid, stderr);
402*fcf3ce44SJohn Forte 				(void) fprintf(stderr, "\n");
403*fcf3ce44SJohn Forte 			}
404*fcf3ce44SJohn Forte 		} else {
405*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "LU import failed(%llx) : %s.\n",
406*fcf3ce44SJohn Forte 			    rlc->op_ret, strerror(errno));
407*fcf3ce44SJohn Forte 		}
408*fcf3ce44SJohn Forte 		ret = 1;
409*fcf3ce44SJohn Forte 	} else {
410*fcf3ce44SJohn Forte 		if (rlc->flags & RLC_REGISTER_LU) {
411*fcf3ce44SJohn Forte 			(void) printf("\nImported the following LU:\n");
412*fcf3ce44SJohn Forte 			print_attr_header();
413*fcf3ce44SJohn Forte 			(void) print_lu_attr(rlc->lu_handle, NULL);
414*fcf3ce44SJohn Forte 			(void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
415*fcf3ce44SJohn Forte 			    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
416*fcf3ce44SJohn Forte 			    "%02x%02x%02x%02x%02x%02x",
417*fcf3ce44SJohn Forte 			    rlc->guid[0], rlc->guid[1], rlc->guid[2],
418*fcf3ce44SJohn Forte 			    rlc->guid[3], rlc->guid[4], rlc->guid[5],
419*fcf3ce44SJohn Forte 			    rlc->guid[6], rlc->guid[7], rlc->guid[8],
420*fcf3ce44SJohn Forte 			    rlc->guid[9], rlc->guid[10], rlc->guid[11],
421*fcf3ce44SJohn Forte 			    rlc->guid[12], rlc->guid[13], rlc->guid[14],
422*fcf3ce44SJohn Forte 			    rlc->guid[15]);
423*fcf3ce44SJohn Forte 
424*fcf3ce44SJohn Forte 			ret = persist_lu_register(guidAsciiBuf, argv[argc - 1]);
425*fcf3ce44SJohn Forte 		}
426*fcf3ce44SJohn Forte 	}
427*fcf3ce44SJohn Forte 
428*fcf3ce44SJohn Forte import_lu_done:;
429*fcf3ce44SJohn Forte 	free(rlc);
430*fcf3ce44SJohn Forte 	return (ret);
431*fcf3ce44SJohn Forte }
432*fcf3ce44SJohn Forte 
433*fcf3ce44SJohn Forte /*ARGSUSED*/
434*fcf3ce44SJohn Forte int
435*fcf3ce44SJohn Forte delete_lu(int argc, char *argv[], cmdOptions_t *options, void *callData)
436*fcf3ce44SJohn Forte {
437*fcf3ce44SJohn Forte 	deregister_lu_cmd_t	drlc;
438*fcf3ce44SJohn Forte 	int			ret = 0, i;
439*fcf3ce44SJohn Forte 	char			chstr[3], *pend = NULL;
440*fcf3ce44SJohn Forte 	uint32_t		ch, off = 0;
441*fcf3ce44SJohn Forte 	int			exists = 0;
442*fcf3ce44SJohn Forte 	char			guidAsciiBuf[33];
443*fcf3ce44SJohn Forte 	nvlist_t		*nvl = NULL;
444*fcf3ce44SJohn Forte 
445*fcf3ce44SJohn Forte 	int			stmf_ret;
446*fcf3ce44SJohn Forte 	int			keep_view = 0;
447*fcf3ce44SJohn Forte 	uint64_t		setToken;
448*fcf3ce44SJohn Forte 	stmfGuid		inGuid;
449*fcf3ce44SJohn Forte 	stmfViewEntryList	*viewEntryList;
450*fcf3ce44SJohn Forte 	boolean_t		retryGetProviderData;
451*fcf3ce44SJohn Forte 
452*fcf3ce44SJohn Forte 	for (; options->optval; options++) {
453*fcf3ce44SJohn Forte 		switch (options->optval) {
454*fcf3ce44SJohn Forte 		case 'k':
455*fcf3ce44SJohn Forte 			keep_view = 1;
456*fcf3ce44SJohn Forte 			break;
457*fcf3ce44SJohn Forte 		}
458*fcf3ce44SJohn Forte 	}
459*fcf3ce44SJohn Forte 
460*fcf3ce44SJohn Forte 	if (strlen(argv[argc - 1]) != 32) {
461*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "GUID must be 32 characters\n");
462*fcf3ce44SJohn Forte 		ret = 1;
463*fcf3ce44SJohn Forte 		goto delete_lu_done;
464*fcf3ce44SJohn Forte 	}
465*fcf3ce44SJohn Forte 
466*fcf3ce44SJohn Forte 	for (i = 0; i < 32; i++) {
467*fcf3ce44SJohn Forte 		guidAsciiBuf[i] = tolower(argv[argc - 1][i]);
468*fcf3ce44SJohn Forte 	}
469*fcf3ce44SJohn Forte 
470*fcf3ce44SJohn Forte 	guidAsciiBuf[i] = 0;
471*fcf3ce44SJohn Forte 
472*fcf3ce44SJohn Forte 	do {
473*fcf3ce44SJohn Forte 		retryGetProviderData = B_FALSE;
474*fcf3ce44SJohn Forte 		stmf_ret = stmfGetProviderDataProt("sbd", &nvl,
475*fcf3ce44SJohn Forte 		    STMF_LU_PROVIDER_TYPE, &setToken);
476*fcf3ce44SJohn Forte 		if (stmf_ret != STMF_STATUS_SUCCESS) {
477*fcf3ce44SJohn Forte 			(void) fprintf(stderr,
478*fcf3ce44SJohn Forte 			    "Could not access persistent store\n");
479*fcf3ce44SJohn Forte 			ret = 1;
480*fcf3ce44SJohn Forte 			goto delete_lu_done;
481*fcf3ce44SJohn Forte 		}
482*fcf3ce44SJohn Forte 		ret = nvlist_remove(nvl, guidAsciiBuf, DATA_TYPE_STRING);
483*fcf3ce44SJohn Forte 		if (ret == 0) {
484*fcf3ce44SJohn Forte 			exists = 1;
485*fcf3ce44SJohn Forte 			stmf_ret = stmfSetProviderDataProt("sbd", nvl,
486*fcf3ce44SJohn Forte 			    STMF_LU_PROVIDER_TYPE, &setToken);
487*fcf3ce44SJohn Forte 			if (stmf_ret != STMF_STATUS_SUCCESS) {
488*fcf3ce44SJohn Forte 				if (stmf_ret == STMF_ERROR_BUSY) {
489*fcf3ce44SJohn Forte 					(void) fprintf(stderr,
490*fcf3ce44SJohn Forte 					    "stmf framework resource busy\n");
491*fcf3ce44SJohn Forte 				} else if (stmf_ret ==
492*fcf3ce44SJohn Forte 				    STMF_ERROR_PROV_DATA_STALE) {
493*fcf3ce44SJohn Forte 					/*
494*fcf3ce44SJohn Forte 					 * update failed, try again
495*fcf3ce44SJohn Forte 					 */
496*fcf3ce44SJohn Forte 					nvlist_free(nvl);
497*fcf3ce44SJohn Forte 					nvl = NULL;
498*fcf3ce44SJohn Forte 					retryGetProviderData = B_TRUE;
499*fcf3ce44SJohn Forte 					continue;
500*fcf3ce44SJohn Forte 				} else {
501*fcf3ce44SJohn Forte 					(void) fprintf(stderr,
502*fcf3ce44SJohn Forte 					    "unable to set persistent store "
503*fcf3ce44SJohn Forte 					    "data\n");
504*fcf3ce44SJohn Forte 				}
505*fcf3ce44SJohn Forte 				ret = 1;
506*fcf3ce44SJohn Forte 				goto delete_lu_done;
507*fcf3ce44SJohn Forte 			}
508*fcf3ce44SJohn Forte 		}
509*fcf3ce44SJohn Forte 	} while (retryGetProviderData);
510*fcf3ce44SJohn Forte 
511*fcf3ce44SJohn Forte 	bzero(&drlc, sizeof (drlc));
512*fcf3ce44SJohn Forte 	drlc.total_struct_size = sizeof (drlc);
513*fcf3ce44SJohn Forte 	drlc.flags = RLC_DEREGISTER_LU;
514*fcf3ce44SJohn Forte 
515*fcf3ce44SJohn Forte 	chstr[2] = 0;
516*fcf3ce44SJohn Forte 	i = 0;
517*fcf3ce44SJohn Forte 	while ((off + 2) <= strlen(argv[argc - 1])) {
518*fcf3ce44SJohn Forte 		bcopy(argv[argc -1] + off, chstr, 2);
519*fcf3ce44SJohn Forte 		off += 2;
520*fcf3ce44SJohn Forte 
521*fcf3ce44SJohn Forte 		if (!isxdigit(chstr[0]) || !isxdigit(chstr[1])) {
522*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "Invalid LU GUID specified.\n");
523*fcf3ce44SJohn Forte 			ret = 1;
524*fcf3ce44SJohn Forte 			goto delete_lu_done;
525*fcf3ce44SJohn Forte 		}
526*fcf3ce44SJohn Forte 		errno = 0;
527*fcf3ce44SJohn Forte 		ch = strtoul(chstr, &pend, 16);
528*fcf3ce44SJohn Forte 		if (errno != 0) {
529*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "Invalid LU GUID specified.\n");
530*fcf3ce44SJohn Forte 			ret = 1;
531*fcf3ce44SJohn Forte 			goto delete_lu_done;
532*fcf3ce44SJohn Forte 		}
533*fcf3ce44SJohn Forte 		drlc.guid[i++] = ch;
534*fcf3ce44SJohn Forte 
535*fcf3ce44SJohn Forte 	}
536*fcf3ce44SJohn Forte 
537*fcf3ce44SJohn Forte 	if (ioctl(sbd_fd, SBD_DEREGISTER_LU, &drlc) < 0) {
538*fcf3ce44SJohn Forte 		if (errno != ENODEV) {
539*fcf3ce44SJohn Forte 			(void) fprintf(stderr,
540*fcf3ce44SJohn Forte 			    "Request to delete LU failed: %s\n",
541*fcf3ce44SJohn Forte 			    strerror(errno));
542*fcf3ce44SJohn Forte 			ret = 1;
543*fcf3ce44SJohn Forte 			goto delete_lu_done;
544*fcf3ce44SJohn Forte 		}
545*fcf3ce44SJohn Forte 	} else if (drlc.return_code != 0) {
546*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "LU deregister failed: ret_code-%x",
547*fcf3ce44SJohn Forte 		    drlc.return_code);
548*fcf3ce44SJohn Forte 		ret = 1;
549*fcf3ce44SJohn Forte 		goto delete_lu_done;
550*fcf3ce44SJohn Forte 	} else {
551*fcf3ce44SJohn Forte 		exists = 1;
552*fcf3ce44SJohn Forte 	}
553*fcf3ce44SJohn Forte 
554*fcf3ce44SJohn Forte 	if (!keep_view) {
555*fcf3ce44SJohn Forte 		for (i = 0; i < 16; i++)
556*fcf3ce44SJohn Forte 			inGuid.guid[i] = drlc.guid[i];
557*fcf3ce44SJohn Forte 
558*fcf3ce44SJohn Forte 		if ((stmf_ret = stmfGetViewEntryList(&inGuid,
559*fcf3ce44SJohn Forte 		    &viewEntryList)) == STMF_STATUS_SUCCESS) {
560*fcf3ce44SJohn Forte 			for (i = 0; i < viewEntryList->cnt; i++) {
561*fcf3ce44SJohn Forte 				(void) stmfRemoveViewEntry(&inGuid,
562*fcf3ce44SJohn Forte 				    viewEntryList->ve[i].veIndex);
563*fcf3ce44SJohn Forte 			}
564*fcf3ce44SJohn Forte 		} else if (stmf_ret != STMF_ERROR_NOT_FOUND) {
565*fcf3ce44SJohn Forte 			(void) fprintf(stderr,
566*fcf3ce44SJohn Forte 			    "unable to remove view entries\n");
567*fcf3ce44SJohn Forte 			ret = 1;
568*fcf3ce44SJohn Forte 		}
569*fcf3ce44SJohn Forte 	}
570*fcf3ce44SJohn Forte 
571*fcf3ce44SJohn Forte 	if (!exists) {
572*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "GUID not found.\n");
573*fcf3ce44SJohn Forte 		ret = 1;
574*fcf3ce44SJohn Forte 		goto delete_lu_done;
575*fcf3ce44SJohn Forte 	}
576*fcf3ce44SJohn Forte 
577*fcf3ce44SJohn Forte delete_lu_done:;
578*fcf3ce44SJohn Forte 	return (ret);
579*fcf3ce44SJohn Forte }
580*fcf3ce44SJohn Forte 
581*fcf3ce44SJohn Forte /*ARGSUSED*/
582*fcf3ce44SJohn Forte int
583*fcf3ce44SJohn Forte modify_lu(int argc, char *argv[], cmdOptions_t *options, void *callData)
584*fcf3ce44SJohn Forte {
585*fcf3ce44SJohn Forte 	modify_lu_cmd_t *mlc;
586*fcf3ce44SJohn Forte 	uint32_t fl = 0, struct_size;
587*fcf3ce44SJohn Forte 	int ret = 0, err;
588*fcf3ce44SJohn Forte 	int i = 0;
589*fcf3ce44SJohn Forte 	uint64_t size;
590*fcf3ce44SJohn Forte 	int is_filename = 0;
591*fcf3ce44SJohn Forte 	char chstr[3], *pend = NULL;
592*fcf3ce44SJohn Forte 	uint32_t ch;
593*fcf3ce44SJohn Forte 	uint32_t off = 0;
594*fcf3ce44SJohn Forte 
595*fcf3ce44SJohn Forte 	if (argv[argc - 1][0] == '/') {
596*fcf3ce44SJohn Forte 		is_filename = 1;
597*fcf3ce44SJohn Forte 		fl = strlen(argv[argc - 1]) + 1;
598*fcf3ce44SJohn Forte 		struct_size = sizeof (modify_lu_cmd_t) + fl - 8;
599*fcf3ce44SJohn Forte 	} else {
600*fcf3ce44SJohn Forte 		struct_size = sizeof (modify_lu_cmd_t);
601*fcf3ce44SJohn Forte 	}
602*fcf3ce44SJohn Forte 	mlc = (modify_lu_cmd_t *)malloc(struct_size);
603*fcf3ce44SJohn Forte 	if (mlc == NULL) {
604*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "Unable to allocate memory\n");
605*fcf3ce44SJohn Forte 		return (1);
606*fcf3ce44SJohn Forte 	}
607*fcf3ce44SJohn Forte 	bzero(mlc, sizeof (modify_lu_cmd_t));
608*fcf3ce44SJohn Forte 	mlc->total_struct_size = struct_size;
609*fcf3ce44SJohn Forte 
610*fcf3ce44SJohn Forte 	mlc->flags = RLC_LU_TYPE_FILEDISK | RLC_CREATE_LU;
611*fcf3ce44SJohn Forte 	for (; options->optval; options++) {
612*fcf3ce44SJohn Forte 		if (options->optval == 's') {
613*fcf3ce44SJohn Forte 			err = str_to_size(options->optarg, &size);
614*fcf3ce44SJohn Forte 			if (err == 1) {
615*fcf3ce44SJohn Forte 				(void) fprintf(stderr,
616*fcf3ce44SJohn Forte 				    "Size out of range: maximum"
617*fcf3ce44SJohn Forte 				    " supported size is 9223372036854775808"
618*fcf3ce44SJohn Forte 				    " (8 Exabytes)\n");
619*fcf3ce44SJohn Forte 				ret = 1;
620*fcf3ce44SJohn Forte 				goto modify_lu_done;
621*fcf3ce44SJohn Forte 			} else if (err == 2) {
622*fcf3ce44SJohn Forte 				(void) fprintf(stderr,
623*fcf3ce44SJohn Forte 				    "Invalid size specified\n");
624*fcf3ce44SJohn Forte 				ret = 1;
625*fcf3ce44SJohn Forte 				goto modify_lu_done;
626*fcf3ce44SJohn Forte 			}
627*fcf3ce44SJohn Forte 			mlc->lu_size = size;
628*fcf3ce44SJohn Forte 		}
629*fcf3ce44SJohn Forte 	}
630*fcf3ce44SJohn Forte 	if (is_filename) {
631*fcf3ce44SJohn Forte 		(void) strcpy(mlc->name, argv[argc-1]);
632*fcf3ce44SJohn Forte 		(void) memset(mlc->guid, 0, 16);
633*fcf3ce44SJohn Forte 	} else {
634*fcf3ce44SJohn Forte 		if (strlen(argv[argc - 1]) != 32) {
635*fcf3ce44SJohn Forte 			(void) fprintf(stderr,
636*fcf3ce44SJohn Forte 			    "Invalid device identifier or filename"
637*fcf3ce44SJohn Forte 			    " specified.\nIf it is a filename, it should be an"
638*fcf3ce44SJohn Forte 			    " absolute path i.e. it should start with a /\n");
639*fcf3ce44SJohn Forte 			goto modify_lu_done;
640*fcf3ce44SJohn Forte 		}
641*fcf3ce44SJohn Forte 		chstr[2] = 0;
642*fcf3ce44SJohn Forte 		i = 0;
643*fcf3ce44SJohn Forte 		while ((off + 2) <= strlen(argv[argc - 1])) {
644*fcf3ce44SJohn Forte 			bcopy(argv[argc -1] + off, chstr, 2);
645*fcf3ce44SJohn Forte 			off += 2;
646*fcf3ce44SJohn Forte 
647*fcf3ce44SJohn Forte 			ch = strtoul(chstr, &pend, 16);
648*fcf3ce44SJohn Forte 			if (errno != 0) {
649*fcf3ce44SJohn Forte 				(void) fprintf(stderr,
650*fcf3ce44SJohn Forte 				    "Invalid device identifier or"
651*fcf3ce44SJohn Forte 				    " filename specified.\nIf it is a"
652*fcf3ce44SJohn Forte 				    " filename, it should be an absolute path"
653*fcf3ce44SJohn Forte 				    " i.e. it should start with a /\n");
654*fcf3ce44SJohn Forte 				ret = 1;
655*fcf3ce44SJohn Forte 				goto modify_lu_done;
656*fcf3ce44SJohn Forte 			}
657*fcf3ce44SJohn Forte 			mlc->guid[i++] = ch;
658*fcf3ce44SJohn Forte 
659*fcf3ce44SJohn Forte 		}
660*fcf3ce44SJohn Forte 		mlc->name[0] = '\0';
661*fcf3ce44SJohn Forte 	}
662*fcf3ce44SJohn Forte 	if ((ioctl(sbd_fd, SBD_MODIFY_LU, mlc) < 0) ||
663*fcf3ce44SJohn Forte 	    (mlc->return_code != 0) || (mlc->op_ret |= STMF_SUCCESS)) {
664*fcf3ce44SJohn Forte 		if (mlc->return_code && (mlc->return_code < RLC_RET_MAX_VAL)) {
665*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "LU modify failed : %s.\n",
666*fcf3ce44SJohn Forte 			    rlc_ret[mlc->return_code]);
667*fcf3ce44SJohn Forte 			if (mlc->return_code ==
668*fcf3ce44SJohn Forte 			    RLC_RET_SIZE_NOT_SUPPORTED_BY_FS) {
669*fcf3ce44SJohn Forte 				(void) fprintf(stderr, "Maximum LU size on "
670*fcf3ce44SJohn Forte 				    "the underlying filesystem can be %llu "
671*fcf3ce44SJohn Forte 				    "bytes.\n",
672*fcf3ce44SJohn Forte 				    ((((uint64_t)1) << mlc->filesize_nbits)
673*fcf3ce44SJohn Forte 				    - 1) & 0xfffffffffffffe00ull);
674*fcf3ce44SJohn Forte 			} else if (mlc->return_code ==
675*fcf3ce44SJohn Forte 			    RLC_RET_LU_NOT_INITIALIZED) {
676*fcf3ce44SJohn Forte 				(void) fprintf(stderr, "Use 'sbdadm lu-create' "
677*fcf3ce44SJohn Forte 				    "to initialize the LU.\n");
678*fcf3ce44SJohn Forte 			}
679*fcf3ce44SJohn Forte 		} else {
680*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "LU modify failed(%llx) : %s.\n",
681*fcf3ce44SJohn Forte 			    mlc->op_ret, strerror(errno));
682*fcf3ce44SJohn Forte 		}
683*fcf3ce44SJohn Forte 		ret = 1;
684*fcf3ce44SJohn Forte 	} else {
685*fcf3ce44SJohn Forte 		(void) printf("LU modified Successfully.\n");
686*fcf3ce44SJohn Forte 	}
687*fcf3ce44SJohn Forte 
688*fcf3ce44SJohn Forte modify_lu_done:;
689*fcf3ce44SJohn Forte 	free(mlc);
690*fcf3ce44SJohn Forte 	return (ret);
691*fcf3ce44SJohn Forte }
692*fcf3ce44SJohn Forte 
693*fcf3ce44SJohn Forte 
694*fcf3ce44SJohn Forte /*ARGSUSED*/
695*fcf3ce44SJohn Forte int
696*fcf3ce44SJohn Forte list_lus(int argc, char *argv[], cmdOptions_t *options, void *callData)
697*fcf3ce44SJohn Forte {
698*fcf3ce44SJohn Forte 	sbd_lu_list_t *sll;
699*fcf3ce44SJohn Forte 	uint32_t i;
700*fcf3ce44SJohn Forte 	ssize_t list_size;
701*fcf3ce44SJohn Forte 	int retry_count = 0;
702*fcf3ce44SJohn Forte 	uint32_t lu_count_in = MAX_LU_LIST;
703*fcf3ce44SJohn Forte 	int ret;
704*fcf3ce44SJohn Forte 	nvlist_t *nvl = NULL;
705*fcf3ce44SJohn Forte 	nvpair_t *np;
706*fcf3ce44SJohn Forte 	char *s;
707*fcf3ce44SJohn Forte 
708*fcf3ce44SJohn Forte 	ret = stmfGetProviderDataProt("sbd", &nvl, STMF_LU_PROVIDER_TYPE,
709*fcf3ce44SJohn Forte 	    NULL);
710*fcf3ce44SJohn Forte 	if (ret != STMF_STATUS_SUCCESS) {
711*fcf3ce44SJohn Forte 		if (ret == STMF_ERROR_NOT_FOUND) {
712*fcf3ce44SJohn Forte 			(void) nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);
713*fcf3ce44SJohn Forte 		} else {
714*fcf3ce44SJohn Forte 			(void) fprintf(stderr,
715*fcf3ce44SJohn Forte 			    "Could not access persistent store\n");
716*fcf3ce44SJohn Forte 			return (1);
717*fcf3ce44SJohn Forte 		}
718*fcf3ce44SJohn Forte 	}
719*fcf3ce44SJohn Forte 
720*fcf3ce44SJohn Forte retry_get_lu_list:
721*fcf3ce44SJohn Forte 	list_size = (lu_count_in * 8) + sizeof (sbd_lu_list_t) - 8;
722*fcf3ce44SJohn Forte 	sll = (sbd_lu_list_t *)calloc(1, list_size);
723*fcf3ce44SJohn Forte 	if (sll == NULL) {
724*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "Memory allocation failure\n");
725*fcf3ce44SJohn Forte 		nvlist_free(nvl);
726*fcf3ce44SJohn Forte 		return (1);
727*fcf3ce44SJohn Forte 	}
728*fcf3ce44SJohn Forte 
729*fcf3ce44SJohn Forte 	sll->total_struct_size = list_size;
730*fcf3ce44SJohn Forte 
731*fcf3ce44SJohn Forte 	sll->count_in = lu_count_in;
732*fcf3ce44SJohn Forte 	if (ioctl(sbd_fd, SBD_GET_LU_LIST, sll) < 0) {
733*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "Unable to get LU list : %s\n",
734*fcf3ce44SJohn Forte 		    strerror(errno));
735*fcf3ce44SJohn Forte 		free(sll);
736*fcf3ce44SJohn Forte 		nvlist_free(nvl);
737*fcf3ce44SJohn Forte 		return (1);
738*fcf3ce44SJohn Forte 	}
739*fcf3ce44SJohn Forte 	if (sll->count_out > sll->count_in) {
740*fcf3ce44SJohn Forte 		lu_count_in = sll->count_out;
741*fcf3ce44SJohn Forte 		free(sll);
742*fcf3ce44SJohn Forte 		if (retry_count < LU_LIST_MAX_RETRIES) {
743*fcf3ce44SJohn Forte 			retry_count++;
744*fcf3ce44SJohn Forte 			goto retry_get_lu_list;
745*fcf3ce44SJohn Forte 		} else {
746*fcf3ce44SJohn Forte 			(void) fprintf(stderr, "Unable to get LU list after %d"
747*fcf3ce44SJohn Forte 			    " retries\n", retry_count);
748*fcf3ce44SJohn Forte 			nvlist_free(nvl);
749*fcf3ce44SJohn Forte 			return (1);
750*fcf3ce44SJohn Forte 		}
751*fcf3ce44SJohn Forte 	}
752*fcf3ce44SJohn Forte 
753*fcf3ce44SJohn Forte 	(void) printf("\nFound %d LU(s)\n", sll->count_out);
754*fcf3ce44SJohn Forte 	if (sll->count_out == 0)
755*fcf3ce44SJohn Forte 		goto over_print_attr;
756*fcf3ce44SJohn Forte 
757*fcf3ce44SJohn Forte 	print_attr_header();
758*fcf3ce44SJohn Forte 	for (i = 0; i < sll->count_out; i++) {
759*fcf3ce44SJohn Forte 		if (!print_lu_attr(sll->handles[i], &s))
760*fcf3ce44SJohn Forte 			continue;
761*fcf3ce44SJohn Forte 		if (nvlist_remove(nvl, s, DATA_TYPE_STRING) != 0) {
762*fcf3ce44SJohn Forte 			(void) fprintf(stderr,
763*fcf3ce44SJohn Forte 			    "Error: GUID %s does not exist in "
764*fcf3ce44SJohn Forte 			    "persistent store\n", s);
765*fcf3ce44SJohn Forte 		}
766*fcf3ce44SJohn Forte 	}
767*fcf3ce44SJohn Forte over_print_attr:
768*fcf3ce44SJohn Forte 	free(sll);
769*fcf3ce44SJohn Forte 	np = NULL;
770*fcf3ce44SJohn Forte 	while ((np = nvlist_next_nvpair(nvl, np)) != NULL) {
771*fcf3ce44SJohn Forte 		if (nvpair_type(np) != DATA_TYPE_STRING)
772*fcf3ce44SJohn Forte 			continue;
773*fcf3ce44SJohn Forte 		if (nvpair_value_string(np, &s) != 0)
774*fcf3ce44SJohn Forte 			continue;
775*fcf3ce44SJohn Forte 
776*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "%s   <Failed to load>    %s\n",
777*fcf3ce44SJohn Forte 		    nvpair_name(np), s);
778*fcf3ce44SJohn Forte 	}
779*fcf3ce44SJohn Forte 	nvlist_free(nvl);
780*fcf3ce44SJohn Forte 	return (0);
781*fcf3ce44SJohn Forte }
782*fcf3ce44SJohn Forte 
783*fcf3ce44SJohn Forte void
784*fcf3ce44SJohn Forte print_attr_header()
785*fcf3ce44SJohn Forte {
786*fcf3ce44SJohn Forte 	(void) printf("\n");
787*fcf3ce44SJohn Forte 	(void) printf("	      GUID                    DATA SIZE      "
788*fcf3ce44SJohn Forte 	    "     SOURCE\n");
789*fcf3ce44SJohn Forte 	(void) printf("--------------------------------  -------------------"
790*fcf3ce44SJohn Forte 	    "  ----------------\n");
791*fcf3ce44SJohn Forte }
792*fcf3ce44SJohn Forte 
793*fcf3ce44SJohn Forte void
794*fcf3ce44SJohn Forte print_guid(uint8_t *g, FILE *f)
795*fcf3ce44SJohn Forte {
796*fcf3ce44SJohn Forte 	int i;
797*fcf3ce44SJohn Forte 
798*fcf3ce44SJohn Forte 	for (i = 0; i < 16; i++) {
799*fcf3ce44SJohn Forte 		(void) fprintf(f, "%02x", g[i]);
800*fcf3ce44SJohn Forte 	}
801*fcf3ce44SJohn Forte }
802*fcf3ce44SJohn Forte 
803*fcf3ce44SJohn Forte int
804*fcf3ce44SJohn Forte print_lu_attr(uint64_t handle, char **s)
805*fcf3ce44SJohn Forte {
806*fcf3ce44SJohn Forte 	sbd_lu_attr_t *sla;
807*fcf3ce44SJohn Forte 
808*fcf3ce44SJohn Forte 	sla = (sbd_lu_attr_t *)big_buf;
809*fcf3ce44SJohn Forte 
810*fcf3ce44SJohn Forte 	bzero(sla, BIG_BUF_SIZE);
811*fcf3ce44SJohn Forte 
812*fcf3ce44SJohn Forte 	sla->lu_handle = handle;
813*fcf3ce44SJohn Forte 	sla->total_struct_size = BIG_BUF_SIZE;
814*fcf3ce44SJohn Forte 	sla->max_name_length = BIG_BUF_SIZE - sizeof (*sla) + 7;
815*fcf3ce44SJohn Forte 
816*fcf3ce44SJohn Forte 	if (ioctl(sbd_fd, SBD_GET_LU_ATTR, sla) < 0) {
817*fcf3ce44SJohn Forte 		(void) fprintf(stderr, "Request to get LU attr failed: %s\n",
818*fcf3ce44SJohn Forte 		    strerror(errno));
819*fcf3ce44SJohn Forte 		return (0);
820*fcf3ce44SJohn Forte 	}
821*fcf3ce44SJohn Forte 
822*fcf3ce44SJohn Forte 	print_guid(sla->guid, stdout);
823*fcf3ce44SJohn Forte 
824*fcf3ce44SJohn Forte 	if (sla->data_size > 9999999999999ull)
825*fcf3ce44SJohn Forte 		(void) printf("  %-19llu  ", sla->data_size);
826*fcf3ce44SJohn Forte 	else
827*fcf3ce44SJohn Forte 		(void) printf("      %-13llu    ", sla->data_size);
828*fcf3ce44SJohn Forte 
829*fcf3ce44SJohn Forte 	if (sla->flags & RLC_LU_TYPE_MEMDISK) {
830*fcf3ce44SJohn Forte 		(void) printf("<RAM : %llu bytes>\n", sla->total_size);
831*fcf3ce44SJohn Forte 	} else {
832*fcf3ce44SJohn Forte 		(void) printf("%s\n", sla->name);
833*fcf3ce44SJohn Forte 	}
834*fcf3ce44SJohn Forte 	if (s != NULL) {
835*fcf3ce44SJohn Forte 		(void) snprintf((char *)big_buf, sizeof (big_buf),
836*fcf3ce44SJohn Forte 		    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
837*fcf3ce44SJohn Forte 		    "%02x%02x%02x%02x%02x%02x",
838*fcf3ce44SJohn Forte 		    sla->guid[0], sla->guid[1], sla->guid[2],
839*fcf3ce44SJohn Forte 		    sla->guid[3], sla->guid[4], sla->guid[5],
840*fcf3ce44SJohn Forte 		    sla->guid[6], sla->guid[7], sla->guid[8],
841*fcf3ce44SJohn Forte 		    sla->guid[9], sla->guid[10], sla->guid[11],
842*fcf3ce44SJohn Forte 		    sla->guid[12], sla->guid[13], sla->guid[14],
843*fcf3ce44SJohn Forte 		    sla->guid[15]);
844*fcf3ce44SJohn Forte 		*s = (char *)big_buf;
845*fcf3ce44SJohn Forte 	}
846*fcf3ce44SJohn Forte 	return (1);
847*fcf3ce44SJohn Forte }
848