Deleted Added
full compact
fsm.c (185289) fsm.c (211095)
1/*-
1/*-
2 * Copyright (c) 2005-2008 Daniel Braniss <danny@cs.huji.ac.il>
2 * Copyright (c) 2005-2010 Daniel Braniss <danny@cs.huji.ac.il>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright

--- 14 unchanged lines hidden (view full) ---

25 *
26 */
27
28/*
29 | $Id: fsm.c,v 2.8 2007/05/19 16:34:21 danny Exp danny $
30 */
31
32#include <sys/cdefs.h>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright

--- 14 unchanged lines hidden (view full) ---

25 *
26 */
27
28/*
29 | $Id: fsm.c,v 2.8 2007/05/19 16:34:21 danny Exp danny $
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sbin/iscontrol/fsm.c 185289 2008-11-25 07:17:11Z scottl $");
33__FBSDID("$FreeBSD: head/sbin/iscontrol/fsm.c 211095 2010-08-09 12:36:36Z des $");
34
35#include <sys/param.h>
36#include <sys/types.h>
37#include <sys/socket.h>
38#include <sys/sysctl.h>
39
40#include <netinet/in.h>
41#include <netinet/tcp.h>

--- 9 unchanged lines hidden (view full) ---

51#include <string.h>
52#include <errno.h>
53#include <fcntl.h>
54#include <time.h>
55#include <syslog.h>
56#include <stdarg.h>
57#include <camlib.h>
58
34
35#include <sys/param.h>
36#include <sys/types.h>
37#include <sys/socket.h>
38#include <sys/sysctl.h>
39
40#include <netinet/in.h>
41#include <netinet/tcp.h>

--- 9 unchanged lines hidden (view full) ---

51#include <string.h>
52#include <errno.h>
53#include <fcntl.h>
54#include <time.h>
55#include <syslog.h>
56#include <stdarg.h>
57#include <camlib.h>
58
59#include "iscsi.h"
59#include <dev/iscsi/initiator/iscsi.h>
60#include "iscontrol.h"
61
62typedef enum {
63 T1 = 1,
64 T2, /*T3,*/ T4, T5, /*T6,*/ T7, T8, T9,
65 T10, T11, T12, T13, T14, T15, T16, T18
66} trans_t;
67

--- 26 unchanged lines hidden (view full) ---

94 if(sess->flags & SESS_REDIRECT) {
95 sess->redirect_cnt++;
96 sess->flags |= SESS_RECONNECT;
97 } else
98 sleep(2); // XXX: actually should be ?
99#ifdef notyet
100 {
101 time_t sec;
60#include "iscontrol.h"
61
62typedef enum {
63 T1 = 1,
64 T2, /*T3,*/ T4, T5, /*T6,*/ T7, T8, T9,
65 T10, T11, T12, T13, T14, T15, T16, T18
66} trans_t;
67

--- 26 unchanged lines hidden (view full) ---

94 if(sess->flags & SESS_REDIRECT) {
95 sess->redirect_cnt++;
96 sess->flags |= SESS_RECONNECT;
97 } else
98 sleep(2); // XXX: actually should be ?
99#ifdef notyet
100 {
101 time_t sec;
102 // make sure we are not in a loop
103 // XXX: this code has to be tested
104 sec = time(0) - sess->reconnect_time;
105 if(sec > (5*60)) {
106 // if we've been connected for more that 5 minutes
107 // then just reconnect
108 sess->reconnect_time = sec;
109 sess->reconnect_cnt1 = 0;
110 }
111 else {
112 //
113 sess->reconnect_cnt1++;
114 if((sec / sess->reconnect_cnt1) < 2) {
115 // if less that 2 seconds from the last reconnect
116 // we are most probably looping
117 syslog(LOG_CRIT, "too many reconnects %d", sess->reconnect_cnt1);
118 return 0;
102 // make sure we are not in a loop
103 // XXX: this code has to be tested
104 sec = time(0) - sess->reconnect_time;
105 if(sec > (5*60)) {
106 // if we've been connected for more that 5 minutes
107 // then just reconnect
108 sess->reconnect_time = sec;
109 sess->reconnect_cnt1 = 0;
119 }
110 }
111 else {
112 //
113 sess->reconnect_cnt1++;
114 if((sec / sess->reconnect_cnt1) < 2) {
115 // if less that 2 seconds from the last reconnect
116 // we are most probably looping
117 syslog(LOG_CRIT, "too many reconnects %d", sess->reconnect_cnt1);
118 return 0;
119 }
120 }
120 }
121 }
121 }
122#endif
123 sess->reconnect_cnt++;
124 }
125
126 snprintf(pbuf, sizeof(pbuf), "%d", op->port);
127 memset(&hints, 0, sizeof(hints));
128 hints.ai_family = PF_UNSPEC;
129 hints.ai_socktype = SOCK_STREAM;

--- 5 unchanged lines hidden (view full) ---

135 sess->flags &= ~SESS_CONNECTED;
136 sv_errno = 0;
137 soc = -1;
138 for(res = res0; res; res = res->ai_next) {
139 soc = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
140 if (soc == -1)
141 continue;
142
122#endif
123 sess->reconnect_cnt++;
124 }
125
126 snprintf(pbuf, sizeof(pbuf), "%d", op->port);
127 memset(&hints, 0, sizeof(hints));
128 hints.ai_family = PF_UNSPEC;
129 hints.ai_socktype = SOCK_STREAM;

--- 5 unchanged lines hidden (view full) ---

135 sess->flags &= ~SESS_CONNECTED;
136 sv_errno = 0;
137 soc = -1;
138 for(res = res0; res; res = res->ai_next) {
139 soc = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
140 if (soc == -1)
141 continue;
142
143 // from Patrick.Guelat@imp.ch:
144 // iscontrol can be called without waiting for the socket entry to time out
145 val = 1;
143 // from Patrick.Guelat@imp.ch:
144 // iscontrol can be called without waiting for the socket entry to time out
145 val = 1;
146 if(setsockopt(soc, SOL_SOCKET, SO_REUSEADDR, &val, (socklen_t)sizeof(val)) < 0) {
146 if(setsockopt(soc, SOL_SOCKET, SO_REUSEADDR, &val, (socklen_t)sizeof(val)) < 0) {
147 fprintf(stderr, "Cannot set socket SO_REUSEADDR %d: %s\n\n",
148 errno, strerror(errno));
149 }
147 fprintf(stderr, "Cannot set socket SO_REUSEADDR %d: %s\n\n",
148 errno, strerror(errno));
149 }
150
151 if(connect(soc, res->ai_addr, res->ai_addrlen) == 0)
152 break;
153 sv_errno = errno;
154 close(soc);
155 soc = -1;
156 }
157 freeaddrinfo(res0);

--- 33 unchanged lines hidden (view full) ---

191 || (setsockopt(sess->soc, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) < 0)) {
192 fprintf(stderr, "Cannot set socket sndbuf & rcvbuf to %d err=%d %s\n",
193 val, errno, strerror(errno));
194 return 0;
195 }
196 }
197 sess->flags |= SESS_CONNECTED;
198 return T1;
150
151 if(connect(soc, res->ai_addr, res->ai_addrlen) == 0)
152 break;
153 sv_errno = errno;
154 close(soc);
155 soc = -1;
156 }
157 freeaddrinfo(res0);

--- 33 unchanged lines hidden (view full) ---

191 || (setsockopt(sess->soc, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) < 0)) {
192 fprintf(stderr, "Cannot set socket sndbuf & rcvbuf to %d err=%d %s\n",
193 val, errno, strerror(errno));
194 return 0;
195 }
196 }
197 sess->flags |= SESS_CONNECTED;
198 return T1;
199 }
199 }
200
201 fprintf(stderr, "errno=%d\n", sv_errno);
202 perror("connect");
203 switch(sv_errno) {
204 case ECONNREFUSED:
205 case ENETUNREACH:
206 case ETIMEDOUT:
207 if((sess->flags & SESS_REDIRECT) == 0) {

--- 76 unchanged lines hidden (view full) ---

284 if(fd < 0) {
285 perror(iscsidev);
286 return 0;
287 }
288 {
289 // XXX: this has to go
290 size_t n;
291 n = sizeof(sess->isid);
200
201 fprintf(stderr, "errno=%d\n", sv_errno);
202 perror("connect");
203 switch(sv_errno) {
204 case ECONNREFUSED:
205 case ENETUNREACH:
206 case ETIMEDOUT:
207 if((sess->flags & SESS_REDIRECT) == 0) {

--- 76 unchanged lines hidden (view full) ---

284 if(fd < 0) {
285 perror(iscsidev);
286 return 0;
287 }
288 {
289 // XXX: this has to go
290 size_t n;
291 n = sizeof(sess->isid);
292 if(sysctlbyname("net.iscsi.isid", (void *)sess->isid, (size_t *)&n, 0, 0) != 0)
292 if(sysctlbyname("net.iscsi_initiator.isid", (void *)sess->isid, (size_t *)&n, 0, 0) != 0)
293 perror("sysctlbyname");
294 }
295 if(ioctl(fd, ISCSISETSES, &n)) {
296 perror("ISCSISETSES");
297 return 0;
298 }
299 asprintf(&dev, "%s%d", iscsidev, n);
300 nfd = open(dev, O_RDWR);

--- 37 unchanged lines hidden (view full) ---

338
339 case SIGINT:
340 case SIGTERM:
341 default:
342 return; // ignore
343 }
344}
345
293 perror("sysctlbyname");
294 }
295 if(ioctl(fd, ISCSISETSES, &n)) {
296 perror("ISCSISETSES");
297 return 0;
298 }
299 asprintf(&dev, "%s%d", iscsidev, n);
300 nfd = open(dev, O_RDWR);

--- 37 unchanged lines hidden (view full) ---

338
339 case SIGINT:
340 case SIGTERM:
341 default:
342 return; // ignore
343 }
344}
345
346static void
346static int
347doCAM(isess_t *sess)
348{
349 char pathstr[1024];
350 union ccb *ccb;
347doCAM(isess_t *sess)
348{
349 char pathstr[1024];
350 union ccb *ccb;
351 int i;
351 int i, n;
352
353 if(ioctl(sess->fd, ISCSIGETCAM, &sess->cam) != 0) {
354 syslog(LOG_WARNING, "ISCSIGETCAM failed: %d", errno);
352
353 if(ioctl(sess->fd, ISCSIGETCAM, &sess->cam) != 0) {
354 syslog(LOG_WARNING, "ISCSIGETCAM failed: %d", errno);
355 return;
355 return 0;
356 }
356 }
357 debug(2, "nluns=%d", sess->cam.target_nluns);
357 debug(1, "nluns=%d", sess->cam.target_nluns);
358 /*
359 | for now will do this for each lun ...
360 */
358 /*
359 | for now will do this for each lun ...
360 */
361 for(i = 0; i < sess->cam.target_nluns; i++) {
361 for(n = i = 0; i < sess->cam.target_nluns; i++) {
362 debug(2, "CAM path_id=%d target_id=%d target_lun=%d",
363 sess->cam.path_id, sess->cam.target_id, sess->cam.target_lun[i]);
364
365 sess->camdev = cam_open_btl(sess->cam.path_id, sess->cam.target_id,
362 debug(2, "CAM path_id=%d target_id=%d target_lun=%d",
363 sess->cam.path_id, sess->cam.target_id, sess->cam.target_lun[i]);
364
365 sess->camdev = cam_open_btl(sess->cam.path_id, sess->cam.target_id,
366 sess->cam.target_lun[i], O_RDWR, NULL);
366 i, O_RDWR, NULL);
367 if(sess->camdev == NULL) {
367 if(sess->camdev == NULL) {
368 syslog(LOG_WARNING, "%s", cam_errbuf);
368 //syslog(LOG_WARNING, "%s", cam_errbuf);
369 debug(3, "%s", cam_errbuf);
370 continue;
371 }
372
373 cam_path_string(sess->camdev, pathstr, sizeof(pathstr));
374 debug(2, "pathstr=%s", pathstr);
375
376 ccb = cam_getccb(sess->camdev);
377 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
378 ccb->ccb_h.func_code = XPT_REL_SIMQ;
379 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
380 ccb->crs.openings = sess->op->tags;
369 debug(3, "%s", cam_errbuf);
370 continue;
371 }
372
373 cam_path_string(sess->camdev, pathstr, sizeof(pathstr));
374 debug(2, "pathstr=%s", pathstr);
375
376 ccb = cam_getccb(sess->camdev);
377 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr));
378 ccb->ccb_h.func_code = XPT_REL_SIMQ;
379 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
380 ccb->crs.openings = sess->op->tags;
381
382 if(cam_send_ccb(sess->camdev, ccb) < 0)
381 if(cam_send_ccb(sess->camdev, ccb) < 0)
383 syslog(LOG_WARNING, "%s", cam_errbuf);
382 debug(2, "%s", cam_errbuf);
384 else
385 if((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
386 syslog(LOG_WARNING, "XPT_REL_SIMQ CCB failed");
387 // cam_error_print(sess->camdev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
388 }
383 else
384 if((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
385 syslog(LOG_WARNING, "XPT_REL_SIMQ CCB failed");
386 // cam_error_print(sess->camdev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
387 }
389 else
388 else {
389 n++;
390 syslog(LOG_INFO, "%s tagged openings now %d\n", pathstr, ccb->crs.openings);
390 syslog(LOG_INFO, "%s tagged openings now %d\n", pathstr, ccb->crs.openings);
391
391 }
392 cam_freeccb(ccb);
393 cam_close_device(sess->camdev);
394 }
392 cam_freeccb(ccb);
393 cam_close_device(sess->camdev);
394 }
395 return n;
395}
396
397static trans_t
398supervise(isess_t *sess)
399{
400 int sig, val;
401
402 debug_called(3);

--- 9 unchanged lines hidden (view full) ---

412 if(setOptions(sess, SESS_FULLFEATURE) != 0)
413 return 0; // failure
414
415 if((sess->flags & SESS_FULLFEATURE) == 0) {
416 if(daemon(0, 1) != 0) {
417 perror("daemon");
418 exit(1);
419 }
396}
397
398static trans_t
399supervise(isess_t *sess)
400{
401 int sig, val;
402
403 debug_called(3);

--- 9 unchanged lines hidden (view full) ---

413 if(setOptions(sess, SESS_FULLFEATURE) != 0)
414 return 0; // failure
415
416 if((sess->flags & SESS_FULLFEATURE) == 0) {
417 if(daemon(0, 1) != 0) {
418 perror("daemon");
419 exit(1);
420 }
421 if(sess->op->pidfile != NULL) {
422 FILE *pidf;
420
423
424 pidf = fopen(sess->op->pidfile, "w");
425 if(pidf != NULL) {
426 fprintf(pidf, "%d\n", getpid());
427 fclose(pidf);
428 }
429 }
421 openlog("iscontrol", LOG_CONS|LOG_PERROR|LOG_PID|LOG_NDELAY, LOG_KERN);
422 syslog(LOG_INFO, "running");
423
424 currsess = sess;
425 if(ioctl(sess->fd, ISCSISTART)) {
426 perror("ISCSISTART");
427 return -1;
428 }
430 openlog("iscontrol", LOG_CONS|LOG_PERROR|LOG_PID|LOG_NDELAY, LOG_KERN);
431 syslog(LOG_INFO, "running");
432
433 currsess = sess;
434 if(ioctl(sess->fd, ISCSISTART)) {
435 perror("ISCSISTART");
436 return -1;
437 }
429 doCAM(sess);
438 if(doCAM(sess) == 0) {
439 syslog(LOG_WARNING, "no device found");
440 ioctl(sess->fd, ISCSISTOP);
441 return T15;
442 }
430
431 }
432 else {
433 if(ioctl(sess->fd, ISCSIRESTART)) {
434 perror("ISCSIRESTART");
435 return -1;
436 }
437 }

--- 6 unchanged lines hidden (view full) ---

444 signal(sig, trap);
445 if(ioctl(sess->fd, ISCSISIGNAL, &sig)) {
446 perror("ISCSISIGNAL");
447 return -1;
448 }
449 sess->flags |= SESS_FULLFEATURE;
450
451 sess->flags &= ~(SESS_REDIRECT | SESS_RECONNECT);
443
444 }
445 else {
446 if(ioctl(sess->fd, ISCSIRESTART)) {
447 perror("ISCSIRESTART");
448 return -1;
449 }
450 }

--- 6 unchanged lines hidden (view full) ---

457 signal(sig, trap);
458 if(ioctl(sess->fd, ISCSISIGNAL, &sig)) {
459 perror("ISCSISIGNAL");
460 return -1;
461 }
462 sess->flags |= SESS_FULLFEATURE;
463
464 sess->flags &= ~(SESS_REDIRECT | SESS_RECONNECT);
452 printf("iscontrol: supervise starting main loop\n");
465 if(vflag)
466 printf("iscontrol: supervise starting main loop\n");
453 /*
454 | the main loop - actually do nothing
455 | all the work is done inside the kernel
456 */
457 while((sess->flags & (SESS_REDIRECT|SESS_RECONNECT|SESS_DISCONNECT)) == 0) {
458 // do something?
459 // like sending a nop_out?
460 sleep(60);
461 }
462 printf("iscontrol: supervise going down\n");
463 syslog(LOG_INFO, "sess flags=%x", sess->flags);
464
465 sig = 0;
466 if(ioctl(sess->fd, ISCSISIGNAL, &sig)) {
467 perror("ISCSISIGNAL");
468 }
469
470 if(sess->flags & SESS_DISCONNECT) {
467 /*
468 | the main loop - actually do nothing
469 | all the work is done inside the kernel
470 */
471 while((sess->flags & (SESS_REDIRECT|SESS_RECONNECT|SESS_DISCONNECT)) == 0) {
472 // do something?
473 // like sending a nop_out?
474 sleep(60);
475 }
476 printf("iscontrol: supervise going down\n");
477 syslog(LOG_INFO, "sess flags=%x", sess->flags);
478
479 sig = 0;
480 if(ioctl(sess->fd, ISCSISIGNAL, &sig)) {
481 perror("ISCSISIGNAL");
482 }
483
484 if(sess->flags & SESS_DISCONNECT) {
471 val = 0;
472 if(ioctl(sess->fd, ISCSISTOP, &val)) {
473 perror("ISCSISTOP");
474 }
475 sess->flags &= ~SESS_FULLFEATURE;
476 return T9;
477 }
478 else {
485 sess->flags &= ~SESS_FULLFEATURE;
486 return T9;
487 }
488 else {
489 val = 0;
490 if(ioctl(sess->fd, ISCSISTOP, &val)) {
491 perror("ISCSISTOP");
492 }
479 sess->flags |= SESS_INITIALLOGIN1;
480 }
481 return T8;
482}
483
484static int
485handledDiscoveryResp(isess_t *sess, pdu_t *pp)
486{
487 u_char *ptr;
488 int len, n;
489
490 debug_called(3);
491
492 len = pp->ds_len;
493 sess->flags |= SESS_INITIALLOGIN1;
494 }
495 return T8;
496}
497
498static int
499handledDiscoveryResp(isess_t *sess, pdu_t *pp)
500{
501 u_char *ptr;
502 int len, n;
503
504 debug_called(3);
505
506 len = pp->ds_len;
493 ptr = pp->ds;
507 ptr = pp->ds_addr;
494 while(len > 0) {
495 if(*ptr != 0)
496 printf("%s\n", ptr);
497 n = strlen((char *)ptr) + 1;
498 len -= n;
499 ptr += n;
500 }
501 return 0;

--- 72 unchanged lines hidden (view full) ---

574 default:
575 return 0;
576 }
577}
578
579static int
580handleLogoutResp(isess_t *sess, pdu_t *pp)
581{
508 while(len > 0) {
509 if(*ptr != 0)
510 printf("%s\n", ptr);
511 n = strlen((char *)ptr) + 1;
512 len -= n;
513 ptr += n;
514 }
515 return 0;

--- 72 unchanged lines hidden (view full) ---

588 default:
589 return 0;
590 }
591}
592
593static int
594handleLogoutResp(isess_t *sess, pdu_t *pp)
595{
582 if(sess->flags & SESS_DISCONNECT)
596 if(sess->flags & SESS_DISCONNECT) {
597 int val = 0;
598 if(ioctl(sess->fd, ISCSISTOP, &val)) {
599 perror("ISCSISTOP");
600 }
583 return 0;
601 return 0;
602 }
584 return T13;
585}
586
587static trans_t
588startLogout(isess_t *sess)
589{
590 pdu_t spp;
591 logout_req_t *p = (logout_req_t *)&spp.ipdu.bhs;

--- 13 unchanged lines hidden (view full) ---

605 return T18;
606 return 0;
607}
608
609typedef enum {
610 S1, S2, /*S3,*/ S4, S5, S6, S7, S8
611} state_t;
612
603 return T13;
604}
605
606static trans_t
607startLogout(isess_t *sess)
608{
609 pdu_t spp;
610 logout_req_t *p = (logout_req_t *)&spp.ipdu.bhs;

--- 13 unchanged lines hidden (view full) ---

624 return T18;
625 return 0;
626}
627
628typedef enum {
629 S1, S2, /*S3,*/ S4, S5, S6, S7, S8
630} state_t;
631
613#if 0
632/**
614 S1: FREE
615 S2: XPT_WAIT
616 S4: IN_LOGIN
617 S5: LOGGED_IN
618 S6: IN_LOGOUT
619 S7: LOGOUT_REQUESTED
620 S8: CLEANUP_WAIT
621

--- 25 unchanged lines hidden (view full) ---

647 | | | / / -+----- -------
648 | | | / /T11 |T10 / S8 \
649 | | V / / V +----+ \ /
650 | | ---+-+- ----+-- | -------
651 | | / S5 \T9 / S6 \<+ ^
652 | +-----\ /--->\ / T14 |
653 | ------- --+----+------+T17
654 +---------------------------+
633 S1: FREE
634 S2: XPT_WAIT
635 S4: IN_LOGIN
636 S5: LOGGED_IN
637 S6: IN_LOGOUT
638 S7: LOGOUT_REQUESTED
639 S8: CLEANUP_WAIT
640

--- 25 unchanged lines hidden (view full) ---

666 | | | / / -+----- -------
667 | | | / /T11 |T10 / S8 \
668 | | V / / V +----+ \ /
669 | | ---+-+- ----+-- | -------
670 | | / S5 \T9 / S6 \<+ ^
671 | +-----\ /--->\ / T14 |
672 | ------- --+----+------+T17
673 +---------------------------+
655#endif
674*/
656
657int
658fsm(isc_opt_t *op)
659{
660 state_t state;
661 isess_t *sess;
662
663 if((sess = calloc(1, sizeof(isess_t))) == NULL) {

--- 77 unchanged lines hidden ---
675
676int
677fsm(isc_opt_t *op)
678{
679 state_t state;
680 isess_t *sess;
681
682 if((sess = calloc(1, sizeof(isess_t))) == NULL) {

--- 77 unchanged lines hidden ---