12 #include "mpath_persist.h"
13 #include "mpath_persist_int.h"
22 static const char * pr_type_strs[] = {
28 "Write Exclusive, registrants only",
29 "Exclusive Access, registrants only",
30 "Write Exclusive, all registrants",
31 "Exclusive Access, all registrants",
32 "obsolete [9]", "obsolete [0xa]", "obsolete [0xb]", "obsolete [0xc]",
33 "obsolete [0xd]", "obsolete [0xe]", "obsolete [0xf]",
36 int get_transportids_length(unsigned char * transportid_arr, int max_transportid, int num_transportids);
37 void mpath_print_buf_readcap(struct prin_resp *pr_buff);
38 void mpath_print_buf_readfullstat(struct prin_resp *pr_buff);
39 void mpath_print_buf_readresv(struct prin_resp *pr_buff);
40 void mpath_print_buf_readkeys(struct prin_resp *pr_buff);
41 void dumpHex(const char* str, int len, int no_ascii);
42 void * mpath_alloc_prin_response(int prin_sa);
43 void mpath_print_transport_id(struct prin_fulldescr *fdesc);
44 int construct_transportid(const char * inp, struct transportid transid[], int num_transportids);
46 void rcu_register_thread_memb(void) {}
48 void rcu_unregister_thread_memb(void) {}
51 static int verbose, loglevel, noisy;
53 static int handle_args(int argc, char * argv[], int line);
55 static int do_batch_file(const char *batch_fn)
57 char command[] = "mpathpersist";
58 const int ARGV_CHUNK = 2;
59 const char delims[] = " \t\n";
64 int argl = ARGV_CHUNK;
66 char **argv = calloc(argl, sizeof(*argv));
67 int ret = MPATH_PR_SUCCESS;
70 return MPATH_PR_OTHER;
72 fl = fopen(batch_fn, "r");
74 fprintf(stderr, "unable to open %s: %s\n",
75 batch_fn, strerror(errno));
77 return MPATH_PR_SYNTAX_ERROR;
80 fprintf(stderr, "running batch file %s\n",
84 while ((n = getline(&line, &len, fl)) != -1) {
90 argv[argc++] = command;
92 if (line[n-1] == '\n')
95 fprintf(stderr, "processing line %d: %s\n",
98 for (token = strtok_r(line, delims, &_token);
99 token != NULL && *token != '#';
100 token = strtok_r(NULL, delims, &_token)) {
103 int argn = argl + ARGV_CHUNK;
106 tmp = realloc(argv, argn * sizeof(*argv));
113 if (argc == 1 && !strcmp(token, command))
116 argv[argc++] = token;
125 fprintf(stderr, "## file %s line %d:", batch_fn, nline);
126 for (i = 0; i < argc; i++)
127 fprintf(stderr, " %s", argv[i]);
128 fprintf(stderr, "\n");
132 rv = handle_args(argc, argv, nline);
133 if (rv != MPATH_PR_SUCCESS)
143 static struct prout_param_descriptor *
144 alloc_prout_param_descriptor(int num_transportid)
146 struct prout_param_descriptor *paramp;
148 if (num_transportid < 0 || num_transportid > MPATH_MX_TIDS)
151 paramp= malloc(sizeof(struct prout_param_descriptor) +
152 (sizeof(struct transportid *) * num_transportid));
157 memset(paramp, 0, sizeof(struct prout_param_descriptor) +
158 (sizeof(struct transportid *) * num_transportid));
162 static void free_prout_param_descriptor(struct prout_param_descriptor *paramp)
168 for (i = 0; i < paramp->num_transportid; i++)
169 free(paramp->trnptid_list[i]);
174 static int handle_args(int argc, char * argv[], int nline)
178 const char *device_name = NULL;
180 int num_prout_sa = 0;
181 int num_prout_param = 0;
186 uint64_t param_sark = 0;
187 unsigned int prout_type = 0;
188 int param_alltgpt = 0;
190 uint64_t param_rk = 0;
191 unsigned int param_rtp = 0;
192 int num_transportids = 0;
193 struct transportid transportids[MPATH_MX_TIDS];
198 char *batch_fn = NULL;
201 memset(transportids, 0, MPATH_MX_TIDS * sizeof(struct transportid));
205 int option_index = 0;
207 c = getopt_long (argc, argv, "v:Cd:hHioYZK:S:PAT:skrGILcRX:l:f:",
208 long_options, &option_index);
217 "ERROR: -f option not allowed in batch file\n");
218 ret = MPATH_PR_SYNTAX_ERROR;
221 if (batch_fn != NULL) {
223 "ERROR: -f option can be used at most once\n");
224 ret = MPATH_PR_SYNTAX_ERROR;
227 batch_fn = strdup(optarg);
230 if (nline == 0 && 1 != sscanf (optarg, "%d", &loglevel))
232 fprintf (stderr, "bad argument to '--verbose'\n");
233 ret = MPATH_PR_SYNTAX_ERROR;
239 prout_sa = MPATH_PROUT_CLEAR_SA;
244 device_name = optarg;
273 if (1 != sscanf (optarg, "%" SCNx64 "", ¶m_rk))
275 fprintf (stderr, "bad argument to '--param-rk'\n");
276 ret = MPATH_PR_SYNTAX_ERROR;
283 if (1 != sscanf (optarg, "%" SCNx64 "", ¶m_sark))
285 fprintf (stderr, "bad argument to '--param-sark'\n");
286 ret = MPATH_PR_SYNTAX_ERROR;
293 prout_sa = MPATH_PROUT_PREE_SA;
298 prout_sa = MPATH_PROUT_PREE_AB_SA;
303 if (1 != sscanf (optarg, "%x", &prout_type))
305 fprintf (stderr, "bad argument to '--prout-type'\n");
306 ret = MPATH_PR_SYNTAX_ERROR;
313 prin_sa = MPATH_PRIN_RFSTAT_SA;
318 prin_sa = MPATH_PRIN_RKEY_SA;
323 prin_sa = MPATH_PRIN_RRES_SA;
328 prout_sa = MPATH_PROUT_REG_SA;
333 prout_sa = MPATH_PROUT_REG_IGN_SA;
338 prout_sa = MPATH_PROUT_REL_SA;
343 prin_sa = MPATH_PRIN_RCAP_SA;
348 prout_sa = MPATH_PROUT_RES_SA;
353 if (0 != construct_transportid(optarg, transportids, num_transportids)) {
354 fprintf(stderr, "bad argument to '--transport-id'\n");
355 ret = MPATH_PR_SYNTAX_ERROR;
363 if (1 != sscanf(optarg, "%u", &mpath_mx_alloc_len)) {
364 fprintf(stderr, "bad argument to '--alloc-length'\n");
365 ret = MPATH_PR_SYNTAX_ERROR;
367 } else if (MPATH_MAX_PARAM_LEN < mpath_mx_alloc_len) {
368 fprintf(stderr, "'--alloc-length' argument exceeds maximum"
369 " limit(%d)\n", MPATH_MAX_PARAM_LEN);
370 ret = MPATH_PR_SYNTAX_ERROR;
376 fprintf(stderr, "unrecognised switch " "code 0x%x ??\n", c);
377 ret = MPATH_PR_SYNTAX_ERROR;
385 if (NULL == device_name)
387 device_name = argv[optind];
392 for (; optind < argc; ++optind)
393 fprintf (stderr, "Unexpected extra argument: %s\n", argv[optind]);
394 ret = MPATH_PR_SYNTAX_ERROR;
401 noisy = (loglevel >= 3) ? 1 : hex;
402 verbose = (loglevel >= 3)? 3: loglevel;
403 ret = mpath_persistent_reserve_init_vecs(verbose);
404 if (ret != MPATH_PR_SUCCESS)
408 if ((prout_flag + prin_flag) == 0 && batch_fn == NULL)
410 fprintf (stderr, "choose either '--in' or '--out' \n");
411 ret = MPATH_PR_SYNTAX_ERROR;
414 if ((prout_flag + prin_flag) > 1)
416 fprintf (stderr, "choose either '--in' or '--out' \n");
417 ret = MPATH_PR_SYNTAX_ERROR;
421 { /* syntax check on PROUT arguments */
423 if ((1 != num_prout_sa) || (0 != num_prin_sa))
425 fprintf (stderr, " For Persistent Reserve Out only one "
426 "appropriate\n service action must be "
428 ret = MPATH_PR_SYNTAX_ERROR;
433 { /* syntax check on PRIN arguments */
435 if (num_prout_sa > 0)
437 fprintf (stderr, " When a service action for Persistent "
438 "Reserve Out is chosen the\n"
439 " '--out' option must be given \n");
440 ret = MPATH_PR_SYNTAX_ERROR;
443 if (0 == num_prin_sa)
446 " No service action given for Persistent Reserve IN\n");
447 ret = MPATH_PR_SYNTAX_ERROR;
450 else if (num_prin_sa > 1)
452 fprintf (stderr, " Too many service actions given; choose "
454 ret = MPATH_PR_SYNTAX_ERROR;
460 if (batch_fn == NULL)
461 ret = MPATH_PR_SYNTAX_ERROR;
465 if ((param_rtp) && (MPATH_PROUT_REG_MOV_SA != prout_sa))
467 fprintf (stderr, " --relative-target-port"
468 " only useful with --register-move\n");
469 ret = MPATH_PR_SYNTAX_ERROR;
473 if (((MPATH_PROUT_RES_SA == prout_sa) ||
474 (MPATH_PROUT_REL_SA == prout_sa) ||
475 (MPATH_PROUT_PREE_SA == prout_sa) ||
476 (MPATH_PROUT_PREE_AB_SA == prout_sa)) &&
478 fprintf(stderr, "Warning: --prout-type probably needs to be "
481 if ((verbose > 2) && num_transportids)
483 fprintf (stderr, "number of tranport-ids decoded from "
484 "command line : %d\n", num_transportids);
487 if (device_name == NULL)
489 fprintf (stderr, "No device name given \n");
490 ret = MPATH_PR_SYNTAX_ERROR;
495 if ((fd = open (device_name, O_RDONLY)) < 0)
497 fprintf (stderr, "%s: error opening file (rw) fd=%d\n",
499 ret = MPATH_PR_FILE_ERROR;
506 resp = mpath_alloc_prin_response(prin_sa);
509 fprintf (stderr, "failed to allocate PRIN response buffer\n");
510 ret = MPATH_PR_OTHER;
514 ret = __mpath_persistent_reserve_in (fd, prin_sa, resp, noisy);
515 if (ret != MPATH_PR_SUCCESS )
517 fprintf (stderr, "Persistent Reserve IN command failed\n");
524 case MPATH_PRIN_RKEY_SA:
525 mpath_print_buf_readkeys(resp);
527 case MPATH_PRIN_RRES_SA:
528 mpath_print_buf_readresv(resp);
530 case MPATH_PRIN_RCAP_SA:
531 mpath_print_buf_readcap(resp);
533 case MPATH_PRIN_RFSTAT_SA:
534 mpath_print_buf_readfullstat(resp);
542 struct prout_param_descriptor *paramp;
544 paramp = alloc_prout_param_descriptor(num_transportids);
546 fprintf(stderr, "malloc paramp failed\n");
547 ret = MPATH_PR_OTHER;
551 for (j = 7; j >= 0; --j) {
552 paramp->key[j] = (param_rk & 0xff);
556 for (j = 7; j >= 0; --j) {
557 paramp->sa_key[j] = (param_sark & 0xff);
562 paramp->sa_flags |= MPATH_F_ALL_TG_PT_MASK;
564 paramp->sa_flags |= MPATH_F_APTPL_MASK;
566 if (num_transportids)
568 paramp->sa_flags |= MPATH_F_SPEC_I_PT_MASK;
569 paramp->num_transportid = num_transportids;
570 for (j = 0 ; j < num_transportids; j++)
572 paramp->trnptid_list[j] = (struct transportid *)malloc(sizeof(struct transportid));
573 if (!paramp->trnptid_list[j]) {
574 fprintf(stderr, "malloc paramp->trnptid_list[%d] failed.\n", j);
575 ret = MPATH_PR_OTHER;
576 free_prout_param_descriptor(paramp);
579 memcpy(paramp->trnptid_list[j], &transportids[j],sizeof(struct transportid));
583 /* PROUT commands other than 'register and move' */
584 ret = __mpath_persistent_reserve_out (fd, prout_sa, 0, prout_type,
586 free_prout_param_descriptor(paramp);
589 if (ret != MPATH_PR_SUCCESS)
593 case MPATH_PR_SENSE_UNIT_ATTENTION:
594 printf("persistent reserve out: scsi status: Unit Attention\n");
596 case MPATH_PR_RESERV_CONFLICT:
597 printf("persistent reserve out: scsi status: Reservation Conflict\n");
600 printf("PR out: command failed\n");
606 if (ret == MPATH_PR_SYNTAX_ERROR) {
611 fprintf(stderr, "syntax error on line %d in batch file\n",
613 } else if (batch_fn != NULL) {
614 int rv = do_batch_file(batch_fn);
617 ret = ret == 0 ? rv : ret;
620 mpath_persistent_reserve_free_vecs();
621 return (ret >= 0) ? ret : MPATH_PR_OTHER;
624 int main(int argc, char *argv[])
631 fprintf (stderr, "No parameter used\n");
638 fprintf (stderr, "need to be root\n");
642 if (libmpathpersist_init()) {
645 if (atexit((void(*)(void))libmpathpersist_exit))
646 fprintf(stderr, "failed to register cleanup handler for libmpathpersist: %m");
648 ret = handle_args(argc, argv, 0);
649 return (ret >= 0) ? ret : MPATH_PR_OTHER;
653 get_transportids_length(unsigned char * transportid_arr, int max_transportid, int num_transportids)
656 unsigned char * ucp = transportid_arr;
657 int k, off, protocol_id, len;
658 for (k = 0, off = 0; ((k < num_transportids) && (k < max_transportid));
659 ++k, off += MPATH_MX_TID_LEN) {
660 protocol_id = ucp[off] & 0xf;
661 if (5 == protocol_id) {
662 len = (ucp[off + 2] << 8) + ucp[off + 3] + 4;
665 if (off > compact_len)
666 memmove(ucp + compact_len, ucp + off, len);
670 if (off > compact_len)
671 memmove(ucp + compact_len, ucp + off, 24);
679 void mpath_print_buf_readkeys( struct prin_resp *pr_buff)
684 printf(" PR generation=0x%x, ", pr_buff->prin_descriptor.prin_readkeys.prgeneration);
686 num = pr_buff->prin_descriptor.prin_readkeys.additional_length / 8;
688 printf(" 0 registered reservation key.\n");
692 printf(" 1 registered reservation key follows:\n");
694 printf(" %d registered reservation keys follow:\n", num);
697 keyp = (unsigned char *)&pr_buff->prin_descriptor.prin_readkeys.key_list[0];
698 for (i = 0; i < num ; i++)
701 for (j = 0; j < 8; ++j) {
707 printf(" 0x%" PRIx64 "\n", prkey);
709 keyp = (unsigned char *)&pr_buff->prin_descriptor.prin_readkeys.key_list[k];
713 void mpath_print_buf_readresv( struct prin_resp *pr_buff)
715 int j, num, scope=0, type=0;
719 num = pr_buff->prin_descriptor.prin_readresv.additional_length / 8;
722 printf(" PR generation=0x%x, there is NO reservation held \n", pr_buff->prin_descriptor.prin_readresv.prgeneration);
726 printf(" PR generation=0x%x, Reservation follows:\n", pr_buff->prin_descriptor.prin_readresv.prgeneration);
727 keyp = (unsigned char *)&pr_buff->prin_descriptor.prin_readkeys.key_list[0];
729 for (j = 0; j < 8; ++j) {
735 printf(" Key = 0x%" PRIx64 "\n", prkey);
737 scope = (pr_buff->prin_descriptor.prin_readresv.scope_type >> 4) & 0x0f;
738 type = pr_buff->prin_descriptor.prin_readresv.scope_type & 0x0f;
741 printf(" scope = LU_SCOPE, type = %s", pr_type_strs[type]);
743 printf(" scope = %d, type = %s", scope, pr_type_strs[type]);
749 void mpath_print_buf_readcap( struct prin_resp *pr_buff)
751 if ( pr_buff->prin_descriptor.prin_readcap.length <= 2 ) {
752 fprintf(stderr, "Unexpected response for PRIN Report "
757 printf("Report capabilities response:\n");
759 printf(" Compatible Reservation Handling(CRH): %d\n", !!(pr_buff->prin_descriptor.prin_readcap.flags[0] & 0x10));
760 printf(" Specify Initiator Ports Capable(SIP_C): %d\n",!!(pr_buff->prin_descriptor.prin_readcap.flags[0] & 0x8));
761 printf(" All Target Ports Capable(ATP_C): %d\n",!!(pr_buff->prin_descriptor.prin_readcap.flags[0] & 0x4 ));
762 printf(" Persist Through Power Loss Capable(PTPL_C): %d\n",!!(pr_buff->prin_descriptor.prin_readcap.flags[0]));
763 printf(" Type Mask Valid(TMV): %d\n", !!(pr_buff->prin_descriptor.prin_readcap.flags[1] & 0x80));
764 printf(" Allow Commands: %d\n", !!(( pr_buff->prin_descriptor.prin_readcap.flags[1] >> 4) & 0x7));
765 printf(" Persist Through Power Loss Active(PTPL_A): %d\n",
766 !!(pr_buff->prin_descriptor.prin_readcap.flags[1] & 0x1));
768 if(pr_buff->prin_descriptor.prin_readcap.flags[1] & 0x80)
770 printf(" Support indicated in Type mask:\n");
772 printf(" %s: %d\n", pr_type_strs[7], pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x80);
773 printf(" %s: %d\n", pr_type_strs[6], pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x40);
774 printf(" %s: %d\n", pr_type_strs[5], pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x20);
775 printf(" %s: %d\n", pr_type_strs[3], pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x8);
776 printf(" %s: %d\n", pr_type_strs[1], pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x2);
777 printf(" %s: %d\n", pr_type_strs[8], pr_buff->prin_descriptor.prin_readcap.pr_type_mask & 0x100);
781 void mpath_print_buf_readfullstat( struct prin_resp *pr_buff)
786 uint16_t rel_pt_addr;
787 unsigned char * keyp;
789 num = pr_buff->prin_descriptor.prin_readfd.number_of_descriptor;
792 printf(" PR generation=0x%x \n", pr_buff->prin_descriptor.prin_readfd.prgeneration);
796 printf(" PR generation=0x%x \n", pr_buff->prin_descriptor.prin_readfd.prgeneration);
798 for (i = 0 ; i < num; i++)
800 keyp = (unsigned char *)&pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key;
803 for (j = 0; j < 8; ++j) {
809 printf(" Key = 0x%" PRIx64 "\n", prkey);
811 if (pr_buff->prin_descriptor.prin_readfd.descriptors[i]->flag & 0x02)
812 printf(" All target ports bit set\n");
814 printf(" All target ports bit clear\n");
816 rel_pt_addr = pr_buff->prin_descriptor.prin_readfd.descriptors[i]->rtpi;
817 printf(" Relative port address: 0x%x\n",
821 if (pr_buff->prin_descriptor.prin_readfd.descriptors[i]->flag & 0x1) {
822 printf(" << Reservation holder >>\n");
823 j = ((pr_buff->prin_descriptor.prin_readfd.descriptors[i]->scope_type >> 4) & 0xf);
825 printf(" scope: LU_SCOPE, ");
827 printf(" scope: %d ", j);
828 j = (pr_buff->prin_descriptor.prin_readfd.descriptors[i]->scope_type & 0xf);
829 printf(" type: %s\n", pr_type_strs[j]);
831 printf(" not reservation holder\n");
832 mpath_print_transport_id(pr_buff->prin_descriptor.prin_readfd.descriptors[i]);
836 static void usage(void)
838 fprintf(stderr, VERSION_STRING);
840 "Usage: mpathpersist [OPTIONS] [DEVICE]\n"
842 " --verbose|-v level verbosity level\n"
843 " 0 Critical messages\n"
844 " 1 Error messages\n"
845 " 2 Warning messages\n"
846 " 3 Informational messages\n"
847 " 4 Informational messages with trace enabled\n"
848 " --clear|-C PR Out: Clear\n"
849 " --device=DEVICE|-d DEVICE query or change DEVICE\n"
850 " --batch-file|-f FILE run commands from FILE\n"
851 " --help|-h output this usage message\n"
852 " --hex|-H output response in hex\n"
853 " --in|-i request PR In command \n"
854 " --out|-o request PR Out command\n"
855 " --param-alltgpt|-Y PR Out parameter 'ALL_TG_PT\n"
856 " --param-aptpl|-Z PR Out parameter 'APTPL'\n"
857 " --read-keys|-k PR In: Read Keys\n"
858 " --param-rk=RK|-K RK PR Out parameter reservation key\n"
859 " --param-sark=SARK|-S SARK PR Out parameter service action\n"
860 " reservation key (SARK is in hex)\n"
861 " --preempt|-P PR Out: Preempt\n"
862 " --preempt-abort|-A PR Out: Preempt and Abort\n"
863 " --prout-type=TYPE|-T TYPE PR Out command type\n"
864 " --read-full-status|-s PR In: Read Full Status\n"
865 " --read-keys|-k PR In: Read Keys\n"
866 " --read-reservation|-r PR In: Read Reservation\n"
867 " --register|-G PR Out: Register\n"
868 " --register-ignore|-I PR Out: Register and Ignore\n"
869 " --release|-L PR Out: Release\n"
870 " --report-capabilities|-c PR In: Report Capabilities\n"
871 " --reserve|-R PR Out: Reserve\n"
872 " --transport-id=TIDS|-X TIDS TransportIDs can be mentioned\n"
873 " in several forms\n"
874 " --alloc-length=LEN|-l LEN PR In: maximum allocation length\n");
878 mpath_print_transport_id(struct prin_fulldescr *fdesc)
880 switch (fdesc->trnptid.protocol_id) {
881 case MPATH_PROTOCOL_ID_FC:
883 if (0 != fdesc->trnptid.format_code)
884 printf(" [Unexpected format code: %d]\n",
885 fdesc->trnptid.format_code);
886 dumpHex((const char *)fdesc->trnptid.n_port_name, 8, 0);
888 case MPATH_PROTOCOL_ID_ISCSI:
890 if (0 == fdesc->trnptid.format_code) {
891 printf("name: %.*s\n", (int)sizeof(fdesc->trnptid.iscsi_name),
892 fdesc->trnptid.iscsi_name);
893 }else if (1 == fdesc->trnptid.format_code){
894 printf("world wide unique port id: %.*s\n",
895 (int)sizeof(fdesc->trnptid.iscsi_name),
896 fdesc->trnptid.iscsi_name);
898 printf(" [Unexpected format code: %d]\n", fdesc->trnptid.format_code);
899 dumpHex((const char *)fdesc->trnptid.iscsi_name,
900 (int)sizeof(fdesc->trnptid.iscsi_name), 0);
903 case MPATH_PROTOCOL_ID_SAS:
905 if (0 != fdesc->trnptid.format_code)
906 printf(" [Unexpected format code: %d]\n",
907 fdesc->trnptid.format_code);
908 dumpHex((const char *)fdesc->trnptid.sas_address, 8, 0);
916 construct_transportid(const char * lcp, struct transportid transid[], int num_transportids)
919 int j, n, b, c, len, alen;
923 if ((0 == memcmp("fcp,", lcp, 4)) ||
924 (0 == memcmp("FCP,", lcp, 4))) {
926 k = strspn(lcp, "0123456789aAbBcCdDeEfF");
930 fprintf(stderr, "badly formed symbolic FCP TransportID: %s\n",
934 transid[num_transportids].format_code = MPATH_PROTOCOL_ID_FC;
935 transid[num_transportids].protocol_id = MPATH_WWUI_DEVICE_NAME;
936 for (k = 0, j = 0, b = 0; k < 16; ++k) {
945 transid[num_transportids].n_port_name[j] = b | n;
952 if ((0 == memcmp("sas,", lcp, 4)) || (0 == memcmp("SAS,", lcp, 4))) {
954 k = strspn(lcp, "0123456789aAbBcCdDeEfF");
957 fprintf(stderr, "badly formed symbolic SAS TransportID: %s\n",
961 transid[num_transportids].format_code = MPATH_PROTOCOL_ID_SAS;
962 transid[num_transportids].protocol_id = MPATH_WWUI_DEVICE_NAME;
963 memcpy(&transid[num_transportids].sas_address, lcp, 8);
967 if (0 == memcmp("iqn.", lcp, 4)) {
968 ecp = strpbrk(lcp, " \t");
969 isip = strstr(lcp, ",i,0x");
970 if (ecp && (isip > ecp))
972 len = ecp ? (ecp - lcp) : (int)strlen(lcp);
973 transid[num_transportids].format_code = (isip ? MPATH_WWUI_PORT_IDENTIFIER:MPATH_WWUI_DEVICE_NAME);
974 transid[num_transportids].protocol_id = MPATH_PROTOCOL_ID_ISCSI;
975 alen = len + 1; /* at least one trailing null */
978 else if (0 != (alen % 4))
979 alen = ((alen / 4) + 1) * 4;
980 if (alen > 241) { /* sam5r02.pdf A.2 (Annex) */
981 fprintf(stderr, "iSCSI name too long, alen=%d\n", alen);
984 transid[num_transportids].iscsi_name[1] = alen & 0xff;
985 memcpy(&transid[num_transportids].iscsi_name[2], lcp, len);
989 if (k >= MPATH_MAX_PARAM_LEN) {
990 fprintf(stderr, "build_transportid: array length exceeded\n");