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 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* This file is getting large unexpectly, a lex & yacc */
28 /* implementation is expected. */
29
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
39 #include <fcntl.h>
40 #include <unistd.h>
41 #include <pthread.h>
42
43 #include "isns_server.h"
44 #include "isns_htab.h"
45 #include "isns_msgq.h"
46 #include "isns_obj.h"
47 #include "isns_func.h"
48 #include "isns_dd.h"
49 #include "isns_cache.h"
50 #include "isns_pdu.h"
51
52 #ifdef DEBUG
53 /*
54 * external variables
55 */
56 extern const int NUM_OF_CHILD[MAX_OBJ_TYPE];
57 extern const int TYPE_OF_CHILD[MAX_OBJ_TYPE][MAX_CHILD_TYPE];
58 extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
59 extern const int NUM_OF_REF[MAX_OBJ_TYPE_FOR_SIZE];
60
61 extern lookup_ctrl_t *setup_ddid_lcp(lookup_ctrl_t *, uint32_t);
62 extern lookup_ctrl_t *setup_ddsid_lcp(lookup_ctrl_t *, uint32_t);
63
64 /*
65 * global variables
66 */
67 int verbose_mc = 0;
68 int verbose_tc = 0;
69 int verbose_lock = 0;
70 int verbose_net = 0;
71 int verbose_parser = 0;
72
73 /*
74 * local variables
75 */
76 static void print_entity(char *, isns_obj_t *);
77 static void print_iscsi(char *, isns_obj_t *);
78 static void print_portal(char *, isns_obj_t *);
79 static void print_pg(char *, isns_obj_t *);
80 static void print_dd(char *, isns_obj_t *);
81 static void print_dds(char *, isns_obj_t *);
82 static void (*const print_func[MAX_OBJ_TYPE])(char *, isns_obj_t *) = {
83 NULL,
84 &print_entity,
85 &print_iscsi,
86 &print_portal,
87 &print_pg,
88 &print_dd,
89 &print_dds
90 };
91 static int run_cmd(char *);
92
93 typedef struct {
94 uint16_t func_id;
95 char *fname;
96 } isnsp_fnames_t;
97 isnsp_fnames_t fnames[] = {
98 { ISNS_DEV_ATTR_REG, "DevAttrReg" },
99 { ISNS_DEV_ATTR_QRY, "DevAttrQry" },
100 { ISNS_DEV_GET_NEXT, "DevGetNext" },
101 { ISNS_DEV_DEREG, "DevDereg" },
102 { ISNS_SCN_REG, "SCNReg" },
103 { ISNS_SCN_DEREG, "SCNDereg" },
104 { ISNS_DD_REG, "DDReg" },
105 { ISNS_DD_DEREG, "DDDereg" },
106 { ISNS_DDS_REG, "DDSReg" },
107 { ISNS_DDS_DEREG, "DDSDereg" },
108 { ISNS_SCN, "SCN" },
109 { ISNS_ESI, "ESI" },
110 { ISNS_HEARTBEAT, "Heartbeat" },
111 { ISNS_DEV_ATTR_REG_RSP, "DevAttrRegRsp" },
112 { ISNS_DEV_ATTR_QRY_RSP, "DevAttrQryRsp" },
113 { ISNS_DEV_GET_NEXT_RSP, "DevGetNextRsp" },
114 { ISNS_DEV_DEREG_RSP, "DevDeregRsp" },
115 { ISNS_SCN_REG_RSP, "SCNRegRsp" },
116 { ISNS_SCN_DEREG_RSP, "SCNDeregRsp" },
117 { ISNS_SCN_RSP, "SCNRsp" },
118 { ISNS_ESI_RSP, "ESIRsp" },
119 { 0xFFFF, "Unknown" } };
120
121 static char *
get_func_name(uint16_t id)122 get_func_name(
123 uint16_t id
124 )
125 {
126 int i = 0;
127 isnsp_fnames_t *fp = &fnames[i ++];
128 while (fp->func_id != 0xFFFF) {
129 if (fp->func_id == id) {
130 return (fp->fname);
131 }
132 fp = &fnames[i ++];
133 }
134
135 return ("UNKNOWN");
136 }
137
138 static char *
get_tlv_tag_name(uint32_t tag)139 get_tlv_tag_name(
140 uint32_t tag
141 )
142 {
143 switch (tag) {
144 case ISNS_DELIMITER_ATTR_ID:
145 return ("Delimiter");
146 case ISNS_EID_ATTR_ID:
147 return ("Entity Identifier");
148 case ISNS_ENTITY_PROTOCOL_ATTR_ID:
149 return ("Entity Protocol");
150 case ISNS_ENTITY_REG_PERIOD_ATTR_ID:
151 return ("Registration Period");
152 case ISNS_TIMESTAMP_ATTR_ID:
153 return ("Timestamp");
154 case ISNS_PORTAL_IP_ADDR_ATTR_ID:
155 return ("Portal IP Address");
156 case ISNS_PORTAL_PORT_ATTR_ID:
157 return ("Portal TCP/UDP Port");
158 case ISNS_PORTAL_NAME_ATTR_ID:
159 return ("Portal Symbolic Name");
160 case ISNS_ESI_INTERVAL_ATTR_ID:
161 return ("ESI Interval");
162 case ISNS_ESI_PORT_ATTR_ID:
163 return ("ESI Port");
164 case ISNS_SCN_PORT_ATTR_ID:
165 return ("SCN Port");
166 case ISNS_PORTAL_SEC_BMP_ATTR_ID:
167 return ("Portal Security Bitmap");
168 case ISNS_ISCSI_NAME_ATTR_ID:
169 return ("iSCSI Name");
170 case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
171 return ("iSCSI Node Type");
172 case ISNS_ISCSI_ALIAS_ATTR_ID:
173 return ("iSCSI Alias");
174 case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
175 return ("iSCSI Auth Method");
176 case ISNS_ISCSI_SCN_BITMAP_ATTR_ID:
177 return ("iSCSI SCN Bitmap");
178 case ISNS_PG_ISCSI_NAME_ATTR_ID:
179 return ("PG iSCSI Name");
180 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
181 return ("PG Portal IP Addr");
182 case ISNS_PG_PORTAL_PORT_ATTR_ID:
183 return ("PG Portal TCP/UDP Port");
184 case ISNS_PG_TAG_ATTR_ID:
185 return ("PG Tag (PGT)");
186 case ISNS_PG_INDEX_ATTR_ID:
187 return ("PG Index");
188 case ISNS_DD_NAME_ATTR_ID:
189 return ("DD Name");
190 case ISNS_DD_ID_ATTR_ID:
191 return ("DD Index");
192 case ISNS_DD_ISCSI_INDEX_ATTR_ID:
193 return ("DD ISCSI Node Index");
194 case ISNS_DD_ISCSI_NAME_ATTR_ID:
195 return ("DD ISCSI Node Name");
196 case ISNS_DD_SET_NAME_ATTR_ID:
197 return ("DDS Name");
198 case ISNS_DD_SET_ID_ATTR_ID:
199 return ("DDS Index");
200 case ISNS_DD_SET_STATUS_ATTR_ID:
201 return ("DDS Status");
202 default:
203 return ("Unknown");
204 }
205 }
206
207 static void
dump_pdu(isns_pdu_t * pdu,int flag)208 dump_pdu(
209 isns_pdu_t *pdu,
210 int flag
211 )
212 {
213 short ver, id, len, flags, xid, seq;
214
215 uint8_t *payload = pdu->payload;
216 isns_resp_t *resp;
217
218 /* convert the data */
219 if (flag) {
220 ver = ntohs(pdu->version);
221 id = ntohs(pdu->func_id);
222 len = ntohs(pdu->payload_len);
223 flags = ntohs(pdu->flags) & 0xFFFF;
224 xid = ntohs(pdu->xid);
225 seq = ntohs(pdu->seq);
226 } else {
227 ver = pdu->version;
228 id = pdu->func_id;
229 len = pdu->payload_len;
230 flags = pdu->flags & 0xFFFF;
231 xid = pdu->xid;
232 seq = pdu->seq;
233 }
234
235 /* print the pdu header */
236 printf("iSNSP Version: %d\n", ver);
237 printf("Function ID: %s\n", get_func_name(id));
238 printf("PDU Length: %d\n", len);
239 printf("Flags: %x\n", flags);
240 printf(" %d... .... .... .... : ISNS_FLAG_CLIENT\n",
241 ((flags & ISNS_FLAG_CLIENT) == 0) ? 0 : 1);
242 printf(" .%d.. .... .... .... : ISNS_FLAG_SERVER\n",
243 ((flags & ISNS_FLAG_SERVER) == 0) ? 0 : 1);
244 printf(" ..%d. .... .... .... : ISNS_FLAG_AUTH_BLK_PRESENTED\n",
245 ((flags & ISNS_FLAG_AUTH_BLK_PRESENTED) == 0) ? 0 : 1);
246 printf(" ...%d .... .... .... : ISNS_FLAG_REPLACE_REG\n",
247 ((flags & ISNS_FLAG_REPLACE_REG) == 0) ? 0 : 1);
248 printf(" .... %d... .... .... : ISNS_FLAG_LAST_PDU\n",
249 ((flags & ISNS_FLAG_LAST_PDU) == 0) ? 0 : 1);
250 printf(" .... .%d.. .... .... : ISNS_FLAG_FIRST_PDU\n",
251 ((flags & ISNS_FLAG_FIRST_PDU) == 0) ? 0 : 1);
252 printf("Transaction ID: %d\n", xid);
253 printf("Sequence ID: %d\n", seq);
254
255 printf("Payload: ...\n");
256 if (id & ISNS_RSP_MASK) {
257 resp = (isns_resp_t *)payload;
258 printf(" ErrorCode: %d\n", ntohl(resp->status));
259 len -= 4;
260 payload += 4;
261 }
262
263 /* print the payload */
264 while (len > 0) {
265 isns_tlv_t *tlvp;
266 int t, l;
267 uint8_t *v;
268 char *s;
269 int i;
270 in6_addr_t *ip;
271 char pbuff[256] = { 0 };
272
273 tlvp = (isns_tlv_t *)payload;
274
275 /* convert the data */
276 t = ntohl(tlvp->attr_id);
277 l = ntohl(tlvp->attr_len);
278 v = &(tlvp->attr_value[0]);
279
280 /* print payload */
281 if (l > 0) {
282 printf("%s: ", get_tlv_tag_name(t));
283 switch (t) {
284 case ISNS_EID_ATTR_ID:
285 case ISNS_ISCSI_NAME_ATTR_ID:
286 case ISNS_ISCSI_ALIAS_ATTR_ID:
287 case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
288 case ISNS_PG_ISCSI_NAME_ATTR_ID:
289 case ISNS_DD_NAME_ATTR_ID:
290 case ISNS_DD_SET_NAME_ATTR_ID:
291 s = (char *)v;
292 printf("%s\n", s);
293 break;
294 case ISNS_ENTITY_PROTOCOL_ATTR_ID:
295 i = ntohl(*(uint32_t *)v);
296 printf("%s (%d)\n",
297 ((i == 1) ? "No Protocol" :
298 ((i == 2) ? "iSCSI" :
299 ((i == 3) ? "iFCP" :
300 "Others"))),
301 i);
302 break;
303 case ISNS_PORTAL_IP_ADDR_ATTR_ID:
304 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
305 ip = (in6_addr_t *)v;
306 inet_ntop(AF_INET6, (void *)ip,
307 pbuff, sizeof (pbuff));
308 printf("%s\n", pbuff);
309 break;
310 case ISNS_PORTAL_PORT_ATTR_ID:
311 case ISNS_ESI_PORT_ATTR_ID:
312 case ISNS_SCN_PORT_ATTR_ID:
313 i = ntohl(*(uint32_t *)v);
314 printf("%d\n", (i & 0x0000FFFF));
315 printf(" .... .... %d... .... : "
316 "0=TCP\n",
317 ((i & 0x10000) == 0) ? 0 : 1);
318 break;
319 case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
320 i = ntohl(*(uint32_t *)v);
321 printf("0x%x\t", i);
322 if (i & ISNS_CONTROL_NODE_TYPE) {
323 printf("Control ");
324 }
325 if (i & ISNS_INITIATOR_NODE_TYPE) {
326 printf("Initiator ");
327 }
328 if (i & ISNS_TARGET_NODE_TYPE) {
329 printf("Target ");
330 }
331 printf("\n");
332 break;
333 case ISNS_PG_TAG_ATTR_ID:
334 default:
335 i = ntohl(*(uint32_t *)v);
336 printf("%d\n", i);
337 break;
338 }
339 printf(" Attribute Tag: %s (%d)\n",
340 get_tlv_tag_name(t), t);
341 printf(" Attribute Length: %d\n", l);
342 } else {
343 printf("%s: (%d)\n", get_tlv_tag_name(t), t);
344 }
345
346 len -= (sizeof (uint32_t) * 2 + l);
347 payload += (sizeof (uint32_t) * 2 + l);
348 }
349 }
350
351 void
dump_pdu1(isns_pdu_t * pdu)352 dump_pdu1(
353 isns_pdu_t *pdu
354 )
355 {
356 if (verbose_net) {
357 printf("### PDU RECEIVED ###\n");
358 dump_pdu(pdu, 0);
359 }
360 }
361
362 void
dump_pdu2(isns_pdu_t * pdu)363 dump_pdu2(
364 isns_pdu_t *pdu
365 )
366 {
367 if (verbose_net) {
368 printf("### PDU SENT ###\n");
369 dump_pdu(pdu, 1);
370 }
371 }
372
373 void
dump_db()374 dump_db(
375 )
376 {
377 #if 0
378 isns_list_t *list, *lista, *listb;
379 isns_dds_t *dds;
380 isns_dd_t *dd;
381 isns_iscsi2_t *iscsi2;
382
383 printf("### DUMP DATABASE ###\n");
384 /* dump dds(s) */
385 list = dds_list;
386 while (list != NULL) {
387 dds = list->obj.dds;
388 printf("[DDS:%d]%s(%s)\n", dds->id, dds->name,
389 dds->status ? "enabled" : "disabled");
390 lista = dds->dd_list;
391 /* dd(s) that belong to this dds */
392 while (lista != NULL) {
393 dd = lista->obj.dd;
394 printf("\t[DD:%d]%s\n", dd->id, dd->name);
395 lista = lista->next;
396 }
397 list = list->next;
398 }
399 /* dump dd(s) */
400 list = dd_list;
401 while (list != NULL) {
402 dd = list->obj.dd;
403 printf("[DD:%d]%s\n", dd->id, dd->name);
404 /* dds(s) this dd belongs to */
405 lista = dd->dds_list;
406 while (lista != NULL) {
407 dds = lista->obj.dds;
408 printf("\t[DDS:%d]%s\n", dds->id, dds->name);
409 lista = lista->next;
410 }
411 /* node(s) that this dd have */
412 listb = dd->iscsi_list;
413 while (listb != NULL) {
414 iscsi2 = listb->obj.iscsi2;
415 printf("\t[ISCSI:%d]%s\n", iscsi2->id, iscsi2->name);
416 listb = listb->next;
417 }
418 list = list->next;
419 }
420 /* dump node(s) */
421 list = iscsi_list;
422 while (list != NULL) {
423 iscsi2 = list->obj.iscsi2;
424 printf("[ISCSI:%d]%s\n", iscsi2->id, iscsi2->name);
425 lista = iscsi2->dd_list;
426 /* dd(s) that this node belongs to */
427 while (lista != NULL) {
428 dd = lista->obj.dd;
429 printf("\t[DD:%d]%s\n", dd->id, dd->name);
430 lista = lista->next;
431 }
432 list = list->next;
433 }
434 #endif
435 }
436
437 static void
test_cli_help()438 test_cli_help(
439 )
440 {
441 printf("list - list all of storage node.\n");
442 printf("list dd [id] - list all of dd or one with member.\n");
443 printf("list dds [id] - list all of dd-set or one with member.\n");
444
445 printf("\n");
446 printf("new dd <name> - create a dd with name.\n");
447 printf("new dds <name> - create a dd-set with name.\n");
448 printf("new ddn <id> <name> - create a dd with id and name.\n");
449 printf("new ddsn <id> <name> - create a dd-set with id and name.\n");
450 printf("del dd <id> - delete a dd.\n");
451 printf("del dds <id> - delete a dd-set.\n");
452
453 printf("\n");
454 printf("add dd <dd_id> <node_name> - add a node to dd.\n");
455 printf("add ddn <dd_id> <node_id> - add a node to dd.\n");
456 printf("add ddsn <dds_id> <dd_id> - add a dd to dd-set.\n");
457 printf("remove dd <dd_id> <node_name> - remove a node from dd.\n");
458 printf("remove ddn <dd_id> <node_id> - remove a node from dd.\n");
459 printf("remove ddsn <dds_id> <dd_id> - remove a dd from dd-set.\n");
460
461 printf("\n");
462 printf("enable <dds_id> - enable a dd-set.\n");
463 printf("disable <dds_id> - disable a dd-set.\n");
464
465 printf("\n");
466 printf("file <f> - loading command from a file.\n");
467 printf("pause - suspend batch until enter key is pressed.\n");
468
469 printf("help - print this help.\n");
470 printf("quit - stop iSNS server and quit.\n");
471 }
472
473 static enum {
474 CMD_LIST, CMD_LISTNE, CMD_LISTP, CMD_LISTPG,
475 CMD_LISTDD, CMD_LISTDDS, CMD_LISTDDN, CMD_LISTDDSN,
476 CMD_NEWDD, CMD_NEWDDS, CMD_NEWDDN, CMD_NEWDDSN,
477 CMD_DELDD, CMD_DELDDS,
478 CMD_ENABLE, CMD_DISABLE,
479 CMD_ADDDD, CMD_ADDDDN, CMD_ADDDDSN,
480 CMD_REMDD, CMD_REMDDN, CMD_REMDDSN,
481 CMD_VIEW,
482 CMD_FILE, CMD_PAUSE,
483 CMD_HELP,
484 CMD_VERBOSE_MEMORY, CMD_VERBOSE_NET,
485 CMD_VERBOSE_PARSER, CMD_VERBOSE_TIME,
486 CMD_VERBOSE_LOCK,
487 CMD_QUIT,
488 CMD_NONE, CMD_INVALID
489 };
490
491 static int
getcmd(int * argc,int * argv,char * cmd)492 getcmd(
493 int *argc, int *argv, char *cmd
494 )
495 {
496 int j = 0;
497 char tmp[256] = { 0 };
498 *argc = 0;
499 while (*cmd == ' ') cmd ++;
500
501 if (*cmd == 0) {
502 return (CMD_NONE);
503 } else if (*cmd == '?') {
504 return (CMD_HELP);
505 }
506
507 /* list, list dd, list dds, list dd 0 */
508 if (strncmp(cmd, "list ", 5) == 0) {
509 cmd += 5;
510 while (*cmd == ' ') cmd ++;
511 if (*cmd == 0) {
512 return (CMD_LIST);
513 } else if (*cmd == 'p') {
514 cmd ++;
515 while (*cmd == ' ') cmd ++;
516 if (*cmd == 0) {
517 return (CMD_LISTP);
518 }
519 } else if (*cmd == 'g') {
520 cmd ++;
521 while (*cmd == ' ') cmd ++;
522 if (*cmd == 0) {
523 return (CMD_LISTPG);
524 }
525 } else if (*cmd == 'e') {
526 cmd ++;
527 while (*cmd == ' ') cmd ++;
528 if (*cmd == 0) {
529 return (CMD_LISTNE);
530 }
531 } else if (strncmp(cmd, "dds ", 4) == 0) {
532 cmd += 4;
533 while (*cmd == ' ') cmd ++;
534 if (*cmd == 0) {
535 return (CMD_LISTDDS);
536 }
537 j = 0;
538 while (*cmd >= '0' && *cmd <= '9') {
539 tmp[j++] = *cmd ++;
540 }
541 tmp[j] = 0;
542 while (*cmd == ' ') cmd ++;
543 if (*cmd == 0 && j > 0) {
544 argv[(*argc)++] = atoi(tmp);
545 return (CMD_LISTDDSN);
546 }
547 } else if (strncmp(cmd, "dd ", 3) == 0) {
548 cmd += 3;
549 while (*cmd == ' ') cmd ++;
550 if (*cmd == 0) {
551 return (CMD_LISTDD);
552 }
553 j = 0;
554 while (*cmd >= '0' && *cmd <= '9') {
555 tmp[j++] = *cmd ++;
556 }
557 tmp[j] = 0;
558 while (*cmd == ' ') cmd ++;
559 if (*cmd == 0 && j > 0) {
560 argv[(*argc)++] = atoi(tmp);
561 return (CMD_LISTDDN);
562 }
563 }
564 return (CMD_INVALID);
565 }
566
567 /* view 0 */
568 if (strncmp(cmd, "view ", 5) == 0) {
569 cmd += 5;
570 while (*cmd == ' ') cmd ++;
571 j = 0;
572 while (*cmd >= '0' && *cmd <= '9') {
573 tmp[j++] = *cmd ++;
574 }
575 tmp[j] = 0;
576 while (*cmd == ' ') cmd ++;
577 if (*cmd == 0 && j > 0) {
578 argv[(*argc)++] = atoi(tmp);
579 return (CMD_VIEW);
580 }
581 return (CMD_INVALID);
582 }
583
584 /* add dd name */
585 /* add ddn/ddsn id id */
586 if (strncmp(cmd, "add ", 4) == 0) {
587 int addcmd = CMD_INVALID;
588 cmd += 4;
589 while (*cmd == ' ') cmd ++;
590 if (strncmp(cmd, "dd ", 3) == 0) {
591 cmd += 3;
592 addcmd = CMD_ADDDD;
593 } else if (strncmp(cmd, "ddn ", 4) == 0) {
594 cmd += 4;
595 addcmd = CMD_ADDDDN;
596 } else if (strncmp(cmd, "ddsn ", 5) == 0) {
597 cmd += 5;
598 addcmd = CMD_ADDDDSN;
599 } else {
600 return (CMD_INVALID);
601 }
602 while (*cmd == ' ') cmd ++;
603 j = 0;
604 while (*cmd >= '0' && *cmd <= '9') {
605 tmp[j++] = *cmd ++;
606 }
607 tmp[j] = 0;
608 if (j > 0) {
609 argv[(*argc)++] = atoi(tmp);
610 } else {
611 return (CMD_INVALID);
612 }
613 while (*cmd == ' ') cmd ++;
614 if (*cmd != 0) {
615 switch (addcmd) {
616 case CMD_ADDDDN:
617 case CMD_ADDDDSN:
618 j = 0;
619 while (*cmd >= '0' && *cmd <= '9') {
620 tmp[j++] = *cmd ++;
621 }
622 tmp[j] = 0;
623 while (*cmd == ' ') cmd ++;
624 if (*cmd == 0 && j > 0) {
625 argv[(*argc)++] = atoi(tmp);
626 } else {
627 return (CMD_INVALID);
628 }
629 break;
630 case CMD_ADDDD:
631 j = strlen(cmd);
632 while (j > 0) {
633 /* get rid of trail blank space */
634 if (cmd[j - 1] == ' ') {
635 cmd[--j] = 0;
636 } else {
637 break;
638 }
639 }
640 if (j > 0) {
641 cmd[j] = 0;
642 argv[(*argc)++] = (int)cmd;
643 } else {
644 return (CMD_INVALID);
645 }
646 break;
647 }
648 return (addcmd);
649 }
650 return (CMD_INVALID);
651 }
652
653 /* remove dd name */
654 /* remove ddn/ddsn id id */
655 if (strncmp(cmd, "remove ", 7) == 0) {
656 int rmcmd = CMD_INVALID;
657 cmd += 7;
658 while (*cmd == ' ') cmd ++;
659 if (strncmp(cmd, "dd ", 3) == 0) {
660 cmd += 3;
661 while (*cmd == ' ') cmd ++;
662 rmcmd = CMD_REMDD;
663 } else if (strncmp(cmd, "ddn ", 4) == 0) {
664 cmd += 4;
665 while (*cmd == ' ') cmd ++;
666 rmcmd = CMD_REMDDN;
667 } else if (strncmp(cmd, "ddsn ", 5) == 0) {
668 cmd += 5;
669 while (*cmd == ' ') cmd ++;
670 rmcmd = CMD_REMDDSN;
671 } else {
672 return (CMD_INVALID);
673 }
674 j = 0;
675 while (*cmd >= '0' && *cmd <= '9') {
676 tmp[j++] = *cmd ++;
677 }
678 tmp[j] = 0;
679 if (j > 0) {
680 argv[(*argc)++] = atoi(tmp);
681 } else {
682 return (CMD_INVALID);
683 }
684 while (*cmd == ' ') cmd ++;
685 if (*cmd != 0) {
686 switch (rmcmd) {
687 case CMD_REMDDN:
688 case CMD_REMDDSN:
689 j = 0;
690 while (*cmd >= '0' && *cmd <= '9') {
691 tmp[j++] = *cmd ++;
692 }
693 tmp[j] = 0;
694 while (*cmd == ' ') cmd ++;
695 if (*cmd == 0 && j > 0) {
696 argv[(*argc)++] = atoi(tmp);
697 } else {
698 return (CMD_INVALID);
699 }
700 break;
701 case CMD_REMDD:
702 j = strlen(cmd);
703 while (j > 0) {
704 /* get rid of trail blank space */
705 if (cmd[j - 1] == ' ') {
706 cmd[--j] = 0;
707 } else {
708 break;
709 }
710 }
711 if (j > 0) {
712 cmd[j] = 0;
713 argv[(*argc)++] = (int)cmd;
714 } else {
715 return (CMD_INVALID);
716 }
717 break;
718 }
719 return (rmcmd);
720 }
721 return (CMD_INVALID);
722 }
723
724 /* new dd, new dds */
725 if (strncmp(cmd, "new ", 4) == 0) {
726 int newcmd = CMD_INVALID;
727 cmd += 4;
728 while (*cmd == ' ') cmd ++;
729 if (strncmp(cmd, "dd ", 3) == 0) {
730 cmd += 3;
731 newcmd = CMD_NEWDD;
732 } else if (strncmp(cmd, "dds ", 4) == 0) {
733 cmd += 4;
734 newcmd = CMD_NEWDDS;
735 } else if (strncmp(cmd, "ddn ", 4) == 0) {
736 cmd += 4;
737 newcmd = CMD_NEWDDN;
738 } else if (strncmp(cmd, "ddsn ", 5) == 0) {
739 cmd += 5;
740 newcmd = CMD_NEWDDSN;
741 }
742 if (newcmd != CMD_INVALID) {
743 while (*cmd == ' ') cmd ++;
744 if (*cmd == 0) {
745 return (newcmd);
746 }
747 switch (newcmd) {
748 case CMD_NEWDDN:
749 case CMD_NEWDDSN:
750 j = 0;
751 while (*cmd >= '0' && *cmd <= '9') {
752 tmp[j++] = *cmd ++;
753 }
754 tmp[j] = 0;
755 if (*cmd == ' ' && j > 0) {
756 argv[(*argc)++] = atoi(tmp);
757 } else {
758 return (CMD_INVALID);
759 }
760 case CMD_NEWDD:
761 case CMD_NEWDDS:
762 while (*cmd == ' ') cmd ++;
763 if (*cmd != 0) {
764 j = strlen(cmd);
765 } else {
766 j = 0;
767 }
768 while (j > 0) {
769 /* get rid of trail blank space */
770 if (cmd[j - 1] == ' ') {
771 cmd[--j] = 0;
772 } else {
773 break;
774 }
775 }
776 if (j > 0) {
777 cmd[j] = 0;
778 argv[(*argc)++] = (int)cmd;
779 }
780 }
781 return (newcmd);
782 }
783 return (CMD_INVALID);
784 }
785
786 /* del dd, del dds, disable 0 */
787 if (strncmp(cmd, "del ", 4) == 0) {
788 int delcmd = CMD_INVALID;
789 cmd += 4;
790 while (*cmd == ' ') cmd ++;
791 if (strncmp(cmd, "dds ", 4) == 0) {
792 cmd += 4;
793 delcmd = CMD_DELDDS;
794 } else if (strncmp(cmd, "dd ", 3) == 0) {
795 cmd += 3;
796 delcmd = CMD_DELDD;
797 }
798 if (delcmd != CMD_INVALID) {
799 while (*cmd == ' ') cmd ++;
800 j = 0;
801 while (*cmd >= '0' && *cmd <= '9') {
802 tmp[j++] = *cmd ++;
803 }
804 tmp[j] = 0;
805 while (*cmd == ' ') cmd ++;
806 if (*cmd == 0 && j > 0) {
807 argv[(*argc)++] = atoi(tmp);
808 return (delcmd);
809 }
810 }
811 return (CMD_INVALID);
812 }
813
814 /* enable 0 */
815 if (strncmp(cmd, "enable ", 7) == 0) {
816 cmd += 7;
817 while (*cmd == ' ') cmd ++;
818 j = 0;
819 while (*cmd >= '0' && *cmd <= '9') {
820 tmp[j++] = *cmd ++;
821 }
822 tmp[j] = 0;
823 while (*cmd == ' ') cmd ++;
824 if (*cmd == 0 && j > 0) {
825 argv[(*argc)++] = atoi(tmp);
826 return (CMD_ENABLE);
827 }
828 return (CMD_INVALID);
829 }
830
831 /* disable 0 */
832 if (strncmp(cmd, "disable ", 8) == 0) {
833 cmd += 8;
834 while (*cmd == ' ') cmd ++;
835 j = 0;
836 while (*cmd >= '0' && *cmd <= '9') {
837 tmp[j++] = *cmd ++;
838 }
839 tmp[j] = 0;
840 while (*cmd == ' ') cmd ++;
841 if (*cmd == 0 && j > 0) {
842 argv[(*argc)++] = atoi(tmp);
843 return (CMD_DISABLE);
844 }
845 return (CMD_INVALID);
846 }
847
848 /* file */
849 if (strncmp(cmd, "file ", 5) == 0) {
850 cmd += 5;
851 while (*cmd == ' ') cmd ++;
852 if (*cmd != 0) {
853 j = strlen(cmd);
854 } else {
855 j = 0;
856 }
857 while (j > 0) {
858 /* get rid of trail blank space */
859 if (cmd[j - 1] == ' ') {
860 cmd[--j] = 0;
861 } else {
862 break;
863 }
864 }
865 if (j > 0) {
866 cmd[j] = 0;
867 argv[(*argc)++] = (int)cmd;
868 return (CMD_FILE);
869 }
870 return (CMD_INVALID);
871 }
872
873 /* pause */
874 if (strncmp(cmd, "pause ", 6) == 0) {
875 cmd += 6;
876 while (*cmd == ' ') cmd ++;
877 if (*cmd == 0) {
878 return (CMD_PAUSE);
879 }
880 return (CMD_INVALID);
881 }
882
883 /* help */
884 if (strncmp(cmd, "help ", 5) == 0) {
885 cmd += 5;
886 while (*cmd == ' ') cmd ++;
887 if (*cmd == 0) {
888 return (CMD_HELP);
889 }
890 return (CMD_INVALID);
891 }
892
893 /* verbose */
894 if (strncmp(cmd, "verbose ", 8) == 0) {
895 cmd += 8;
896 while (*cmd == ' ') cmd ++;
897 if (*cmd == 0) {
898 return (CMD_VERBOSE_PARSER);
899 } else if (*cmd == 'm') {
900 cmd ++;
901 while (*cmd == ' ') cmd ++;
902 if (*cmd == 0) {
903 return (CMD_VERBOSE_MEMORY);
904 }
905 } else if (*cmd == 'n') {
906 cmd ++;
907 while (*cmd == ' ') cmd ++;
908 if (*cmd == 0) {
909 return (CMD_VERBOSE_NET);
910 }
911 } else if (*cmd == 'p') {
912 cmd ++;
913 while (*cmd == ' ') cmd ++;
914 if (*cmd == 0) {
915 return (CMD_VERBOSE_PARSER);
916 }
917 } else if (*cmd == 't') {
918 cmd ++;
919 while (*cmd == ' ') cmd ++;
920 if (*cmd == 0) {
921 return (CMD_VERBOSE_TIME);
922 }
923 } else if (*cmd == 'l') {
924 cmd ++;
925 while (*cmd == ' ') cmd ++;
926 if (*cmd == 0) {
927 return (CMD_VERBOSE_LOCK);
928 }
929 }
930 return (CMD_INVALID);
931 }
932
933 /* quit */
934 if (strncmp(cmd, "quit ", 5) == 0) {
935 cmd += 5;
936 while (*cmd == ' ') cmd ++;
937 if (*cmd == 0) {
938 return (CMD_QUIT);
939 }
940 return (CMD_INVALID);
941 }
942
943 return (CMD_INVALID);
944 }
945
946 static void
print_entity(char * ident,isns_obj_t * obj)947 print_entity(
948 char *ident,
949 isns_obj_t *obj
950 )
951 {
952 uint32_t uid;
953 uchar_t *eid;
954 uint32_t *cuid;
955 int i, num;
956
957 eid = obj->attrs[
958 ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID)].value.ptr;
959 uid = get_obj_uid(obj);
960
961 if (ident != NULL) {
962 printf("%s%d\t%s\n", ident, uid, (const char *)eid);
963 } else {
964 printf("%d\t%s\n", uid, (const char *)eid);
965 }
966
967 i = 0;
968 while (i < NUM_OF_CHILD[obj->type]) {
969 cuid = get_child_n(obj, i);
970 if (ident != NULL) {
971 printf("%s\t%s%d:", "child", i);
972 } else {
973 printf("\t%s%d:", "child", i);
974 }
975 if (cuid != NULL) {
976 num = *cuid ++;
977 } else {
978 num = 0;
979 }
980 while (num > 0) {
981 printf("\t%d", *cuid ++);
982 num --;
983 }
984 printf("\n");
985 i ++;
986 }
987 }
988
989 static void
print_iscsi(char * ident,isns_obj_t * obj)990 print_iscsi(
991 char *ident,
992 isns_obj_t *obj
993 )
994 {
995 uchar_t *name = obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)]
996 .value.ptr;
997 uchar_t *alias = obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_ALIAS_ATTR_ID)]
998 .value.ptr;
999 uint32_t type = obj->attrs[
1000 ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_TYPE_ATTR_ID)].value.ui;
1001 uint32_t uid = get_obj_uid(obj);
1002 uint32_t puid = get_parent_uid(obj);
1003
1004 if (!alias) {
1005 alias = (uchar_t *)"-";
1006 }
1007
1008 if (ident != NULL) {
1009 printf("%s%d[%d]\t%s\n", ident,
1010 uid, puid, (const char *)name);
1011 printf("%s\t%s", ident, alias);
1012 } else {
1013 printf("%d[%d]\t%s\n",
1014 uid, puid, (const char *)name);
1015 printf("\t%s", alias);
1016 }
1017 if (IS_TYPE_TARGET(type)) {
1018 printf("\tTarget");
1019 }
1020 if (IS_TYPE_INITIATOR(type)) {
1021 printf("\tInitiator");
1022 }
1023 if (IS_TYPE_CONTROL(type)) {
1024 printf("\tControl");
1025 }
1026 if (IS_TYPE_UNKNOWN(type)) {
1027 printf("\t-");
1028 }
1029 printf("\n");
1030 }
1031
1032 static void
print_portal(char * ident,isns_obj_t * obj)1033 print_portal(
1034 char *ident,
1035 isns_obj_t *obj
1036 )
1037 {
1038 char pbuff[256] = { 0 };
1039 in6_addr_t *ip = obj->attrs[
1040 ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID)].value.ip;
1041 uint32_t port = obj->attrs[
1042 ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID)].value.ui;
1043 uint32_t uid = get_obj_uid(obj);
1044 uint32_t puid = get_parent_uid(obj);
1045
1046 inet_ntop(AF_INET6, (void *)ip, pbuff, sizeof (pbuff));
1047 if (ident != NULL) {
1048 printf("%s%d[%d]\t%s:%d", ident,
1049 uid, puid, pbuff, PORT_NUMBER(port));
1050 } else {
1051 printf("%d[%d]\t%s:%d",
1052 uid, puid, pbuff, PORT_NUMBER(port));
1053 }
1054 printf(" %s\n", IS_PORT_UDP(port) ? "UDP" : "TCP");
1055 }
1056
1057 static void
print_pg(char * ident,isns_obj_t * obj)1058 print_pg(
1059 char *ident,
1060 isns_obj_t *obj
1061 )
1062 {
1063 uint32_t ref;
1064 int i;
1065
1066 char pbuff[256] = { 0 };
1067 uchar_t *name = obj->attrs[ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID)]
1068 .value.ptr;
1069 in6_addr_t *ip = obj->attrs[
1070 ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID)].value.ip;
1071 uint32_t port = obj->attrs[
1072 ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID)].value.ui;
1073 uint32_t tag = obj->attrs[
1074 ATTR_INDEX_PG(ISNS_PG_TAG_ATTR_ID)].value.ui;
1075 uint32_t uid = get_obj_uid(obj);
1076 uint32_t puid = get_parent_uid(obj);
1077
1078 inet_ntop(AF_INET6, (void *)ip, pbuff, sizeof (pbuff));
1079 if (ident != NULL) {
1080 printf("%s%d[%d]\t[%d] %s\n", ident,
1081 uid, puid, tag, (const char *)name);
1082 printf("%s\t%s:%d", ident, pbuff, PORT_NUMBER(port));
1083 } else {
1084 printf("%d[%d]\t[%d] %s\n",
1085 uid, puid, tag, (const char *)name);
1086 printf("\t%s:%d", pbuff, PORT_NUMBER(port));
1087 }
1088 printf(" %s\n", IS_PORT_UDP(port) ? "UDP" : "TCP");
1089
1090 if (NUM_OF_REF[obj->type] > 0) {
1091 if (ident != NULL) {
1092 printf("%s\t%s:", "ref");
1093 } else {
1094 printf("\t%s:", "ref");
1095 }
1096 }
1097 i = 0;
1098 while (i < NUM_OF_REF[obj->type]) {
1099 ref = get_ref_n(obj, i);
1100 printf("\t%d", ref);
1101 i ++;
1102 }
1103 if (i > 0) {
1104 printf("\n");
1105 }
1106 }
1107
1108 static void
print_dd(char * ident,isns_obj_t * obj)1109 print_dd(
1110 char *ident,
1111 isns_obj_t *obj
1112 )
1113 {
1114 uchar_t *name = obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)]
1115 .value.ptr;
1116 uint32_t uid = obj->attrs[UID_ATTR_INDEX[OBJ_DD]].value.ui;
1117
1118 if (ident != NULL) {
1119 printf("%s%d\t%s\n", ident, uid, (const char *)name);
1120 } else {
1121 printf("%d\t%s\n", uid, (const char *)name);
1122 }
1123 }
1124
1125 static void
print_dds(char * ident,isns_obj_t * obj)1126 print_dds(
1127 char *ident,
1128 isns_obj_t *obj
1129 )
1130 {
1131 uchar_t *name = obj->attrs[ATTR_INDEX_DDS(
1132 ISNS_DD_SET_NAME_ATTR_ID)].value.ptr;
1133 uint32_t uid = obj->attrs[UID_ATTR_INDEX[OBJ_DDS]].value.ui;
1134 uint32_t enabled = obj->attrs[ATTR_INDEX_DDS(
1135 ISNS_DD_SET_STATUS_ATTR_ID)].value.ui;
1136
1137 if (ident != NULL) {
1138 printf("%s%d\t%s\t\t(%s)\n", ident, uid,
1139 (const char *)name, enabled ? "enabled" : "disabled");
1140 } else {
1141 printf("%d\t%s\t\t(%s)\n", uid,
1142 (const char *)name, enabled ? "enabled" : "disabled");
1143 }
1144 }
1145
1146 void
print_object(char * ident,isns_obj_t * obj)1147 print_object(
1148 char *ident,
1149 isns_obj_t *obj
1150 )
1151 {
1152 print_func[obj->type](ident, obj);
1153 }
1154
1155 /*ARGSUSED*/
1156 static int
cb_print_obj_n(void * p1,void * p2)1157 cb_print_obj_n(
1158 void *p1,
1159 void *p2
1160 )
1161 {
1162 isns_obj_t *obj = (isns_obj_t *)p1;
1163 print_func[obj->type](NULL, obj);
1164
1165 return (0);
1166 }
1167
1168 static void
list_pg()1169 list_pg(
1170 )
1171 {
1172 cache_dump_htab(OBJ_PG);
1173 }
1174
1175 static void
list_portal()1176 list_portal(
1177 )
1178 {
1179 cache_dump_htab(OBJ_PORTAL);
1180 }
1181
1182 static void
list_node()1183 list_node(
1184 )
1185 {
1186 cache_dump_htab(OBJ_ISCSI);
1187 }
1188
1189 static void
list_entity()1190 list_entity(
1191 )
1192 {
1193 cache_dump_htab(OBJ_ENTITY);
1194 }
1195
1196 static void
list_dd()1197 list_dd(
1198 )
1199 {
1200 cache_dump_htab(OBJ_DD);
1201 }
1202
1203 static void
list_ddn(uint32_t uid)1204 list_ddn(
1205 uint32_t uid
1206 )
1207 {
1208 lookup_ctrl_t lc;
1209
1210 bmp_t *p;
1211 uint32_t n;
1212
1213 if (uid != 0) {
1214 setup_ddid_lcp(&lc, uid);
1215 cache_lookup(&lc, &uid, cb_print_obj_n);
1216 }
1217
1218 if (uid != 0) {
1219 printf("--------------------------------\n");
1220 get_dd_matrix(uid, &p, &n);
1221 SET_UID_LCP(&lc, OBJ_ISCSI, 0);
1222 FOR_EACH_MEMBER(p, n, uid, {
1223 lc.data[0].ui = uid;
1224 cache_lookup(&lc, NULL, cb_print_obj_n);
1225 });
1226 free(p);
1227 } else {
1228 printf("no such dd.\n");
1229 }
1230 }
1231
1232 static void
list_ddsn(uint32_t uid)1233 list_ddsn(
1234 uint32_t uid
1235 )
1236 {
1237 lookup_ctrl_t lc;
1238
1239 bmp_t *p;
1240 uint32_t n;
1241
1242 if (uid != 0) {
1243 setup_ddsid_lcp(&lc, uid);
1244 cache_lookup(&lc, &uid, cb_print_obj_n);
1245 }
1246
1247 if (uid != 0) {
1248 printf("--------------------------------\n");
1249 get_dds_matrix(uid, &p, &n);
1250 SET_UID_LCP(&lc, OBJ_DD, 0);
1251 FOR_EACH_MEMBER(p, n, uid, {
1252 lc.data[0].ui = uid;
1253 cache_lookup(&lc, NULL, cb_print_obj_n);
1254 });
1255 free(p);
1256 } else {
1257 printf("no such dd-set.\n");
1258 }
1259 }
1260
1261 static void
list_dds()1262 list_dds(
1263 )
1264 {
1265 cache_dump_htab(OBJ_DDS);
1266 }
1267
1268 static void
new_dd_dds(int cmd_id,int argc,int * argv)1269 new_dd_dds(
1270 int cmd_id,
1271 int argc,
1272 int *argv
1273 )
1274 {
1275 uint32_t buff[256];
1276 isns_pdu_t *pdu = (isns_pdu_t *)buff;
1277 uint8_t *payload = &pdu->payload[0];
1278 uint16_t payload_len = 0;
1279 isns_tlv_t *tlv;
1280
1281 int len = 0;
1282 uint32_t uid = 0;
1283 char *name;
1284
1285 conn_arg_t conn;
1286
1287 pdu->version = ISNSP_VERSION;
1288
1289 /* source attribute */
1290 tlv = (isns_tlv_t *)payload;
1291 tlv->attr_id = htonl(ISNS_ISCSI_NAME_ATTR_ID);
1292 tlv->attr_len = htonl(32);
1293 strcpy((char *)tlv->attr_value, "i am a control node.");
1294 payload += 8 + 32;
1295 payload_len += 8 + 32;
1296
1297 /* key attributes */
1298
1299 /* delimiter */
1300 tlv = (isns_tlv_t *)payload;
1301 tlv->attr_id = htonl(ISNS_DELIMITER_ATTR_ID);
1302 tlv->attr_len = htonl(0);
1303 payload += 8 + 0;
1304 payload_len += 8 + 0;
1305
1306 /* operating attributes */
1307 switch (cmd_id) {
1308 case CMD_NEWDD:
1309 pdu->func_id = ISNS_DD_REG;
1310 if (argc == 1) {
1311 name = (char *)argv[0];
1312 len = strlen(name) + 1;
1313 len += 4 - (len % 4);
1314 }
1315 tlv = (isns_tlv_t *)payload;
1316 tlv->attr_id = htonl(ISNS_DD_NAME_ATTR_ID);
1317 tlv->attr_len = htonl(len);
1318 if (len > 0) {
1319 strcpy((char *)tlv->attr_value, name);
1320 }
1321 payload_len += 8 + len;
1322 break;
1323 case CMD_NEWDDS:
1324 pdu->func_id = ISNS_DDS_REG;
1325 if (argc == 1) {
1326 name = (char *)argv[0];
1327 len = strlen(name) + 1;
1328 len += 4 - (len % 4);
1329 }
1330 tlv = (isns_tlv_t *)payload;
1331 tlv->attr_id = htonl(ISNS_DD_SET_NAME_ATTR_ID);
1332 tlv->attr_len = htonl(len);
1333 if (len > 0) {
1334 strcpy((char *)tlv->attr_value, name);
1335 }
1336 payload_len += 8 + len;
1337 break;
1338 case CMD_NEWDDN:
1339 pdu->func_id = ISNS_DD_REG;
1340 switch (argc) {
1341 case 2:
1342 name = (char *)argv[1];
1343 len = strlen(name) + 1;
1344 len += 4 - (len % 4);
1345 case 1:
1346 uid = argv[0];
1347 }
1348 tlv = (isns_tlv_t *)payload;
1349 tlv->attr_id = htonl(ISNS_DD_NAME_ATTR_ID);
1350 tlv->attr_len = htonl(len);
1351 if (len > 0) {
1352 strcpy((char *)tlv->attr_value, name);
1353 }
1354 payload += 8 + len;
1355 payload_len += 8 + len;
1356 if (uid > 0) {
1357 tlv = (isns_tlv_t *)payload;
1358 tlv->attr_id = htonl(ISNS_DD_ID_ATTR_ID);
1359 tlv->attr_len = htonl(4);
1360 *(uint32_t *)tlv->attr_value = htonl(uid);
1361 payload_len += 8 + 4;
1362 }
1363 break;
1364 case CMD_NEWDDSN:
1365 pdu->func_id = ISNS_DDS_REG;
1366 switch (argc) {
1367 case 2:
1368 name = (char *)argv[1];
1369 len = strlen(name) + 1;
1370 len += 4 - (len % 4);
1371 case 1:
1372 uid = argv[0];
1373 }
1374 tlv = (isns_tlv_t *)payload;
1375 tlv->attr_id = htonl(ISNS_DD_SET_NAME_ATTR_ID);
1376 tlv->attr_len = htonl(len);
1377 if (len > 0) {
1378 strcpy((char *)tlv->attr_value, name);
1379 }
1380 payload_len += 8 + len;
1381 payload += 8 + len;
1382 if (uid > 0) {
1383 tlv = (isns_tlv_t *)payload;
1384 tlv->attr_id = htonl(ISNS_DD_SET_ID_ATTR_ID);
1385 tlv->attr_len = htonl(4);
1386 *(uint32_t *)tlv->attr_value = htonl(uid);
1387 payload_len += 8 + 4;
1388 }
1389 break;
1390 default:
1391 break;
1392 }
1393
1394 pdu->payload_len = payload_len;
1395
1396 dump_pdu1(pdu);
1397
1398 conn.in_packet.pdu = pdu;
1399 conn.out_packet.pdu = NULL;
1400 conn.out_packet.sz = 0;
1401
1402 if (packet_split_verify(&conn) == 0) {
1403 cache_lock(conn.lock);
1404 conn.handler(&conn);
1405 conn.ec = cache_unlock(conn.lock, conn.ec);
1406 }
1407
1408 if (conn.out_packet.pdu != NULL) {
1409 pdu_update_code(conn.out_packet.pdu,
1410 &conn.out_packet.pl, conn.ec);
1411 dump_pdu2(conn.out_packet.pdu);
1412 free(conn.out_packet.pdu);
1413 } else if (conn.ec != 0) {
1414 printf("operation failed[%d].\n", conn.ec);
1415 }
1416 }
1417
1418 static void
del_dd_dds(int cmd_id,int uid)1419 del_dd_dds(
1420 int cmd_id,
1421 int uid
1422 )
1423 {
1424 uint32_t buff[256];
1425 isns_pdu_t *pdu = (isns_pdu_t *)buff;
1426 uint8_t *payload = &pdu->payload[0];
1427 uint16_t payload_len = 0;
1428 isns_tlv_t *tlv;
1429
1430 uint32_t tag;
1431
1432 conn_arg_t conn;
1433
1434 if (uid == 0) {
1435 return;
1436 }
1437
1438 pdu->version = ISNSP_VERSION;
1439
1440 if (cmd_id == CMD_DELDD) {
1441 tag = ISNS_DD_ID_ATTR_ID;
1442 pdu->func_id = ISNS_DD_DEREG;
1443 } else {
1444 tag = ISNS_DD_SET_ID_ATTR_ID;
1445 pdu->func_id = ISNS_DDS_DEREG;
1446 }
1447
1448 /* source attribute */
1449 tlv = (isns_tlv_t *)payload;
1450 tlv->attr_id = htonl(ISNS_ISCSI_NAME_ATTR_ID);
1451 tlv->attr_len = htonl(32);
1452 strcpy((char *)tlv->attr_value, "i am a control node.");
1453 payload_len += 8 + 32;
1454 payload += 8 + 32;
1455
1456 /* key attributes */
1457 tlv = (isns_tlv_t *)payload;
1458 tlv->attr_id = htonl(tag);
1459 tlv->attr_len = htonl(4);
1460 *(uint32_t *)tlv->attr_value = htonl(uid);
1461 payload_len += 8 + 4;
1462 payload += 8 + 4;
1463
1464 /* delimiter */
1465 tlv = (isns_tlv_t *)payload;
1466 tlv->attr_id = htonl(ISNS_DELIMITER_ATTR_ID);
1467 tlv->attr_len = htonl(0);
1468 payload_len += 8 + 0;
1469 payload += 8 + 0;
1470
1471 /* operating attributes */
1472
1473 pdu->payload_len = payload_len;
1474
1475 dump_pdu1(pdu);
1476
1477 conn.in_packet.pdu = pdu;
1478 conn.out_packet.pdu = NULL;
1479 conn.out_packet.sz = 0;
1480
1481 if (packet_split_verify(&conn) == 0) {
1482 cache_lock(conn.lock);
1483 conn.handler(&conn);
1484 conn.ec = cache_unlock(conn.lock, conn.ec);
1485 }
1486
1487 if (conn.out_packet.pdu != NULL) {
1488 pdu_update_code(conn.out_packet.pdu,
1489 &conn.out_packet.pl, conn.ec);
1490 dump_pdu2(conn.out_packet.pdu);
1491 free(conn.out_packet.pdu);
1492 } else if (conn.ec != 0) {
1493 printf("operation failed[%d].\n", conn.ec);
1494 }
1495 }
1496
1497 static void
update_dds(int cmd_id,int uid)1498 update_dds(
1499 int cmd_id,
1500 int uid
1501 )
1502 {
1503 uint32_t buff[256];
1504 isns_pdu_t *pdu = (isns_pdu_t *)buff;
1505 uint8_t *payload = &pdu->payload[0];
1506 uint16_t payload_len = 0;
1507 isns_tlv_t *tlv;
1508
1509 conn_arg_t conn;
1510
1511 if (uid == 0) {
1512 return;
1513 }
1514
1515 pdu->version = ISNSP_VERSION;
1516
1517 pdu->func_id = ISNS_DDS_REG;
1518
1519 /* source attribute */
1520 tlv = (isns_tlv_t *)payload;
1521 tlv->attr_id = htonl(ISNS_ISCSI_NAME_ATTR_ID);
1522 tlv->attr_len = htonl(32);
1523 strcpy((char *)tlv->attr_value, "i am a control node.");
1524 payload_len += 8 + 32;
1525 payload += 8 + 32;
1526
1527 /* key attributes */
1528 tlv = (isns_tlv_t *)payload;
1529 tlv->attr_id = htonl(ISNS_DD_SET_ID_ATTR_ID);
1530 tlv->attr_len = htonl(4);
1531 *(uint32_t *)tlv->attr_value = htonl(uid);
1532 payload_len += 8 + 4;
1533 payload += 8 + 4;
1534
1535 /* delimiter */
1536 tlv = (isns_tlv_t *)payload;
1537 tlv->attr_id = htonl(ISNS_DELIMITER_ATTR_ID);
1538 tlv->attr_len = htonl(0);
1539 payload_len += 8 + 0;
1540 payload += 8 + 0;
1541
1542 /* operating attributes */
1543 tlv = (isns_tlv_t *)payload;
1544 tlv->attr_id = htonl(ISNS_DD_SET_STATUS_ATTR_ID);
1545 tlv->attr_len = htonl(4);
1546 if (cmd_id == CMD_ENABLE) {
1547 *(uint32_t *)tlv->attr_value = htonl(1);
1548 } else {
1549 *(uint32_t *)tlv->attr_value = htonl(0);
1550 }
1551 payload_len += 8 + 4;
1552
1553 pdu->payload_len = payload_len;
1554
1555 dump_pdu1(pdu);
1556
1557 conn.in_packet.pdu = pdu;
1558 conn.out_packet.pdu = NULL;
1559 conn.out_packet.sz = 0;
1560
1561 if (packet_split_verify(&conn) == 0) {
1562 cache_lock(conn.lock);
1563 conn.handler(&conn);
1564 conn.ec = cache_unlock(conn.lock, conn.ec);
1565 }
1566
1567 if (conn.out_packet.pdu != NULL) {
1568 pdu_update_code(conn.out_packet.pdu,
1569 &conn.out_packet.pl, conn.ec);
1570 dump_pdu2(conn.out_packet.pdu);
1571 free(conn.out_packet.pdu);
1572 } else if (conn.ec != 0) {
1573 printf("operation failed[%d].\n", conn.ec);
1574 }
1575 }
1576
1577 static void
update_member(int cmd_id,int * argv)1578 update_member(
1579 int cmd_id,
1580 int *argv
1581 )
1582 {
1583 uint32_t buff[256];
1584 isns_pdu_t *pdu = (isns_pdu_t *)buff;
1585 uint8_t *payload = &pdu->payload[0];
1586 uint16_t payload_len = 0;
1587 isns_tlv_t *tlv;
1588 uint32_t key_tag, op_tag, op_len;
1589
1590 uint32_t uid = argv[0];
1591 uint32_t m_id;
1592 char *m_name;
1593
1594 conn_arg_t conn;
1595
1596 if (uid == 0) {
1597 printf("operation failed.\n");
1598 return;
1599 }
1600
1601 pdu->version = ISNSP_VERSION;
1602
1603 switch (cmd_id) {
1604 case CMD_ADDDD:
1605 case CMD_ADDDDN:
1606 pdu->func_id = ISNS_DD_REG;
1607 break;
1608 case CMD_REMDD:
1609 case CMD_REMDDN:
1610 pdu->func_id = ISNS_DD_DEREG;
1611 break;
1612 case CMD_ADDDDSN:
1613 pdu->func_id = ISNS_DDS_REG;
1614 break;
1615 case CMD_REMDDSN:
1616 pdu->func_id = ISNS_DDS_DEREG;
1617 break;
1618 }
1619 switch (cmd_id) {
1620 case CMD_ADDDD:
1621 case CMD_REMDD:
1622 key_tag = ISNS_DD_ID_ATTR_ID;
1623 op_tag = ISNS_DD_ISCSI_NAME_ATTR_ID;
1624 m_name = (char *)argv[1];
1625 op_len = strlen(m_name);
1626 op_len += 4 - (op_len % 4);
1627 break;
1628 case CMD_ADDDDN:
1629 case CMD_REMDDN:
1630 key_tag = ISNS_DD_ID_ATTR_ID;
1631 op_tag = ISNS_DD_ISCSI_INDEX_ATTR_ID;
1632 m_id = argv[1];
1633 op_len = 4;
1634 break;
1635 case CMD_ADDDDSN:
1636 case CMD_REMDDSN:
1637 key_tag = ISNS_DD_SET_ID_ATTR_ID;
1638 op_tag = ISNS_DD_ID_ATTR_ID;
1639 m_id = argv[1];
1640 op_len = 4;
1641 break;
1642 }
1643
1644 /* source attribute */
1645 tlv = (isns_tlv_t *)payload;
1646 tlv->attr_id = htonl(ISNS_ISCSI_NAME_ATTR_ID);
1647 tlv->attr_len = htonl(32);
1648 strcpy((char *)tlv->attr_value, "i am a control node.");
1649 payload_len += 8 + 32;
1650 payload += 8 + 32;
1651
1652 /* key attributes */
1653 tlv = (isns_tlv_t *)payload;
1654 tlv->attr_id = htonl(key_tag);
1655 tlv->attr_len = htonl(4);
1656 *(uint32_t *)tlv->attr_value = htonl(uid);
1657 payload_len += 8 + 4;
1658 payload += 8 + 4;
1659
1660 /* delimiter */
1661 tlv = (isns_tlv_t *)payload;
1662 tlv->attr_id = htonl(ISNS_DELIMITER_ATTR_ID);
1663 tlv->attr_len = htonl(0);
1664 payload_len += 8 + 0;
1665 payload += 8 + 0;
1666
1667 /* operating attributes */
1668 tlv = (isns_tlv_t *)payload;
1669 tlv->attr_id = htonl(op_tag);
1670 tlv->attr_len = htonl(op_len);
1671 switch (cmd_id) {
1672 case CMD_ADDDD:
1673 case CMD_REMDD:
1674 strcpy((char *)tlv->attr_value, m_name);
1675 break;
1676 case CMD_ADDDDN:
1677 case CMD_ADDDDSN:
1678 case CMD_REMDDN:
1679 case CMD_REMDDSN:
1680 *(uint32_t *)tlv->attr_value = htonl(m_id);
1681 break;
1682 }
1683 payload_len += 8 + op_len;
1684
1685 pdu->payload_len = payload_len;
1686
1687 dump_pdu1(pdu);
1688
1689 conn.in_packet.pdu = pdu;
1690 conn.out_packet.pdu = NULL;
1691 conn.out_packet.sz = 0;
1692
1693 if (packet_split_verify(&conn) == 0) {
1694 cache_lock(conn.lock);
1695 conn.handler(&conn);
1696 conn.ec = cache_unlock(conn.lock, conn.ec);
1697 }
1698
1699 if (conn.out_packet.pdu != NULL) {
1700 pdu_update_code(conn.out_packet.pdu,
1701 &conn.out_packet.pl, conn.ec);
1702 dump_pdu2(conn.out_packet.pdu);
1703 free(conn.out_packet.pdu);
1704 } else if (conn.ec != 0) {
1705 printf("operation failed[%d].\n", conn.ec);
1706 }
1707 }
1708
1709 static void
cmd_file(char * file)1710 cmd_file(
1711 char *file
1712 )
1713 {
1714 char i = 0, ch, cmd[256];
1715 FILE *f = fopen(file, "r");
1716 if (f != NULL) {
1717 while ((ch = fgetc(f)) != 0 && ch != EOF) {
1718 if (ch == '\t') {
1719 cmd[i++] = ' ';
1720 } else if (ch != '\n') {
1721 cmd[i++] = ch;
1722 } else {
1723 cmd[i ++] = ' ';
1724 cmd[i] = 0;
1725 i = 0;
1726 printf("%s\n", cmd);
1727 if (run_cmd(cmd) != 0) {
1728 break;
1729 }
1730 }
1731 }
1732 fclose(f);
1733 } else {
1734 printf("Cannot open file %s.\n", file);
1735 }
1736 }
1737
1738 static int
run_cmd(char * cmd)1739 run_cmd(
1740 char *cmd
1741 )
1742 {
1743 int argc, argv[32];
1744 int cmd_id;
1745 cmd_id = getcmd(&argc, argv, cmd);
1746 switch (cmd_id) {
1747 case CMD_LIST:
1748 list_node();
1749 break;
1750 case CMD_LISTNE:
1751 list_entity();
1752 break;
1753 case CMD_LISTP:
1754 list_portal();
1755 break;
1756 case CMD_LISTPG:
1757 list_pg();
1758 break;
1759 case CMD_LISTDD:
1760 list_dd();
1761 break;
1762 case CMD_LISTDDS:
1763 list_dds();
1764 break;
1765 case CMD_LISTDDN:
1766 list_ddn(argv[0]);
1767 break;
1768 case CMD_LISTDDSN:
1769 list_ddsn(argv[0]);
1770 break;
1771 case CMD_NEWDD:
1772 case CMD_NEWDDS:
1773 case CMD_NEWDDN:
1774 case CMD_NEWDDSN:
1775 new_dd_dds(cmd_id, argc, argv);
1776 break;
1777 case CMD_DELDD:
1778 case CMD_DELDDS:
1779 del_dd_dds(cmd_id, argv[0]);
1780 break;
1781 case CMD_ENABLE:
1782 case CMD_DISABLE:
1783 update_dds(cmd_id, argv[0]);
1784 break;
1785 case CMD_ADDDD:
1786 case CMD_ADDDDN:
1787 case CMD_ADDDDSN:
1788 case CMD_REMDD:
1789 case CMD_REMDDN:
1790 case CMD_REMDDSN:
1791 update_member(cmd_id, argv);
1792 break;
1793 case CMD_PAUSE:
1794 printf("Press enter to continue...");
1795 getchar();
1796 break;
1797 case CMD_FILE:
1798 cmd_file((char *)argv[0]);
1799 break;
1800 case CMD_HELP:
1801 test_cli_help();
1802 break;
1803 case CMD_VERBOSE_MEMORY:
1804 verbose_mc = !verbose_mc;
1805 break;
1806 case CMD_VERBOSE_NET:
1807 verbose_net = !verbose_net;
1808 break;
1809 case CMD_VERBOSE_TIME:
1810 verbose_tc = !verbose_tc;
1811 break;
1812 case CMD_VERBOSE_LOCK:
1813 verbose_lock = !verbose_lock;
1814 break;
1815 case CMD_VERBOSE_PARSER:
1816 verbose_parser = !verbose_parser;
1817 break;
1818 case CMD_QUIT:
1819 /* clean up cli */
1820 /* notify sys control */
1821 shutdown_server();
1822 return (1);
1823 case CMD_NONE:
1824 break;
1825 default:
1826 printf("invalid command\n");
1827 break;
1828 }
1829 if (cmd_id != CMD_NONE) {
1830 printf("\n>");
1831 } else {
1832 printf(">");
1833 }
1834 return (0);
1835 }
1836
1837 /*ARGSUSED*/
cli_test(void * arg)1838 void *cli_test(void *arg) {
1839 char i = 0, ch, cmd[256];
1840
1841 printf("iSNS Server test CLI.\n");
1842 printf("Copyright 2007 Sun Microsystems, Inc.\n");
1843
1844 printf("\n>");
1845 while ((ch = getchar()) != 0 && ch != EOF) {
1846 if (ch == '\t') {
1847 cmd[i++] = ' ';
1848 } else if (ch != '\n') {
1849 cmd[i++] = ch;
1850 } else {
1851 cmd[i ++] = ' ';
1852 cmd[i] = 0;
1853 i = 0;
1854 if (run_cmd(cmd) != 0) {
1855 break;
1856 }
1857 }
1858 }
1859
1860 return (NULL);
1861 }
1862 #endif
1863