[tgt]accept_connection
不得不说一开始看这个代码我心里是想死的,基本没有注释, 动不动就用宏。还好受到伍哥点化,教了我看源代码的一招半式总算能理出来一点头绪,也算是没白看两天。
target和initiator之间要建立连接才能有之后的操作,accept_connection就是实现这个功能的。
1 static void accept_connection(int afd, int events, void *data) 2 { 3 struct sockaddr_storage from; 4 socklen_t namesize; 5 struct iscsi_connection *conn; 6 struct iscsi_tcp_connection *tcp_conn; 7 int fd, ret; 8 9 dprintf("%d\n", afd); 10 11 namesize = sizeof(from); 12 fd = accept(afd, (struct sockaddr *) &from, &namesize); 13 if (fd < 0) { 14 eprintf("can't accept, %m\n"); 15 return; 16 } 17 18 if (!is_system_available()) 19 goto out; 20 21 if (list_empty(&iscsi_targets_list)) 22 goto out; 23 24 ret = set_keepalive(fd); 25 if (ret) 26 goto out; 27 28 ret = set_nodelay(fd); 29 if (ret) 30 goto out; 31 32 tcp_conn = zalloc(sizeof(*tcp_conn)); 33 if (!tcp_conn) 34 goto out; 35 36 conn = &tcp_conn->iscsi_conn; 37 38 ret = conn_init(conn); 39 if (ret) { 40 free(tcp_conn); 41 goto out; 42 } 43 44 tcp_conn->fd = fd; 45 conn->tp = &iscsi_tcp; 46 47 conn_read_pdu(conn); 48 set_non_blocking(fd); 49 50 ret = tgt_event_add(fd, EPOLLIN, iscsi_tcp_event_handler, conn); 51 if (ret) { 52 conn_exit(conn); 53 free(tcp_conn); 54 goto out; 55 } 56 57 list_add(&tcp_conn->tcp_conn_siblings, &iscsi_tcp_conn_list); 58 59 return; 60 out: 61 close(fd); 62 return; 63 }
说是用来建立连接的,所以肯定就要accept了,返回一个fd, 然后就是检查各种状态以确保建立连接之后可以正常工作。比如系统是不是可用的,有没有target,对socket的一些设置。
接下来就是初始化 iscsi_tcp_conn ,iscsi_conn 两个结构体了,这两个结构体就是我们要的连接 ,
然后再登记一个iscsi_tcp_event_handler,毕竟之后要来处理传来的command。由于目前tgt支持两种driver 所以还要把iscsi_transport里的方法指向iscsi_tcp。
最后把连接放入iscsi_tcp_conn_list。