+ add support for IPv6 in the target (CIDR scoping has still to be
implemented for IPv6, but works fine for IPv4) + now poll any connections opened in the target. select is used if poll is not available + remove ramdisk type of backing store, since it was never used, and is of no use for our needs + bump version to 20060727
This commit is contained in:
parent
a6fd778155
commit
66644e0749
5
dist/iscsi/include/conffile.h
vendored
5
dist/iscsi/include/conffile.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: conffile.h,v 1.2 2006/03/20 20:25:42 agc Exp $ */
|
||||
/* $NetBSD: conffile.h,v 1.3 2006/08/03 20:21:59 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright © 2006 Alistair Crooks. All rights reserved.
|
||||
@ -34,6 +34,9 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
DEFINE_ARRAY(strv_t, char *);
|
||||
|
19
dist/iscsi/include/config.h
vendored
19
dist/iscsi/include/config.h
vendored
@ -34,6 +34,12 @@
|
||||
/* Define to 1 if you have the `fsync_range' function. */
|
||||
#define HAVE_FSYNC_RANGE 1
|
||||
|
||||
/* Define to 1 if you have the `getaddrinfo' function. */
|
||||
#define HAVE_GETADDRINFO 1
|
||||
|
||||
/* Define to 1 if you have the `getnameinfo' function. */
|
||||
#define HAVE_GETNAMEINFO 1
|
||||
|
||||
/* Define to 1 if you have the `htobe64' function. */
|
||||
/* #undef HAVE_HTOBE64 */
|
||||
|
||||
@ -70,6 +76,12 @@
|
||||
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
||||
#define HAVE_NETINET_TCP_H 1
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#define HAVE_POLL 1
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#define HAVE_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file. */
|
||||
#define HAVE_PTHREAD_H 1
|
||||
|
||||
@ -124,6 +136,9 @@
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
@ -179,13 +194,13 @@
|
||||
#define PACKAGE_NAME "netbsd-iscsi"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "netbsd-iscsi 20060529"
|
||||
#define PACKAGE_STRING "netbsd-iscsi 20060727"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "netbsd-iscsi"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "20060529"
|
||||
#define PACKAGE_VERSION "20060727"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
15
dist/iscsi/include/config.h.in
vendored
15
dist/iscsi/include/config.h.in
vendored
@ -33,6 +33,12 @@
|
||||
/* Define to 1 if you have the `fsync_range' function. */
|
||||
#undef HAVE_FSYNC_RANGE
|
||||
|
||||
/* Define to 1 if you have the `getaddrinfo' function. */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
||||
/* Define to 1 if you have the `getnameinfo' function. */
|
||||
#undef HAVE_GETNAMEINFO
|
||||
|
||||
/* Define to 1 if you have the `htobe64' function. */
|
||||
#undef HAVE_HTOBE64
|
||||
|
||||
@ -69,6 +75,12 @@
|
||||
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
||||
#undef HAVE_NETINET_TCP_H
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#undef HAVE_POLL_H
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file. */
|
||||
#undef HAVE_PTHREAD_H
|
||||
|
||||
@ -123,6 +135,9 @@
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
|
||||
|
8
dist/iscsi/include/initiator.h
vendored
8
dist/iscsi/include/initiator.h
vendored
@ -116,11 +116,17 @@ typedef struct iscsi_target_t {
|
||||
|
||||
DEFINE_ARRAY(strv_t, char *);
|
||||
|
||||
enum {
|
||||
ISCSI_IPv4 = AF_INET,
|
||||
ISCSI_IPv6 = AF_INET6,
|
||||
ISCSI_UNSPEC = PF_UNSPEC
|
||||
};
|
||||
|
||||
/**********
|
||||
* Public *
|
||||
**********/
|
||||
|
||||
int initiator_init(const char *, const char *, int, int, int);
|
||||
int initiator_init(const char *, int, const char *, int, int, int);
|
||||
int initiator_info(char *, int, int);
|
||||
int initiator_command(initiator_cmd_t *);
|
||||
int initiator_enqueue(initiator_cmd_t *);
|
||||
|
17
dist/iscsi/include/target.h
vendored
17
dist/iscsi/include/target.h
vendored
@ -51,9 +51,13 @@
|
||||
enum {
|
||||
MAX_TGT_NAME_SIZE = 512,
|
||||
MAX_INITIATOR_ADDRESS_SIZE = 256,
|
||||
MAX_CONFIG_FILE_NAME = 512,
|
||||
|
||||
ISCSI_IPv4 = 4,
|
||||
ISCSI_IPv6 = 6
|
||||
ISCSI_IPv4 = AF_INET,
|
||||
ISCSI_IPv6 = AF_INET6,
|
||||
ISCSI_UNSPEC = PF_UNSPEC,
|
||||
|
||||
MAXSOCK = 8
|
||||
};
|
||||
|
||||
/* global variables, moved from target.c */
|
||||
@ -61,15 +65,20 @@ typedef struct globals_t {
|
||||
char targetname[MAX_TGT_NAME_SIZE]; /* name of target */
|
||||
uint16_t port; /* target port */
|
||||
iscsi_socket_t sock; /* socket on which it's listening */
|
||||
int sockc; /* # of live sockets on which it's listening */
|
||||
iscsi_socket_t sockv[MAXSOCK]; /* sockets on which it's listening */
|
||||
int famv[MAXSOCK]; /* address families */
|
||||
int state; /* current state of target */
|
||||
int listener_pid; /* PID on which it's listening */
|
||||
volatile int listener_listening; /* whether a listener is listening */
|
||||
char targetaddress[MAX_TGT_NAME_SIZE]; /* iSCSI TargetAddress set after iscsi_sock_accept() */
|
||||
targv_t *tv; /* array of target devices */
|
||||
int address_family; /* IP address family */
|
||||
int address_family; /* global default IP address family */
|
||||
int max_sessions; /* maximum number of sessions */
|
||||
char config_file[MAX_CONFIG_FILE_NAME]; /* config file name */
|
||||
} globals_t;
|
||||
|
||||
/* session parameters */
|
||||
typedef struct target_session_t {
|
||||
int id;
|
||||
int d;
|
||||
@ -91,7 +100,7 @@ typedef struct target_session_t {
|
||||
iscsi_sess_param_t sess_params;
|
||||
char initiator[MAX_INITIATOR_ADDRESS_SIZE];
|
||||
int address_family;
|
||||
} target_session_t;
|
||||
} target_session_t;
|
||||
|
||||
typedef struct target_cmd_t {
|
||||
iscsi_scsi_cmd_args_t *scsi_cmd;
|
||||
|
4
dist/iscsi/include/util.h
vendored
4
dist/iscsi/include/util.h
vendored
@ -70,7 +70,6 @@
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
@ -293,6 +292,9 @@ typedef int iscsi_socket_t;
|
||||
#define ISCSI_SOCK_MSG_BYTE_ALIGN 4
|
||||
|
||||
int iscsi_sock_create(iscsi_socket_t * );
|
||||
int iscsi_socks_establish(iscsi_socket_t *, int *, int *, int);
|
||||
int iscsi_waitfor_connection(iscsi_socket_t *, int, const char *cf, iscsi_socket_t *);
|
||||
const char *iscsi_address_family(int);
|
||||
int iscsi_sock_setsockopt(iscsi_socket_t * , int , int , void *, unsigned );
|
||||
int iscsi_sock_getsockopt(iscsi_socket_t * , int , int , void *, unsigned *);
|
||||
int iscsi_sock_bind(iscsi_socket_t , int );
|
||||
|
14
dist/iscsi/src/TODO
vendored
14
dist/iscsi/src/TODO
vendored
@ -1,7 +1,15 @@
|
||||
To do
|
||||
=====
|
||||
cmdline fs or fsmmap
|
||||
add kevent
|
||||
add HUP support to read sig and targets file
|
||||
CRC/digests
|
||||
finish reservations
|
||||
VPD 80 handling
|
||||
RAID 1 rebuilding, breaking etc
|
||||
bind to cmdline port properly now too
|
||||
proper allow_netmask support for IPv6
|
||||
add ability to add a target in, take one out (if !busy)
|
||||
proper IPv6 support in harness
|
||||
|
||||
Done
|
||||
====
|
||||
@ -35,3 +43,7 @@ add uuid
|
||||
Solaris initiator compatibility
|
||||
fix 64-byte swapping macros
|
||||
add reservations - RESERVE_6 and RELEASE_6 done
|
||||
pass addr family in sess structure
|
||||
add poll configure glue
|
||||
use poll if we have it
|
||||
proper IPv6 support in target
|
||||
|
3
dist/iscsi/src/conffile.c
vendored
3
dist/iscsi/src/conffile.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: conffile.c,v 1.3 2006/05/13 22:50:24 christos Exp $ */
|
||||
/* $NetBSD: conffile.c,v 1.4 2006/08/03 20:21:59 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright © 2006 Alistair Crooks. All rights reserved.
|
||||
@ -29,6 +29,7 @@
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
29
dist/iscsi/src/configure
vendored
29
dist/iscsi/src/configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.59 for netbsd-iscsi 20060529.
|
||||
# Generated by GNU Autoconf 2.59 for netbsd-iscsi 20060727.
|
||||
#
|
||||
# Report bugs to <Alistair Crooks <agc@NetBSD.org>>.
|
||||
#
|
||||
@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='netbsd-iscsi'
|
||||
PACKAGE_TARNAME='netbsd-iscsi'
|
||||
PACKAGE_VERSION='20060529'
|
||||
PACKAGE_STRING='netbsd-iscsi 20060529'
|
||||
PACKAGE_VERSION='20060727'
|
||||
PACKAGE_STRING='netbsd-iscsi 20060727'
|
||||
PACKAGE_BUGREPORT='Alistair Crooks <agc@NetBSD.org>'
|
||||
|
||||
ac_unique_file="iscsi.c"
|
||||
@ -780,7 +780,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures netbsd-iscsi 20060529 to adapt to many kinds of systems.
|
||||
\`configure' configures netbsd-iscsi 20060727 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -837,7 +837,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of netbsd-iscsi 20060529:";;
|
||||
short | recursive ) echo "Configuration of netbsd-iscsi 20060727:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -949,7 +949,7 @@ fi
|
||||
test -n "$ac_init_help" && exit 0
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
netbsd-iscsi configure 20060529
|
||||
netbsd-iscsi configure 20060727
|
||||
generated by GNU Autoconf 2.59
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
@ -963,7 +963,7 @@ cat >&5 <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by netbsd-iscsi $as_me 20060529, which was
|
||||
It was created by netbsd-iscsi $as_me 20060727, which was
|
||||
generated by GNU Autoconf 2.59. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -3069,7 +3069,8 @@ done
|
||||
|
||||
|
||||
|
||||
for ac_header in arpa/inet.h netinet/in.h netinet/tcp.h netdb.h
|
||||
|
||||
for ac_header in arpa/inet.h netinet/in.h netinet/tcp.h netdb.h poll.h
|
||||
do
|
||||
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
if eval "test \"\${$as_ac_Header+set}\" = set"; then
|
||||
@ -3224,7 +3225,8 @@ done
|
||||
|
||||
|
||||
|
||||
for ac_header in asm/byteorder.h sys/bswap.h sys/byteorder.h libkern/OSByteOrder.h byteswap.h machine/endian.h
|
||||
|
||||
for ac_header in asm/byteorder.h sys/bswap.h sys/byteorder.h sys/select.h libkern/OSByteOrder.h byteswap.h machine/endian.h
|
||||
do
|
||||
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
if eval "test \"\${$as_ac_Header+set}\" = set"; then
|
||||
@ -4159,7 +4161,10 @@ fi
|
||||
|
||||
|
||||
|
||||
for ac_func in __bswap64 asprintf asnprintf bswap64 daemon htobe64 fsync_range snprintf strlcpy strtoll syslog uuid_create uuid_to_string vasprintf vasnprintf vsnprintf
|
||||
|
||||
|
||||
|
||||
for ac_func in __bswap64 asprintf asnprintf bswap64 daemon fsync_range getaddrinfo getnameinfo htobe64 poll snprintf strlcpy strtoll syslog uuid_create uuid_to_string vasprintf vasnprintf vsnprintf
|
||||
do
|
||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
@ -4624,7 +4629,7 @@ _ASBOX
|
||||
} >&5
|
||||
cat >&5 <<_CSEOF
|
||||
|
||||
This file was extended by netbsd-iscsi $as_me 20060529, which was
|
||||
This file was extended by netbsd-iscsi $as_me 20060727, which was
|
||||
generated by GNU Autoconf 2.59. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -4684,7 +4689,7 @@ _ACEOF
|
||||
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
ac_cs_version="\\
|
||||
netbsd-iscsi config.status 20060529
|
||||
netbsd-iscsi config.status 20060727
|
||||
configured by $0, generated by GNU Autoconf 2.59,
|
||||
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
8
dist/iscsi/src/configure.ac
vendored
8
dist/iscsi/src/configure.ac
vendored
@ -1,6 +1,6 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([netbsd-iscsi],[20060529],[Alistair Crooks <agc@NetBSD.org>])
|
||||
AC_INIT([netbsd-iscsi],[20060727],[Alistair Crooks <agc@NetBSD.org>])
|
||||
AC_CONFIG_SRCDIR([iscsi.c])
|
||||
AC_CONFIG_HEADER(../include/config.h)
|
||||
|
||||
@ -12,8 +12,8 @@ AC_PROG_RANLIB
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(sys/types.h sys/param.h sys/stat.h sys/time.h sys/mman.h sys/uio.h sys/socket.h sys/time.h sys/vfs.h)
|
||||
AC_CHECK_HEADERS(arpa/inet.h netinet/in.h netinet/tcp.h netdb.h)
|
||||
AC_CHECK_HEADERS(asm/byteorder.h sys/bswap.h sys/byteorder.h libkern/OSByteOrder.h byteswap.h machine/endian.h)
|
||||
AC_CHECK_HEADERS(arpa/inet.h netinet/in.h netinet/tcp.h netdb.h poll.h)
|
||||
AC_CHECK_HEADERS(asm/byteorder.h sys/bswap.h sys/byteorder.h sys/select.h libkern/OSByteOrder.h byteswap.h machine/endian.h)
|
||||
AC_CHECK_HEADERS(ctype.h errno.h fcntl.h pthread.h pwd.h signal.h stdlib.h syslog.h unistd.h string.h stdarg.h utime.h uuid.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
@ -34,7 +34,7 @@ AC_CHECK_LIB(socket, connect)
|
||||
AC_CHECK_LIB(resolv, inet_aton)
|
||||
|
||||
dnl Check for functionality
|
||||
AC_CHECK_FUNCS(__bswap64 asprintf asnprintf bswap64 daemon htobe64 fsync_range snprintf strlcpy strtoll syslog uuid_create uuid_to_string vasprintf vasnprintf vsnprintf)
|
||||
AC_CHECK_FUNCS(__bswap64 asprintf asnprintf bswap64 daemon fsync_range getaddrinfo getnameinfo htobe64 poll snprintf strlcpy strtoll syslog uuid_create uuid_to_string vasprintf vasnprintf vsnprintf)
|
||||
|
||||
dnl that's it for now...
|
||||
AC_OUTPUT(Makefile)
|
||||
|
88
dist/iscsi/src/disk.c
vendored
88
dist/iscsi/src/disk.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: disk.c,v 1.19 2006/05/31 19:53:13 agc Exp $ */
|
||||
/* $NetBSD: disk.c,v 1.20 2006/08/03 20:21:59 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright © 2006 Alistair Crooks. All rights reserved.
|
||||
@ -126,14 +126,6 @@
|
||||
#include "defs.h"
|
||||
#include "storage.h"
|
||||
|
||||
/*
|
||||
* Begin disk configuration. If we're operating in filesystem mode, then the
|
||||
* file /tmp/<targetname>_<iscsi port>_iscsi_disk_lun_x is created for each
|
||||
* lun x. You can create symbolic links in /tmp to point to devices in /dev.
|
||||
* For example, "ln -s /dev/sda /tmp/mytarget_3260_iscsi_disk_lun_0." If
|
||||
* we're operating in ramdisk mode, then each lun is its own ramdisk.
|
||||
*/
|
||||
|
||||
#define CONFIG_DISK_NUM_LUNS_DFLT 1
|
||||
#define CONFIG_DISK_BLOCK_LEN_DFLT 512
|
||||
#define CONFIG_DISK_NUM_BLOCKS_DFLT 204800
|
||||
@ -146,25 +138,28 @@
|
||||
* Globals
|
||||
*/
|
||||
enum {
|
||||
ISCSI_RAMDISK = 0x01,
|
||||
MAX_RESERVATIONS = 32,
|
||||
|
||||
ISCSI_FS_MMAP = 0x02,
|
||||
ISCSI_FS = 0x03
|
||||
};
|
||||
|
||||
#define MB(x) ((x) * 1024 * 1024)
|
||||
|
||||
/* this struct describes an iscsi disk */
|
||||
typedef struct iscsi_disk_t {
|
||||
int type;
|
||||
uint8_t *ramdisk[CONFIG_DISK_MAX_LUNS];
|
||||
char filename[MAXPATHLEN];
|
||||
uint8_t buffer[CONFIG_DISK_MAX_LUNS][MB(1)];
|
||||
uint64_t blockc;
|
||||
uint64_t blocklen;
|
||||
uint64_t luns;
|
||||
uint64_t size;
|
||||
uuid_t uuid;
|
||||
char *uuid_string;
|
||||
targv_t *tv;
|
||||
int type; /* type of disk - fs/mmap and fs */
|
||||
char filename[MAXPATHLEN]; /* filename for the disk itself */
|
||||
uint8_t buffer[CONFIG_DISK_MAX_LUNS][MB(1)]; /* buffer for fs and fs/mmap options */
|
||||
uint64_t blockc; /* # of blocks */
|
||||
uint64_t blocklen; /* block size */
|
||||
uint64_t luns; /* # of luns */
|
||||
uint64_t size; /* size of complete disk */
|
||||
uuid_t uuid; /* disk's uuid */
|
||||
char *uuid_string; /* uuid string */
|
||||
targv_t *tv; /* the component devices and extents */
|
||||
uint32_t resc; /* # of reservation keys */
|
||||
uint64_t reskeys[MAX_RESERVATIONS]; /* the reservation keys */
|
||||
} iscsi_disk_t;
|
||||
|
||||
DEFINE_ARRAY(disks_t, iscsi_disk_t);
|
||||
@ -185,8 +180,8 @@ disk/extent code
|
||||
* Private Interface
|
||||
*/
|
||||
|
||||
static int disk_read(target_session_t * , iscsi_scsi_cmd_args_t * , uint32_t , uint16_t , uint8_t );
|
||||
static int disk_write(target_session_t * , iscsi_scsi_cmd_args_t * , uint8_t , uint32_t , uint32_t );
|
||||
static int disk_read(target_session_t * , iscsi_scsi_cmd_args_t * , uint32_t , uint16_t , uint8_t);
|
||||
static int disk_write(target_session_t * , iscsi_scsi_cmd_args_t * , uint8_t , uint32_t , uint32_t);
|
||||
|
||||
/* return the de index and offset within the device for RAID0 */
|
||||
static int
|
||||
@ -334,7 +329,7 @@ extent_fsync_range(disc_extent_t *xp, int how, off_t from, off_t len)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* (recursively) lseek on the device's devices */
|
||||
/* (recursively) fsync_range on the device's devices */
|
||||
static int
|
||||
device_fsync_range(disc_device_t *dp, int how, off_t from, off_t len)
|
||||
{
|
||||
@ -902,30 +897,19 @@ device_init(globals_t *gp, targv_t *tvp, disc_target_t *tp)
|
||||
disks.v[disks.c].luns,
|
||||
(disks.v[disks.c].luns == 1) ? "" : "s",
|
||||
disks.v[disks.c].blockc, disks.v[disks.c].blocklen,
|
||||
(disks.v[disks.c].type == ISCSI_FS) ? "iscsi fs" :
|
||||
(disks.v[disks.c].type == ISCSI_FS_MMAP) ? "iscsi fs mmap" : "iscsi ramdisk");
|
||||
(disks.v[disks.c].type == ISCSI_FS) ? "iscsi fs" : "iscsi fs mmap");
|
||||
for (i = 0; i < disks.v[disks.c].luns; i++) {
|
||||
printf("DISK: LUN %d: ", i);
|
||||
|
||||
if (disks.v[disks.c].type == ISCSI_RAMDISK) {
|
||||
if ((disks.v[disks.c].ramdisk[i] = iscsi_malloc((unsigned)disks.v[disks.c].size)) == NULL) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_malloc() failed\n");
|
||||
return -1;
|
||||
}
|
||||
iscsi_trace(TRACE_ISCSI_DEBUG, __FILE__, __LINE__, "allocated %" PRIu64 " bytes at %p\n", disks.v[disks.c].size, disks.v[disks.c].ramdisk[i]);
|
||||
printf("%" PRIu64 " MB ramdisk\n", disks.v[disks.c].size / MB(1));
|
||||
} else {
|
||||
(void) strlcpy(disks.v[disks.c].filename, disc_get_filename(&tp->de), sizeof(disks.v[disks.c].filename));
|
||||
if (de_open(&tp->de, O_CREAT | O_RDWR, 0666) == -1) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "error opening \"%s\"\n", disks.v[disks.c].filename);
|
||||
return -1;
|
||||
}
|
||||
if (!allocate_space(tp)) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "error allocating space for \"%s\"", tp->target);
|
||||
return -1;
|
||||
}
|
||||
printf("%" PRIu64 " MB disk storage for \"%s\"\n", (de_getsize(&tp->de) / MB(1)), tp->target);
|
||||
(void) strlcpy(disks.v[disks.c].filename, disc_get_filename(&tp->de), sizeof(disks.v[disks.c].filename));
|
||||
if (de_open(&tp->de, O_CREAT | O_RDWR, 0666) == -1) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "error opening \"%s\"\n", disks.v[disks.c].filename);
|
||||
return -1;
|
||||
}
|
||||
if (!allocate_space(tp)) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "error allocating space for \"%s\"", tp->target);
|
||||
return -1;
|
||||
}
|
||||
printf("%" PRIu64 " MB disk storage for \"%s\"\n", (de_getsize(&tp->de) / MB(1)), tp->target);
|
||||
}
|
||||
return disks.c++;
|
||||
}
|
||||
@ -1234,14 +1218,6 @@ device_command(target_session_t * sess, target_cmd_t * cmd)
|
||||
int
|
||||
device_shutdown(target_session_t *sess)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (disks.v[sess->d].type == ISCSI_RAMDISK) {
|
||||
for (i = 0; i < disks.v[sess->d].luns; i++) {
|
||||
iscsi_trace(TRACE_ISCSI_DEBUG, __FILE__, __LINE__, "freeing ramdisk[%d] (%p)\n", i, disks.v[sess->d].ramdisk[i]);
|
||||
iscsi_free(disks.v[sess->d].ramdisk[i]);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1263,9 +1239,6 @@ disk_write(target_session_t *sess, iscsi_scsi_cmd_args_t *args, uint8_t lun, uin
|
||||
/* Assign ptr for write data */
|
||||
|
||||
switch(disks.v[sess->d].type) {
|
||||
case ISCSI_RAMDISK:
|
||||
ptr = disks.v[sess->d].ramdisk[lun] + (int) byte_offset;
|
||||
break;
|
||||
case ISCSI_FS:
|
||||
RETURN_GREATER("num_bytes (FIX ME)", (unsigned) num_bytes, MB(1), NO_CLEANUP, -1);
|
||||
ptr = disks.v[sess->d].buffer[lun];
|
||||
@ -1348,9 +1321,6 @@ disk_read(target_session_t * sess, iscsi_scsi_cmd_args_t * args, uint32_t lba, u
|
||||
return -1;
|
||||
}
|
||||
switch (disks.v[sess->d].type) {
|
||||
case ISCSI_RAMDISK:
|
||||
ptr = disks.v[sess->d].ramdisk[lun] + (int)byte_offset;
|
||||
break;
|
||||
case ISCSI_FS:
|
||||
RETURN_GREATER("num_bytes (FIX ME)", (unsigned) num_bytes, MB(1), NO_CLEANUP, -1);
|
||||
ptr = disks.v[sess->d].buffer[lun];
|
||||
|
140
dist/iscsi/src/initiator.c
vendored
140
dist/iscsi/src/initiator.c
vendored
@ -681,7 +681,7 @@ full_feature_phase(initiator_session_t * sess)
|
||||
}
|
||||
|
||||
int
|
||||
initiator_init(const char *hostname, const char *user, int auth_type, int mutual_auth, int digest_type)
|
||||
initiator_init(const char *hostname, int address_family, const char *user, int auth_type, int mutual_auth, int digest_type)
|
||||
{
|
||||
int i;
|
||||
initiator_session_t *sess = NULL;
|
||||
@ -1269,30 +1269,17 @@ tx_worker_proc_i(void *arg)
|
||||
ISCSI_LOCK(&me->work_mutex, return -1);
|
||||
|
||||
/*
|
||||
* The Rx thread will receive a response for the
|
||||
* command and execute the
|
||||
*/
|
||||
/*
|
||||
* callback. We need to make sure the callback
|
||||
* function is not executed
|
||||
*/
|
||||
/*
|
||||
* before the Tx thread has completed sending the
|
||||
* command. This is what
|
||||
*/
|
||||
/*
|
||||
* tx_done is used for. The last step is to set
|
||||
* tx_done and signal the
|
||||
*/
|
||||
/*
|
||||
* Rx thread, which may be block on the condition.
|
||||
* NOP_OUT (without ping)
|
||||
*/
|
||||
/*
|
||||
* will have no response for the Rx thread to process
|
||||
* - so we execute
|
||||
*/
|
||||
/* the callback directly. */
|
||||
* The Rx thread will receive a response for
|
||||
* the command and execute the callback. We
|
||||
* need to make sure the callback function is
|
||||
* not executed before the Tx thread has
|
||||
* completed sending the command. This is
|
||||
* what tx_done is used for. The last step is
|
||||
* to set tx_done and signal the Rx thread,
|
||||
* which may be block on the condition.
|
||||
* NOP_OUT (without ping) will have no
|
||||
* response for the Rx thread to process - so
|
||||
* we execute the callback directly. */
|
||||
|
||||
if ((cmd->type == ISCSI_NOP_OUT) && (((iscsi_nop_out_args_t *) (cmd->ptr))->tag == 0xffffffff)) {
|
||||
iscsi_trace(TRACE_ISCSI_DEBUG, __FILE__, __LINE__, "executing callback() function directly for NOP_OUT (no NOP_IN)\n");
|
||||
@ -1674,20 +1661,12 @@ login_phase_i(initiator_session_t * sess, char *text, int text_len)
|
||||
do {
|
||||
|
||||
/*
|
||||
* Build login command. Note that the <length> and <text>
|
||||
* fields may get
|
||||
*/
|
||||
/*
|
||||
* updated by login_response_i. Such is the case when we
|
||||
* receive offers
|
||||
*/
|
||||
/*
|
||||
* from the target. The new <length> and <text> fields will
|
||||
* represent
|
||||
*/
|
||||
/*
|
||||
* the response that we need to send to the target on the
|
||||
* next login.
|
||||
* Build login command. Note that the <length> and
|
||||
* <text> fields may get updated by login_response_i.
|
||||
* Such is the case when we receive offers from the
|
||||
* target. The new <length> and <text> fields will
|
||||
* represent the response that we need to send to the
|
||||
* target on the next login.
|
||||
*/
|
||||
|
||||
login_cmd->cont = 0;
|
||||
@ -2124,14 +2103,10 @@ nop_out_i(initiator_cmd_t * cmd)
|
||||
if (nop_out->tag != 0xffffffff) {
|
||||
|
||||
/*
|
||||
* Insert cmd into the hash table, keyed by nop_out->tag.
|
||||
* Upon receipt of the
|
||||
*/
|
||||
/*
|
||||
* NOP_IN_T, the Rx thread will retreive the cmd ptr using
|
||||
* the tag from the
|
||||
*/
|
||||
/* NOP_IN_T PDU. */
|
||||
* Insert cmd into the hash table, keyed by
|
||||
* nop_out->tag. Upon receipt of the NOP_IN_T, the Rx
|
||||
* thread will retreive the cmd ptr using the tag from
|
||||
* the NOP_IN_T PDU. */
|
||||
|
||||
if (hash_insert(&g_tag_hash, cmd, nop_out->tag) != 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "hash_insert() failed\n");
|
||||
@ -2148,18 +2123,12 @@ nop_out_i(initiator_cmd_t * cmd)
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* We need to make a copy of nop_out->length and save in the variable
|
||||
* length. Otherwise,
|
||||
*/
|
||||
/*
|
||||
* we may get a seg fault - as if this is a NOP_OUT without ping, the
|
||||
* Tx thread will
|
||||
*/
|
||||
/*
|
||||
* issue the callback function immediately after we return - thereby
|
||||
* unallocating the
|
||||
*/
|
||||
/* NOP_OUT and initiator command structures. */
|
||||
* We need to make a copy of nop_out->length and save in the
|
||||
* variable length. Otherwise, we may get a seg fault - as if
|
||||
* this is a NOP_OUT without ping, the Tx thread will issue
|
||||
* the callback function immediately after we return - thereby
|
||||
* de-allocating the NOP_OUT and initiator command structures.
|
||||
* */
|
||||
|
||||
if ((rc = iscsi_sock_send_header_and_data(sess->sock, header, ISCSI_HEADER_LEN, nop_out->data,
|
||||
length, 0)) != ISCSI_HEADER_LEN + length) {
|
||||
@ -2250,10 +2219,9 @@ scsi_command_i(initiator_cmd_t * cmd)
|
||||
goto error;
|
||||
}
|
||||
/*
|
||||
* If we're sending any immediate data, we need to make a new iovec
|
||||
* that
|
||||
*/
|
||||
/* contains only the immediata data (a subset of the original iovec). */
|
||||
* If we're sending any immediate data, we need to make a new
|
||||
* iovec that contains only the immediata data (a subset of
|
||||
* the original iovec). */
|
||||
iscsi_trace(TRACE_ISCSI_DEBUG, __FILE__, __LINE__, "sending command PDU with %u bytes immediate data\n", scsi_cmd->length);
|
||||
if (scsi_cmd->length && sess->sess_params.immediate_data) {
|
||||
if ((sg_copy = iscsi_malloc_atomic(sg_len * sizeof(struct iovec))) == NULL) {
|
||||
@ -2304,12 +2272,9 @@ scsi_command_i(initiator_cmd_t * cmd)
|
||||
iscsi_trace(TRACE_ISCSI_DEBUG, __FILE__, __LINE__, "command PDU sent with %u bytes immediate data (%u bytes AHS)\n", scsi_cmd->length, scsi_cmd->ahs_len);
|
||||
|
||||
/*
|
||||
* Send data PDUS if 1) we're not in R2T mode and 2) we haven't sent
|
||||
* everything as immediate
|
||||
*/
|
||||
/*
|
||||
* data and 3) we have not reached the first burst when sending
|
||||
* immediate data
|
||||
* Send data PDUS if 1) we're not in R2T mode and 2) we
|
||||
* haven't sent everything as immediate data and 3) we have
|
||||
* not reached the first burst when sending immediate data
|
||||
*/
|
||||
if (scsi_cmd->output
|
||||
&& (!sess->sess_params.initial_r2t)
|
||||
@ -2658,12 +2623,9 @@ scsi_r2t_i(initiator_session_t * sess, initiator_cmd_t * cmd, uint8_t *header)
|
||||
int sg_len, sg_len_copy, sg_len_which;
|
||||
int fragment_flag;
|
||||
|
||||
/* Make sure an initiator_cmd_t was specified, that it has a callback */
|
||||
/*
|
||||
* function specified and that it also has a iscsi_scsi_cmd_args_t
|
||||
* associated
|
||||
*/
|
||||
/* with it. */
|
||||
/* Make sure an initiator_cmd_t was specified, that it has a
|
||||
* callback function specified and that it also has a
|
||||
* iscsi_scsi_cmd_args_t associated with it. */
|
||||
|
||||
if (cmd) {
|
||||
if ((scsi_cmd = (iscsi_scsi_cmd_args_t *) cmd->ptr) == NULL) {
|
||||
@ -2799,12 +2761,9 @@ scsi_response_i(initiator_session_t * sess, initiator_cmd_t * cmd, uint8_t *head
|
||||
iscsi_scsi_cmd_args_t *scsi_cmd;
|
||||
iscsi_scsi_rsp_t scsi_rsp;
|
||||
|
||||
/* Make sure an initiator_cmd_t was specified, that it has a callback */
|
||||
/*
|
||||
* function specified and that it also has a iscsi_scsi_cmd_args_t
|
||||
* associated
|
||||
*/
|
||||
/* with it. */
|
||||
/* Make sure an initiator_cmd_t was specified, that it has a
|
||||
* callback function specified and that it also has a
|
||||
* iscsi_scsi_cmd_args_t associated with it. */
|
||||
|
||||
if (cmd) {
|
||||
if ((scsi_cmd = (iscsi_scsi_cmd_args_t *) cmd->ptr) == NULL) {
|
||||
@ -2820,10 +2779,8 @@ scsi_response_i(initiator_session_t * sess, initiator_cmd_t * cmd, uint8_t *head
|
||||
}
|
||||
|
||||
/*
|
||||
* Read SCSI response and check return args. Those marked "FIX ME"
|
||||
* are not
|
||||
*/
|
||||
/* yet implemented. */
|
||||
* Read SCSI response and check return args. Those marked
|
||||
* "FIX ME" are not yet implemented. */
|
||||
|
||||
if (iscsi_scsi_rsp_decap(header, &scsi_rsp) != 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_scsi_rsp_decap() failed\n");
|
||||
@ -2848,9 +2805,7 @@ scsi_response_i(initiator_session_t * sess, initiator_cmd_t * cmd, uint8_t *head
|
||||
}
|
||||
/*
|
||||
* Make sure all data was successfully transferred if command
|
||||
* completed successfully,
|
||||
*/
|
||||
/* otherwise read sense data. */
|
||||
* completed successfully, otherwise read sense data. */
|
||||
|
||||
if (scsi_rsp.status == 0) {
|
||||
if (scsi_cmd->output) {
|
||||
@ -2917,12 +2872,9 @@ scsi_read_data_i(initiator_session_t * sess, initiator_cmd_t * cmd, uint8_t *hea
|
||||
|
||||
iscsi_trace(TRACE_ISCSI_DEBUG, __FILE__, __LINE__, "processing read data\n");
|
||||
|
||||
/* Make sure an initiator_cmd_t was specified, that it has a callback */
|
||||
/*
|
||||
* function specified and that it also has a iscsi_scsi_cmd_args_t
|
||||
* associated
|
||||
*/
|
||||
/* with it. */
|
||||
/* Make sure an initiator_cmd_t was specified, that it has a
|
||||
* callback function specified and that it also has a
|
||||
* iscsi_scsi_cmd_args_t associated with it. */
|
||||
|
||||
if (cmd) {
|
||||
if (cmd->type != ISCSI_SCSI_CMD) {
|
||||
|
14
dist/iscsi/src/iscsi-harness.c
vendored
14
dist/iscsi/src/iscsi-harness.c
vendored
@ -72,6 +72,7 @@ main(int argc, char **argv)
|
||||
char hostname[1024];
|
||||
char *host;
|
||||
char *user;
|
||||
int address_family;
|
||||
int tgtlo = 0;
|
||||
int tgthi = CONFIG_INITIATOR_NUM_TARGETS;
|
||||
int target = -1;
|
||||
@ -89,10 +90,17 @@ main(int argc, char **argv)
|
||||
(void) gethostname(host = hostname, sizeof(hostname));
|
||||
digest_type = DigestNone;
|
||||
auth_type = AuthNone;
|
||||
address_family = ISCSI_UNSPEC;
|
||||
mutual_auth = 0;
|
||||
|
||||
while ((i = getopt(argc, argv, "a:d:h:l:n:t:u:V")) != -1) {
|
||||
while ((i = getopt(argc, argv, "46a:d:h:l:n:t:u:V")) != -1) {
|
||||
switch(i) {
|
||||
case '4':
|
||||
address_family = ISCSI_IPv4;
|
||||
break;
|
||||
case '6':
|
||||
address_family = ISCSI_IPv6;
|
||||
break;
|
||||
case 'a':
|
||||
if (strcasecmp(optarg, "chap") == 0) {
|
||||
auth_type = AuthCHAP;
|
||||
@ -152,7 +160,7 @@ main(int argc, char **argv)
|
||||
tgthi = target + 1;
|
||||
}
|
||||
if (argc == 1) {
|
||||
(void) fprintf(stderr, "usage: %s [-V] [-a auth-type] [-d digest-type] [-h hostname] [-l lun] [-n iterations] [-t target] [-u user]\n", *argv);
|
||||
(void) fprintf(stderr, "usage: %s [-4] [-6] [-V] [-a auth-type] [-d digest-type] [-h hostname] [-l lun] [-n iterations] [-t target] [-u user]\n", *argv);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (j = 0; j < iterations; j++) {
|
||||
@ -165,7 +173,7 @@ main(int argc, char **argv)
|
||||
sigaction(SIGPIPE, &act, NULL);
|
||||
|
||||
/* Initialize Initiator */
|
||||
if (initiator_init(host, user, auth_type, mutual_auth, digest_type) == -1) {
|
||||
if (initiator_init(host, address_family, user, auth_type, mutual_auth, digest_type) == -1) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "initiator_init() failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
13
dist/iscsi/src/iscsi-target.c
vendored
13
dist/iscsi/src/iscsi-target.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: iscsi-target.c,v 1.10 2006/05/27 21:21:04 agc Exp $ */
|
||||
/* $NetBSD: iscsi-target.c,v 1.11 2006/08/03 20:21:59 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright © 2006 Alistair Crooks. All rights reserved.
|
||||
@ -64,7 +64,6 @@ static globals_t g;
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const char *cf;
|
||||
targv_t tv;
|
||||
devv_t dv;
|
||||
extv_t ev;
|
||||
@ -81,10 +80,10 @@ main(int argc, char **argv)
|
||||
(void) strlcpy(TargetName, DEFAULT_TARGET_NAME, sizeof(TargetName));
|
||||
detach_me_harder = 1;
|
||||
g.port = ISCSI_PORT;
|
||||
g.address_family = ISCSI_IPv4;
|
||||
g.address_family = ISCSI_UNSPEC;
|
||||
g.max_sessions = DEFAULT_TARGET_MAX_SESSIONS;
|
||||
|
||||
cf = _PATH_ISCSI_TARGETS;
|
||||
(void) strlcpy(g.config_file, _PATH_ISCSI_TARGETS, sizeof(g.config_file));
|
||||
|
||||
while ((i = getopt(argc, argv, "46b:Df:p:s:t:Vv:")) != -1) {
|
||||
switch (i) {
|
||||
@ -101,7 +100,7 @@ main(int argc, char **argv)
|
||||
detach_me_harder = 0;
|
||||
break;
|
||||
case 'f':
|
||||
cf = optarg;
|
||||
(void) strlcpy(g.config_file, optarg, sizeof(g.config_file));
|
||||
break;
|
||||
case 'p':
|
||||
g.port = (uint16_t) atoi(optarg);
|
||||
@ -132,8 +131,8 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (!read_conf_file(cf, &tv, &dv, &ev)) {
|
||||
(void) fprintf(stderr, "Error: can't open `%s'\n", cf);
|
||||
if (!read_conf_file(g.config_file, &tv, &dv, &ev)) {
|
||||
(void) fprintf(stderr, "Error: can't open `%s'\n", g.config_file);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
3
dist/iscsi/src/storage.c
vendored
3
dist/iscsi/src/storage.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: storage.c,v 1.4 2006/03/20 20:45:07 agc Exp $ */
|
||||
/* $NetBSD: storage.c,v 1.5 2006/08/03 20:21:59 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright © 2006 Alistair Crooks. All rights reserved.
|
||||
@ -404,4 +404,3 @@ write_pid_file(const char *f)
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
|
121
dist/iscsi/src/target.c
vendored
121
dist/iscsi/src/target.c
vendored
@ -68,6 +68,10 @@
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
@ -646,7 +650,7 @@ text_command_t(target_session_t * sess, uint8_t *header)
|
||||
PARAM_TEXT_ADD(sess->params, "SendTargets", "Reject", text_out, &len_out, 2048, 0, TC_ERROR);
|
||||
} else {
|
||||
for (i = 0 ; i < sess->globals->tv->c ; i++) {
|
||||
if (sess->address_family == ISCSI_IPv6 ||
|
||||
if (sess->address_family == ISCSI_IPv6 ||
|
||||
(sess->address_family == ISCSI_IPv4 && allow_netmask(sess->globals->tv->v[i].mask, sess->initiator))) {
|
||||
(void) snprintf(buf, sizeof(buf), "%s:%s", sess->globals->targetname, sess->globals->tv->v[i].target);
|
||||
PARAM_TEXT_ADD(sess->params, "TargetName", buf, text_out, &len_out, 2048, 0, TC_ERROR);
|
||||
@ -1494,11 +1498,10 @@ target_init(globals_t *gp, targv_t *tv, char *TargetName)
|
||||
gp->listener_pid = -1;
|
||||
gp->state = TARGET_INITIALIZED;
|
||||
|
||||
printf("TARGET: TargetName is %s, listening on %s port %d\n",
|
||||
gp->targetname,
|
||||
(gp->address_family == ISCSI_IPv4) ? "IPv4" :
|
||||
(gp->address_family == ISCSI_IPv6) ? "IPv6" : "unknown",
|
||||
gp->port);
|
||||
printf("TARGET: TargetName is %s\n", gp->targetname);
|
||||
for (i = 0 ; i < gp->sockc ; i++) {
|
||||
printf("\tsocket %d listening on port %hd\n", gp->sockv[i], gp->port);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1566,41 +1569,29 @@ target_shutdown(globals_t *gp)
|
||||
int
|
||||
target_listen(globals_t *gp)
|
||||
{
|
||||
struct sockaddr_in6 remoteAddrStorage6;
|
||||
struct sockaddr_in6 localAddrStorage6;
|
||||
struct sockaddr_in remoteAddrStorage;
|
||||
struct sockaddr_in localAddrStorage;
|
||||
target_session_t *sess;
|
||||
iscsi_socket_t newconn;
|
||||
socklen_t remoteAddrLen;
|
||||
socklen_t localAddrLen;
|
||||
char remote[1024];
|
||||
char local[1024];
|
||||
int one = 1;
|
||||
int i;
|
||||
|
||||
ISCSI_THREAD_START("listen_thread");
|
||||
gp->listener_pid = ISCSI_GETPID;
|
||||
gp->listener_listening++;
|
||||
iscsi_trace(TRACE_ISCSI_DEBUG, __FILE__, __LINE__, "listener thread started\n");
|
||||
|
||||
/* Create/Bind/Listen */
|
||||
if (!iscsi_sock_create(&gp->sock)) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_create() failed\n");
|
||||
goto done;
|
||||
}
|
||||
if (!iscsi_sock_setsockopt(&gp->sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_setsockopt() failed\n");
|
||||
goto done;
|
||||
}
|
||||
if (!iscsi_sock_setsockopt(&gp->sock, SOL_TCP, TCP_NODELAY, &one, sizeof(one))) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_setsockopt() failed\n");
|
||||
return -1;
|
||||
}
|
||||
if (!iscsi_sock_bind(gp->sock, gp->port)) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_bind() failed\n");
|
||||
goto done;
|
||||
}
|
||||
if (!iscsi_sock_listen(gp->sock)) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_listen() failed\n");
|
||||
if (!iscsi_socks_establish(gp->sockv, gp->famv, &gp->sockc, gp->address_family)) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_establish() failed\n");
|
||||
goto done;
|
||||
}
|
||||
gp->sock = gp->sockv[0];
|
||||
|
||||
iscsi_trace(TRACE_NET_DEBUG, __FILE__, __LINE__, "create, bind, listen OK\n");
|
||||
|
||||
/* Loop for connections: FIX ME with queue */
|
||||
@ -1616,52 +1607,75 @@ target_listen(globals_t *gp)
|
||||
|
||||
sess->globals = gp;
|
||||
|
||||
sess->address_family = gp->address_family;
|
||||
|
||||
/* Accept connection, spawn session thread, and */
|
||||
/* clean up old threads */
|
||||
|
||||
iscsi_trace(TRACE_NET_DEBUG, __FILE__, __LINE__, "waiting for IPv4 connection on port %hd\n", gp->port);
|
||||
if (!iscsi_sock_accept(gp->sock, &sess->sock)) {
|
||||
i = iscsi_waitfor_connection(gp->sockv, gp->sockc, gp->config_file, &newconn);
|
||||
|
||||
iscsi_trace(TRACE_NET_DEBUG, __FILE__, __LINE__, "waiting for %s connection on port %hd\n",
|
||||
iscsi_address_family(gp->famv[i]),
|
||||
gp->port);
|
||||
|
||||
if (!iscsi_sock_accept(newconn, &sess->sock)) {
|
||||
iscsi_trace(TRACE_ISCSI_DEBUG, __FILE__, __LINE__, "iscsi_sock_accept() failed\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
localAddrLen = sizeof(localAddrStorage);
|
||||
(void) memset(&localAddrStorage, 0x0, sizeof(localAddrStorage));
|
||||
if (!iscsi_sock_getsockname(sess->sock, (struct sockaddr *) (void *) &localAddrStorage, &localAddrLen)) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_getsockname() failed\n");
|
||||
goto done;
|
||||
}
|
||||
switch (gp->famv[i]) {
|
||||
case AF_INET:
|
||||
sess->address_family = ISCSI_IPv4;
|
||||
(void) memset(&localAddrStorage, 0x0, localAddrLen = sizeof(localAddrStorage));
|
||||
if (getsockname(sess->sock, (struct sockaddr *) (void *) &localAddrStorage, &localAddrLen) < 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_getsockname() failed\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
remoteAddrLen = sizeof(remoteAddrStorage);
|
||||
(void) memset(&remoteAddrStorage, 0x0, sizeof(remoteAddrStorage));
|
||||
if (!iscsi_sock_getpeername(sess->sock, (struct sockaddr *) (void *) &remoteAddrStorage, &remoteAddrLen)) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_getpeername() failed\n");
|
||||
goto done;
|
||||
}
|
||||
(void) memset(&remoteAddrStorage, 0x0, remoteAddrLen = sizeof(remoteAddrStorage));
|
||||
if (getpeername(sess->sock, (struct sockaddr *) (void *) &remoteAddrStorage, &remoteAddrLen) < 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_getpeername() failed\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
switch (sess->address_family = (remoteAddrStorage.sin_family = PF_INET6) ? ISCSI_IPv6 : ISCSI_IPv4) {
|
||||
case ISCSI_IPv4:
|
||||
#ifdef HAVE_GETNAMEINFO
|
||||
if (getnameinfo((struct sockaddr *)(void *)&localAddrStorage,
|
||||
sizeof(localAddrStorage), local, sizeof(local), NULL, 0, NI_NUMERICHOST) < 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "getnameinfo local failed\n");
|
||||
}
|
||||
if (getnameinfo((struct sockaddr *)(void *)&remoteAddrStorage,
|
||||
sizeof(remoteAddrStorage), remote, sizeof(remote), NULL, 0, NI_NUMERICHOST) < 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "getnameinfo remote failed\n");
|
||||
}
|
||||
(void) strlcpy(sess->initiator, remote, sizeof(sess->initiator));
|
||||
#else
|
||||
(void) strlcpy(local, inet_ntoa(localAddrStorage.sin_addr), sizeof(local));
|
||||
(void) strlcpy(sess->initiator, inet_ntoa(remoteAddrStorage.sin_addr), sizeof(sess->initiator));
|
||||
#endif
|
||||
|
||||
(void) snprintf(gp->targetaddress, sizeof(gp->targetaddress), "%s:%u,1", local, gp->port);
|
||||
iscsi_trace(TRACE_ISCSI_DEBUG, __FILE__, __LINE__, "IPv4 connection accepted on port %d (local IP %s, remote IP %s)\n",
|
||||
gp->port, local, sess->initiator);
|
||||
iscsi_trace(TRACE_ISCSI_DEBUG, __FILE__, __LINE__, "TargetAddress = \"%s\"\n", gp->targetaddress);
|
||||
if (iscsi_thread_create(&sess->worker.thread, (void *) worker_proc_t, sess) != 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_thread_create() failed\n");
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
sess->address_family = ISCSI_IPv6;
|
||||
(void) memset(&localAddrStorage6, 0x0, localAddrLen = sizeof(localAddrStorage6));
|
||||
if (getsockname(sess->sock, (struct sockaddr *) (void *) &localAddrStorage6, &localAddrLen) < 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "getsockname() failed\n");
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
case ISCSI_IPv6:
|
||||
if (inet_ntop(localAddrStorage.sin_family, (void *)&localAddrStorage.sin_addr, local, sizeof(local)) == NULL) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "inet_ntop local failed\n");
|
||||
|
||||
(void) memset(&remoteAddrStorage6, 0x0, remoteAddrLen = sizeof(remoteAddrStorage6));
|
||||
if (getpeername(sess->sock, (struct sockaddr *) (void *) &remoteAddrStorage6, &remoteAddrLen) < 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_getpeername() failed\n");
|
||||
goto done;
|
||||
}
|
||||
if (inet_ntop(remoteAddrStorage.sin_family, (void *)&remoteAddrStorage.sin_addr, remote, sizeof(remote)) == NULL) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "inet_ntop remotefailed\n");
|
||||
|
||||
if (getnameinfo((struct sockaddr *)(void *)&localAddrStorage6, sizeof(localAddrStorage6), local, sizeof(local), NULL, 0, NI_NUMERICHOST) < 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "getnameinfo local failed\n");
|
||||
}
|
||||
if (getnameinfo((struct sockaddr *)(void *)&remoteAddrStorage6, sizeof(remoteAddrStorage6), remote, sizeof(remote), NULL, 0, NI_NUMERICHOST) < 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "getnameinfo remote failed\n");
|
||||
}
|
||||
(void) strlcpy(sess->initiator, remote, sizeof(sess->initiator));
|
||||
(void) snprintf(gp->targetaddress, sizeof(gp->targetaddress), "%s:%u,1", local, gp->port);
|
||||
@ -1670,6 +1684,7 @@ target_listen(globals_t *gp)
|
||||
iscsi_trace(TRACE_ISCSI_DEBUG, __FILE__, __LINE__, "TargetAddress = \"%s\"\n", gp->targetaddress);
|
||||
break;
|
||||
}
|
||||
|
||||
if (iscsi_thread_create(&sess->worker.thread, (void *) worker_proc_t, sess) != 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_thread_create() failed\n");
|
||||
goto done;
|
||||
|
133
dist/iscsi/src/util.c
vendored
133
dist/iscsi/src/util.c
vendored
@ -33,6 +33,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
@ -74,6 +75,14 @@
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -543,6 +552,130 @@ iscsi_sock_listen(iscsi_socket_t sock)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef MAXSOCK
|
||||
#define MAXSOCK 16
|
||||
#endif
|
||||
|
||||
int
|
||||
iscsi_socks_establish(iscsi_socket_t *sockv, int *famv, int *sockc, int family)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res;
|
||||
struct addrinfo *res0;
|
||||
const char *cause = NULL;
|
||||
int one = 1;
|
||||
int error;
|
||||
|
||||
(void) memset(&hints, 0x0, sizeof(hints));
|
||||
hints.ai_family = family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
if ((error = getaddrinfo(NULL, "iscsi", &hints, &res0)) != 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "getaddrinfo: %s", gai_strerror(error));
|
||||
return 0;
|
||||
}
|
||||
*sockc = 0;
|
||||
for (res = res0; res && *sockc < MAXSOCK; res = res->ai_next) {
|
||||
if ((sockv[*sockc] = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
|
||||
cause = "socket";
|
||||
continue;
|
||||
}
|
||||
famv[*sockc] = res->ai_family;
|
||||
if (!iscsi_sock_setsockopt(&sockv[*sockc], SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_setsockopt() failed\n");
|
||||
continue;
|
||||
}
|
||||
if (!iscsi_sock_setsockopt(&sockv[*sockc], SOL_TCP, TCP_NODELAY, &one, sizeof(one))) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_setsockopt() failed\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bind(sockv[*sockc], res->ai_addr, res->ai_addrlen) < 0) {
|
||||
cause = "bind";
|
||||
close(sockv[*sockc]);
|
||||
continue;
|
||||
}
|
||||
(void) listen(sockv[*sockc], 32);
|
||||
|
||||
*sockc += 1;
|
||||
}
|
||||
if (*sockc == 0) {
|
||||
iscsi_trace_error(__FILE__, __LINE__, "iscsi_sock_establish: no sockets found: %s", cause);
|
||||
freeaddrinfo(res0);
|
||||
return 0;
|
||||
}
|
||||
freeaddrinfo(res0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* return the address family for the socket */
|
||||
const char *
|
||||
iscsi_address_family(int fam)
|
||||
{
|
||||
return (fam == AF_INET) ? "IPv4" : (fam == AF_INET6) ? "IPv6" : "[unknown type]";
|
||||
}
|
||||
|
||||
/* wait for a connection to come in on a socket */
|
||||
int
|
||||
iscsi_waitfor_connection(iscsi_socket_t *sockv, int sockc, const char *cf, iscsi_socket_t *sock)
|
||||
{
|
||||
#ifdef HAVE_POLL
|
||||
struct pollfd socks[MAXSOCK];
|
||||
int i;
|
||||
|
||||
for (;;) {
|
||||
for (i = 0 ; i < sockc ; i++) {
|
||||
socks[i].fd = sockv[i];
|
||||
socks[i].events = POLLIN;
|
||||
socks[i].revents = 0;
|
||||
}
|
||||
switch(poll(socks, sockc, INFTIM)) {
|
||||
case -1:
|
||||
/* interrupted system call */
|
||||
continue;
|
||||
case 0:
|
||||
/* timeout */
|
||||
continue;
|
||||
default:
|
||||
for (i = 0 ; i < sockc ; i++) {
|
||||
if (socks[i].revents & POLLIN) {
|
||||
iscsi_trace(TRACE_NET_DEBUG, __FILE__, __LINE__, "connection %d selected\n", sockv[i]);
|
||||
*sock = sockv[i];
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
fd_set infds;
|
||||
int i;
|
||||
|
||||
for (;;) {
|
||||
FD_ZERO(&infds);
|
||||
for (i = 0 ; i < sockc ; i++) {
|
||||
FD_SET(sockv[i], &infds);
|
||||
}
|
||||
iscsi_trace(TRACE_NET_DEBUG, __FILE__, __LINE__, "waiting for connection\n");
|
||||
switch (select(32, &infds, NULL, NULL, NULL)) {
|
||||
case -1:
|
||||
/* interrupted system call */
|
||||
continue;
|
||||
case 0:
|
||||
/* timeout */
|
||||
continue;
|
||||
default:
|
||||
for (i = 0 ; i < sockc ; i++) {
|
||||
if (FD_ISSET(sockv[i], &infds)) {
|
||||
iscsi_trace(TRACE_NET_DEBUG, __FILE__, __LINE__, "connection %d selected\n", sockv[i]);
|
||||
*sock = sockv[i];
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
iscsi_sock_accept(iscsi_socket_t sock, iscsi_socket_t * newsock)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user