iscsi distribution has moved to src/external/bsd/iscsi

This commit is contained in:
agc 2009-06-25 23:42:21 +00:00
parent 9fc49d2576
commit 664fc89d11
9 changed files with 0 additions and 1615 deletions

View File

@ -1,9 +0,0 @@
# $NetBSD: Makefile,v 1.3 2009/06/20 04:18:39 agc Exp $
.if exists(${.CURDIR}/../../Makefile.inc)
.include "${.CURDIR}/../../Makefile.inc"
.endif
SUBDIR= target initiator
.include <bsd.subdir.mk>

View File

@ -1,23 +0,0 @@
# $NetBSD: Makefile,v 1.4 2009/06/20 17:58:21 agc Exp $
.sinclude "${.CURDIR}/../../Makefile.inc"
.include <bsd.own.mk>
PROG=iscsi-initiator
SRCS=iscsi-initiator.c virtdir.c initiator.c libkmod.c
LDADD+= -lrefuse -liscsi
DPADD+= ${LIBREFUSE} ${LIBISCSI}
CPPFLAGS+= -g -I${NETBSDSRCDIR}/dist/iscsi/include
MAN=iscsi-initiator.8
WARNS=4
.ifdef MODULAR_KERNEL
CPPFLAGS+= -DUSE_LIBKMOD
LDADD+= -lprop
DPADD+= ${LIBPROP}
.endif
.PATH: ${NETBSDSRCDIR}/dist/iscsi/src
.include <bsd.prog.mk>

View File

@ -1,150 +0,0 @@
.\" $NetBSD: iscsi-initiator.8,v 1.2 2009/06/19 19:31:18 wiz Exp $
.\"
.\" Copyright © 2007 Alistair Crooks. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. The name of the author may not be used to endorse or promote
.\" products derived from this software without specific prior written
.\" permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd September 20, 2007
.Dt ISCSI-INITIATOR 8
.Os
.Sh NAME
.Nm iscsi-initiator
.Nd refuse-based iSCSI initiator
.Sh SYNOPSIS
.Nm
.Op Fl 46bcfVv
.Op Fl a Ar authentication-type
.Op Fl d Ar digest-type
.Op Fl h Ar target-hostname
.Op Fl p Ar target-port-number
.Op Fl t Ar target-number
.Op Fl u Ar username
.Ar mount_point
.Sh DESCRIPTION
The
.Nm
utility can be used to access an iSCSI target, such as
.Xr iscsi-target 8 ,
to access block storage which has been exported.
Information pertaining to the target is displayed underneath
the mount point, along with the device corresponding
to the storage which the target exports.
.Pp
The various arguments are as follows:
.Bl -tag -width Ds
.It Fl 4
Use an IPv4 connection to the target.
.It Fl 6
Use an IPv6 connection to the target.
.It Fl a Ar authentication-type
Use the specified authentication type when communicating with the target.
The possible values are chap, kerberos, srp or none.
The default value is none.
.It Fl b
Show the storage as a block device.
.It Fl c
Show the storage as a character device.
.It Fl d Ar digest-type
Use the specified digest type when communicating with the target.
The possible values are header, data, both, all or none.
The default value is none.
.It Fl f
Show the storage as a regular file.
.It Fl h Ar hostname
Connect to the iSCSI target running on the host specified as the argument.
.It Fl p Ar port-number
Connect to the iSCSI target running on the port specified as the argument.
The default value is 3260.
.It Fl t Ar target
Connect to the number of the iSCSI target running as the argument.
.It Fl u Ar username
Use the specified user's credentials when logging in to the iSCSI target.
There is no default.
.It Fl V
Print out the version number and then exit.
.It Fl v
Be verbose in operation.
.El
.Pp
The
.Xr refuse 3
library is used to provide the file system features.
.Pp
The mandatory parameter is the local mount point.
.Pp
This iSCSI initiator presents a view of the targets underneath the
mount point.
Firstly, it creates a directory tree with the hostname of the target,
and, in that directory, a virtual directory is created for each
target name exported by the iSCSI target program.
Within that virtual target directory, symbolic links exist for
the hostname (for convenience),
a textual representation of the IP address,
the iSCSI target product name,
the iSCSI target IQN,
the iSCSI target vendor and version number.
One other directory entry is presented in the virtual target
directory, relating to the storage presented by the iSCSI target.
This can be in the form of a regular file, which is also the
default, a block device or a character device.
.Pp
Please note that the
.Nm
utility needs the
.Dq puffs
kernel module loaded via
.Xr modload 8
to operate.
.Sh EXAMPLES
.Bd -literal
# ./iscsi-initiator -u agc iscsi-target0.alistaircrooks.co.uk /mnt
# ls -al /mnt/iscsi-target0.alistaircrooks.co.uk/target0
total 576
drwxr-xr-x 2 agc agc 512 May 11 22:24 .
drwxr-xr-x 2 agc agc 512 May 11 22:24 ..
lrw-r--r-- 1 agc agc 39 May 11 22:24 hostname -\*[Gt] iscsi-target0.alistaircrooks.co.uk
lrw-r--r-- 1 agc agc 14 May 11 22:24 ip -\*[Gt] 172.16.135.130
lrw-r--r-- 1 agc agc 16 May 11 22:24 product -\*[Gt] NetBSD iSCSI
-rw-r--r-- 1 agc agc 104857600 May 11 22:24 storage
lrw-r--r-- 1 agc agc 43 May 11 22:24 targetname -\*[Gt] iqn.1994-04.org.netbsd.iscsi-target:target0
lrw-r--r-- 1 agc agc 8 May 11 22:24 vendor -\*[Gt] NetBSD
lrw-r--r-- 1 agc agc 4 May 11 22:24 version -\*[Gt] 0
#
.Ed
.Sh SEE ALSO
.Xr puffs 3 ,
.Xr refuse 3 ,
.Xr iscsi-target 8
.Sh HISTORY
The
.Nm
utility first appeared in
.Nx 5.0 .
.Sh AUTHORS
The
.Nm
utility was written by
.An Alistair Crooks
.Aq agc@NetBSD.org .

View File

@ -1,715 +0,0 @@
/*
* Copyright © 2007 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#define FUSE_USE_VERSION 26
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <fuse.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define EXTERN
#include "scsi_cmd_codes.h"
#include "iscsi.h"
#include "initiator.h"
#include "tests.h"
#include "virtdir.h"
#if defined(__NetBSD__) && defined(USE_LIBKMOD)
#include "libkmod.h"
#endif
#include "defs.h"
static int verbose; /* how chatty are we? */
static virtdir_t iscsi;
enum {
VendorLen = 8,
ProductLen = 16,
VersionLen = 4,
SGsize = 131072
};
/* this struct keeps information on the target */
typedef struct targetinfo_t {
char *host; /* resolvable host name */
char *ip; /* textual IP address */
char *targetname; /* name of iSCSI target prog */
char *stargetname; /* short name of the target */
uint64_t target; /* target number */
uint32_t lun; /* LUN number */
uint32_t lbac; /* number of LBAs */
uint32_t blocksize; /* size of device blocks */
uint32_t devicetype; /* SCSI device type */
char vendor[VendorLen + 1];
/* device vendor information */
char product[ProductLen + 1];
/* device product information */
char version[VersionLen + 1];
/* device version information */
char *serial; /* unit serial number */
} targetinfo_t;
DEFINE_ARRAY(targetv_t, targetinfo_t);
static targetv_t tv; /* target vector of targetinfo_t structs */
/* iqns and target addresses are returned as pairs in this dynamic array */
static strv_t all_targets;
/* Small Target Info... */
typedef struct sti_t {
struct stat st; /* normal stat info */
uint64_t target; /* cached target number, so we don't have an expensive pathname-based lookup */
} sti_t;
#ifndef __UNCONST
#define __UNCONST(x) (x)
#endif
/* read the capacity (maximum LBA and blocksize) from the target */
int
read_capacity(uint64_t target, uint32_t lun, uint32_t *maxlba, uint32_t *blocklen)
{
iscsi_scsi_cmd_args_t args;
initiator_cmd_t cmd;
uint8_t data[8];
uint8_t cdb[16];
(void) memset(cdb, 0x0, sizeof(cdb));
cdb[0] = READ_CAPACITY;
cdb[1] = lun << 5;
(void) memset(&args, 0x0, sizeof(args));
args.recv_data = data;
args.input = 1;
args.lun = lun;
args.trans_len = 8;
args.cdb = cdb;
(void) memset(&cmd, 0, sizeof(initiator_cmd_t));
cmd.isid = target;
cmd.type = ISCSI_SCSI_CMD;
cmd.ptr = &args;
if (initiator_command(&cmd) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "initiator_command() failed\n");
return -1;
}
if (args.status) {
iscsi_trace_error(__FILE__, __LINE__, "READ_CAPACITY failed (status %#x)\n", args.status);
return -1;
}
*maxlba = ISCSI_NTOHL(*((uint32_t *) (data)));
*blocklen = ISCSI_NTOHL(*((uint32_t *) (data + 4)));
if (*maxlba == 0) {
iscsi_trace_error(__FILE__, __LINE__, "Device returned Maximum LBA of zero\n");
return -1;
}
if (*blocklen % 2) {
iscsi_trace_error(__FILE__, __LINE__, "Device returned strange block len: %u\n", *blocklen);
return -1;
}
return 0;
}
/* send inquiry command to the target, to get it to identify itself */
static int
inquiry(uint64_t target, uint32_t lun, uint8_t type, uint8_t inquire, uint8_t *data)
{
iscsi_scsi_cmd_args_t args;
initiator_cmd_t cmd;
uint8_t cdb[16];
(void) memset(cdb, 0x0, sizeof(cdb));
cdb[0] = INQUIRY;
cdb[1] = type | (lun << 5);
cdb[2] = inquire;
cdb[4] = 256 - 1;
(void) memset(&args, 0x0, sizeof(args));
args.input = 1;
args.trans_len = 256;
args.cdb = cdb;
args.lun = lun;
args.recv_data = data;
(void) memset(&cmd, 0x0, sizeof(cmd));
cmd.isid = target;
cmd.type = ISCSI_SCSI_CMD;
cmd.ptr = &args;
if (initiator_command(&cmd) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "initiator_command() failed\n");
return -1;
}
if (args.status) {
iscsi_trace_error(__FILE__, __LINE__, "INQUIRY failed (status %#x)\n", args.status);
return -1;
}
return 0;
}
/* read or write a single block of information */
static int
blockop(uint64_t target, uint32_t lun, uint32_t lba, uint32_t len,
uint32_t blocklen, uint8_t *data, int writing)
{
iscsi_scsi_cmd_args_t args;
initiator_cmd_t cmd;
uint16_t readlen;
uint8_t cdb[16];
/* Build CDB */
(void) memset(cdb, 0, 16);
cdb[0] = (writing) ? WRITE_10 : READ_10;
cdb[1] = lun << 5;
readlen = (uint16_t) len;
lba2cdb(cdb, &lba, &readlen);
/* Build SCSI command */
(void) memset(&args, 0x0, sizeof(args));
if (writing) {
args.send_data = data;
args.output = 1;
} else {
args.recv_data = data;
args.input = 1;
}
args.lun = lun;
args.trans_len = len*blocklen;
args.length = len*blocklen;
args.cdb = cdb;
(void) memset(&cmd, 0, sizeof(initiator_cmd_t));
cmd.isid = target;
cmd.type = ISCSI_SCSI_CMD;
cmd.ptr = &args;
/* Execute iSCSI command */
if (initiator_command(&cmd) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "initiator_command() failed\n");
return -1;
}
if (args.status) {
iscsi_trace_error(__FILE__, __LINE__, "scsi_command() failed (status %#x)\n", args.status);
return -1;
}
return 0;
}
/* perform a scatter/gather block operation */
static int
sgblockop(uint64_t target, uint32_t lun, uint32_t lba, uint32_t len,
uint32_t blocklen, uint8_t *data, int sglen, int writing)
{
iscsi_scsi_cmd_args_t args;
initiator_cmd_t cmd;
uint16_t readlen;
uint8_t cdb[16];
/* Build CDB */
(void) memset(cdb, 0, 16);
cdb[0] = (writing) ? WRITE_10 : READ_10;
cdb[1] = lun << 5;
readlen = (uint16_t) len;
lba2cdb(cdb, &lba, &readlen);
/* Build iSCSI command */
(void) memset(&args, 0x0, sizeof(args));
args.lun = lun;
args.output = (writing) ? 1 : 0;
args.input = (writing) ? 0 : 1;
args.trans_len = len * blocklen;
args.length = len * blocklen;
args.send_data = (writing) ? data : NULL;
args.send_sg_len = (writing) ? sglen : 0;
args.recv_data = (writing) ? NULL : data;
args.recv_sg_len = (writing) ? 0 : sglen;
args.cdb = cdb;
memset(&cmd, 0, sizeof(initiator_cmd_t));
cmd.isid = target;
cmd.ptr = &args;
cmd.type = ISCSI_SCSI_CMD;
/* Execute iSCSI command */
if (initiator_command(&cmd) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "initiator_command() failed\n");
return -1;
}
if (args.status) {
iscsi_trace_error(__FILE__, __LINE__, "scsi_command() failed (status %#x)\n", args.status);
return -1;
}
return 0;
}
/* read info from the target - method depends on size of data being read */
static int
targetop(uint32_t t, uint64_t offset, uint32_t length, uint32_t request, char *buf, int writing)
{
struct iovec *iov;
uint32_t ioc;
uint32_t i;
int req_len;
if (request > SGsize) {
/* split up request into blocksize chunks */
ioc = request / SGsize;
if ((ioc * SGsize) < request)
ioc++;
if ((iov = iscsi_malloc(ioc * sizeof(*iov))) == NULL) {
iscsi_trace_error(__FILE__, __LINE__, "out of memory\n");
return -1;
}
for (i = 0 ; i < ioc ; i++) {
iov[i].iov_base = &buf[i * SGsize];
if (i == (ioc - 1)) { /* last one */
iov[i].iov_len = request - (i * SGsize);
} else {
iov[i].iov_len = SGsize;
}
}
if (sgblockop(tv.v[t].target, tv.v[t].lun, offset / tv.v[t].blocksize, (length / tv.v[t].blocksize), tv.v[t].blocksize, (uint8_t *) iov, ioc, writing) != 0) {
iscsi_free(iov);
iscsi_trace_error(__FILE__, __LINE__, "read_10() failed\n");
return -1;
}
iscsi_free(iov);
} else {
req_len = length / tv.v[t].blocksize;
if ((req_len * tv.v[t].blocksize) < length)
req_len++;
if (blockop(tv.v[t].target, tv.v[t].lun, offset / tv.v[t].blocksize,
req_len, tv.v[t].blocksize, (uint8_t *) buf, writing) != 0) {
iscsi_trace_error(__FILE__, __LINE__, "read_10() failed\n");
return -1;
}
}
return 0;
}
/****************************************************************************/
/* perform the stat operation */
/* if this is the root, then just synthesise the data */
/* otherwise, retrieve the data, and be sure to fill in the size */
static int
iscsifs_getattr(const char *path, struct stat *st)
{
virt_dirent_t *ep;
sti_t *p;
if (strcmp(path, "/") == 0) {
(void) memset(st, 0x0, sizeof(*st));
st->st_mode = S_IFDIR | 0755;
st->st_nlink = 2;
return 0;
}
if ((ep = virtdir_find(&iscsi, path, strlen(path))) == NULL) {
return -ENOENT;
}
switch(ep->type) {
case 'b':
(void) memcpy(st, &iscsi.file, sizeof(*st));
st->st_mode = (S_IFBLK | 0644);
break;
case 'c':
(void) memcpy(st, &iscsi.file, sizeof(*st));
st->st_mode = (S_IFCHR | 0644);
break;
case 'd':
(void) memcpy(st, &iscsi.dir, sizeof(*st));
break;
case 'f':
(void) memcpy(st, &iscsi.file, sizeof(*st));
p = (sti_t *) ep->tgt;
st->st_size = p->st.st_size;
break;
case 'l':
(void) memcpy(st, &iscsi.lnk, sizeof(*st));
st->st_size = ep->tgtlen;
break;
default:
warn("unknown directory type `%c'", ep->type);
return -ENOENT;
}
st->st_ino = ep->ino;
return 0;
}
/* readdir operation */
static int
iscsifs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info * fi)
{
virt_dirent_t *dp;
VIRTDIR *dirp;
if ((dirp = openvirtdir(&iscsi, path)) == NULL) {
return 0;
}
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
while ((dp = readvirtdir(dirp)) != NULL) {
filler(buf, dp->d_name, NULL, 0);
}
closevirtdir(dirp);
return 0;
}
/* open the file in the file system */
static int
iscsifs_open(const char *path, struct fuse_file_info *fi)
{
virt_dirent_t *ep;
const char *slash;
if ((ep = virtdir_find(&iscsi, path, strlen(path))) == NULL) {
return -ENOENT;
}
/* check path is the correct one */
if ((slash = strrchr(path, '/')) == NULL) {
slash = path;
} else {
slash += 1;
}
if (strcmp(slash, "storage") != 0) {
return -ENOENT;
}
return 0;
}
/* read the storage from the iSCSI target */
static int
iscsifs_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info * fi)
{
virt_dirent_t *ep;
uint64_t target;
sti_t *p;
if ((ep = virtdir_find(&iscsi, path, strlen(path))) == NULL) {
return -ENOENT;
}
p = (sti_t *)ep->tgt;
target = p->target;
if (targetop(target, offset, size, size, buf, 0) < 0) {
return -EPERM;
}
return size;
}
/* write the file's contents to the file system */
static int
iscsifs_write(const char *path, const char *buf, size_t size, off_t offset,
struct fuse_file_info * fi)
{
virt_dirent_t *ep;
uint64_t target;
sti_t *p;
if ((ep = virtdir_find(&iscsi, path, strlen(path))) == NULL) {
return -ENOENT;
}
p = (sti_t *)ep->tgt;
target = p->target;
if (targetop(target, offset, size, size, __UNCONST(buf), 1) < 0) {
return -EPERM;
}
return size;
}
/* fill in the statvfs struct */
static int
iscsifs_statfs(const char *path, struct statvfs *st)
{
(void) memset(st, 0x0, sizeof(*st));
return 0;
}
/* read the symbolic link */
static int
iscsifs_readlink(const char *path, char *buf, size_t size)
{
virt_dirent_t *ep;
if ((ep = virtdir_find(&iscsi, path, strlen(path))) == NULL) {
return -ENOENT;
}
if (ep->tgt == NULL) {
return -ENOENT;
}
(void) strlcpy(buf, ep->tgt, size);
return 0;
}
/* operations struct */
static struct fuse_operations iscsiops = {
.getattr = iscsifs_getattr,
.readlink = iscsifs_readlink,
.readdir = iscsifs_readdir,
.open = iscsifs_open,
.read = iscsifs_read,
.write = iscsifs_write,
.statfs = iscsifs_statfs
};
int
main(int argc, char **argv)
{
initiator_target_t tinfo;
unsigned u;
uint32_t lbac;
uint32_t blocksize;
uint8_t data[256];
sti_t sti;
char hostname[1024];
char name[1024];
char *colon;
char *host;
char *user;
int address_family;
char devtype;
int port;
int target = -1;
int digest_type;
int discover;
int mutual_auth;
int auth_type;
int cc;
int i;
(void) memset(&tinfo, 0x0, sizeof(tinfo));
user = NULL;
(void) gethostname(host = hostname, sizeof(hostname));
digest_type = DigestNone;
auth_type = AuthNone;
address_family = ISCSI_UNSPEC;
port = ISCSI_PORT;
mutual_auth = 0;
discover = 0;
(void) stat("/etc/hosts", &sti.st);
devtype = 'f';
while ((i = getopt(argc, argv, "46a:bcd:Dfh:p:t:u:vV")) != -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;
} else if (strcasecmp(optarg, "kerberos") == 0) {
auth_type = AuthKerberos;
} else if (strcasecmp(optarg, "srp") == 0) {
auth_type = AuthSRP;
}
break;
case 'b':
devtype = 'b';
break;
case 'c':
devtype = 'c';
break;
case 'd':
if (strcasecmp(optarg, "header") == 0) {
digest_type = DigestHeader;
} else if (strcasecmp(optarg, "data") == 0) {
digest_type = DigestData;
} else if (strcasecmp(optarg, "both") == 0 || strcasecmp(optarg, "all") == 0) {
digest_type = (DigestHeader | DigestData);
}
break;
case 'D':
discover = 1;
break;
case 'f':
devtype = 'f';
break;
case 'h':
host = optarg;
break;
case 'p':
port = atoi(optarg);
break;
case 't':
target = atoi(optarg);
break;
case 'u':
user = optarg;
break;
case 'V':
(void) printf("\"%s\" %s\nPlease send all bug reports to %s\n", PACKAGE_NAME, PACKAGE_VERSION, PACKAGE_BUGREPORT);
exit(EXIT_SUCCESS);
/* NOTREACHED */
case 'v':
verbose += 1;
break;
default:
(void) fprintf(stderr, "%s: unknown option `%c'", *argv, i);
}
}
if (user == NULL) {
iscsi_trace_error(__FILE__, __LINE__, "user must be specified with -u");
exit(EXIT_FAILURE);
}
if (initiator_init(host, port, address_family, user, auth_type, mutual_auth, digest_type) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "initiator_init() failed\n");
exit(EXIT_FAILURE);
}
if (initiator_discover(host, 0, 0) < 0) {
printf("initiator_discover() in discover failed\n");
exit(EXIT_FAILURE);
}
if (initiator_get_targets(0,&all_targets) == -1) {
iscsi_trace_error(__FILE__, __LINE__, "initiator_get_targets() failed\n");
exit(EXIT_FAILURE);
}
if (discover) {
printf("Targets available from host %s:\n",host);
for (u = 0; u < all_targets.c ; u += 2) {
printf("%s at %s\n", all_targets.v[u],
all_targets.v[u + 1]);
}
exit(EXIT_SUCCESS);
}
if (all_targets.c/2 > CONFIG_INITIATOR_NUM_TARGETS) {
(void) fprintf(stderr, "CONFIG_INITIATOR_NUM_TARGETS in initiator.h is too small. %d targets available, only %d configurable.\n", all_targets.c/2, CONFIG_INITIATOR_NUM_TARGETS);
(void) fprintf(stderr, "Truncating number of targets to %d.\n", CONFIG_INITIATOR_NUM_TARGETS);
all_targets.c = CONFIG_INITIATOR_NUM_TARGETS;
}
sti.st.st_ino = 0x15c51;
#if defined(__NetBSD__) && defined(USE_LIBKMOD)
/* check that the puffs module is loaded on NetBSD */
if (kmodstat("puffs", NULL) == 0 && !kmodload("puffs")) {
(void) fprintf(stderr, "initiator: can't load puffs module\n");
}
#endif
for (u = 0 ; u < all_targets.c / 2 ; u++) {
ALLOC(targetinfo_t, tv.v, tv.size, tv.c, 10, 10, "iscsifs",
exit(EXIT_FAILURE));
initiator_set_target_name(u, all_targets.v[u * 2]);
if (initiator_discover(host, u, 0) < 0) {
printf("initiator_discover() failed\n");
break;
}
get_target_info(u, &tinfo);
if ((colon = strrchr(tinfo.TargetName, ':')) == NULL) {
colon = tinfo.TargetName;
} else {
colon += 1;
}
/* stuff size into st.st_size */
(void) read_capacity(u, 0, &lbac, &blocksize);
sti.st.st_size = ((uint64_t)lbac + 1) * blocksize;
sti.target = u;
tv.v[tv.c].host = strdup(tinfo.name);
tv.v[tv.c].ip = strdup(tinfo.ip);
tv.v[tv.c].targetname = strdup(tinfo.TargetName);
tv.v[tv.c].stargetname = strdup(colon);
tv.v[tv.c].target = u;
tv.v[tv.c].lun = 0;
tv.v[tv.c].lbac = lbac;
tv.v[tv.c].blocksize = blocksize;
/* get iSCSI target information */
(void) memset(data, 0x0, sizeof(data));
inquiry(u, 0, 0, 0, data);
tv.v[tv.c].devicetype = (data[0] & 0x1f);
(void) memcpy(tv.v[tv.c].vendor, &data[8], VendorLen);
(void) memcpy(tv.v[tv.c].product, &data[8 + VendorLen], ProductLen);
(void) memcpy(tv.v[tv.c].version, &data[8 + VendorLen + ProductLen], VersionLen);
(void) memset(data, 0x0, sizeof(data));
inquiry(u, 0, INQUIRY_EVPD_BIT, INQUIRY_UNIT_SERIAL_NUMBER_VPD, data);
tv.v[tv.c].serial = strdup((char *)&data[4]);
cc = snprintf(name, sizeof(name), "/%s/%s", host, colon);
virtdir_add(&iscsi, name, cc, 'd', name, cc);
cc = snprintf(name, sizeof(name), "/%s/%s/storage", host, colon);
virtdir_add(&iscsi, name, cc, devtype, (void *)&sti, sizeof(sti));
cc = snprintf(name, sizeof(name), "/%s/%s/hostname", host, colon);
virtdir_add(&iscsi, name, cc, 'l', tinfo.name, strlen(tinfo.name));
cc = snprintf(name, sizeof(name), "/%s/%s/ip", host, colon);
virtdir_add(&iscsi, name, cc, 'l', tinfo.ip, strlen(tinfo.ip));
cc = snprintf(name, sizeof(name), "/%s/%s/targetname", host, colon);
virtdir_add(&iscsi, name, cc, 'l', tinfo.TargetName, strlen(tinfo.TargetName));
cc = snprintf(name, sizeof(name), "/%s/%s/vendor", host, colon);
virtdir_add(&iscsi, name, cc, 'l', tv.v[tv.c].vendor, strlen(tv.v[tv.c].vendor));
cc = snprintf(name, sizeof(name), "/%s/%s/product", host, colon);
virtdir_add(&iscsi, name, cc, 'l', tv.v[tv.c].product, strlen(tv.v[tv.c].product));
cc = snprintf(name, sizeof(name), "/%s/%s/version", host, colon);
virtdir_add(&iscsi, name, cc, 'l', tv.v[tv.c].version, strlen(tv.v[tv.c].version));
if (tv.v[tv.c].serial[0] && tv.v[tv.c].serial[0] != ' ') {
cc = snprintf(name, sizeof(name), "/%s/%s/serial", host, colon);
virtdir_add(&iscsi, name, cc, 'l', tv.v[tv.c].serial, strlen(tv.v[tv.c].serial));
}
tv.c += 1;
}
return fuse_main(argc - optind, argv + optind, &iscsiops, NULL);
}

View File

@ -1,219 +0,0 @@
/* $NetBSD: libkmod.c,v 1.1 2009/06/20 04:12:55 agc Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: libkmod.c,v 1.1 2009/06/20 04:12:55 agc Exp $");
#endif /* !lint */
#include <sys/module.h>
#include <prop/proplib.h>
#include <assert.h>
#include <err.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "libkmod.h"
#ifdef USE_LIBKMOD
static const char *classes[] = {
"any",
"misc",
"vfs",
"driver",
"exec",
};
static const char *sources[] = {
"builtin",
"boot",
"filesys",
};
/* comparison routine for qsort */
static int
modcmp(const void *a, const void *b)
{
const modstat_t *msa, *msb;
msa = a;
msb = b;
return strcmp(msa->ms_name, msb->ms_name);
}
/* function which "opens" a module */
int
openkmod(kernel_t *kernel)
{
kernel->size = 4096;
for (;;) {
kernel->iov.iov_base = malloc(kernel->size);
kernel->iov.iov_len = kernel->size;
if (modctl(MODCTL_STAT, &kernel->iov)) {
warn("modctl(MODCTL_STAT)");
return 0;
}
if (kernel->size >= kernel->iov.iov_len) {
break;
}
free(kernel->iov.iov_base);
kernel->size = kernel->iov.iov_len;
}
kernel->size = kernel->iov.iov_len / sizeof(modstat_t);
qsort(kernel->iov.iov_base, kernel->size, sizeof(modstat_t), modcmp);
return 1;
}
/* return details on the module */
int
readkmod(kernel_t *kernel, kmod_t *module)
{
modstat_t *ms;
if (kernel->c * sizeof(*ms) >= kernel->iov.iov_len) {
return 0;
}
ms = kernel->iov.iov_base;
ms += kernel->c++;
(void) memset(module, 0x0, sizeof(*module));
module->name = strdup(ms->ms_name);
module->class = strdup(classes[ms->ms_class]);
module->source = strdup(sources[ms->ms_source]);
module->refcnt = ms->ms_refcnt;
module->size = ms->ms_size;
if (ms->ms_required[0]) {
module->required = strdup(ms->ms_required);
}
return 1;
}
/* free up all resources allocated in a module read */
void
freekmod(kmod_t *module)
{
(void) free(module->name);
(void) free(module->class);
(void) free(module->source);
if (module->required) {
(void) free(module->required);
}
}
/* "close" the module */
int
closekmod(kernel_t *kernel)
{
(void) free(kernel->iov.iov_base);
return 1;
}
/* do the modstat operation */
int
kmodstat(const char *modname, FILE *fp)
{
kernel_t kernel;
kmod_t module;
int modc;
(void) memset(&kernel, 0x0, sizeof(kernel));
(void) memset(&module, 0x0, sizeof(module));
if (!openkmod(&kernel)) {
(void) fprintf(stderr, "can't read kernel modules\n");
return 0;
}
for (modc = 0 ; readkmod(&kernel, &module) ; ) {
if (modname == NULL || strcmp(modname, module.name) == 0) {
if (modc++ == 0) {
if (fp) {
(void) fprintf(fp,
"NAME\t\tCLASS\tSOURCE\tREFS"
"\tSIZE\tREQUIRES\n");
}
}
if (fp) {
(void) fprintf(fp, "%-16s%s\t%s\t%d\t%u\t%s\n",
module.name,
module.class,
module.source,
module.refcnt,
module.size,
(module.required) ? module.required : "-");
}
freekmod(&module);
}
}
(void) closekmod(&kernel);
return modc;
}
/* load the named module into the kernel */
int
kmodload(const char *module)
{
prop_dictionary_t props;
modctl_load_t cmdargs;
char *propsstr;
props = prop_dictionary_create();
propsstr = prop_dictionary_externalize(props);
if (propsstr == NULL) {
(void) fprintf(stderr, "Failed to process properties");
return 0;
}
cmdargs.ml_filename = module;
cmdargs.ml_flags = 0;
cmdargs.ml_props = propsstr;
cmdargs.ml_propslen = strlen(propsstr);
if (modctl(MODCTL_LOAD, &cmdargs)) {
(void) fprintf(stderr, "modctl failure\n");
return 0;
}
(void) free(propsstr);
prop_object_release(props);
return 1;
}
/* and unload the module from the kernel */
int
kmodunload(const char *name)
{
return modctl(MODCTL_UNLOAD, __UNCONST(name)) == 0;
}
#endif /* USE_LIBKMOD */

View File

@ -1,63 +0,0 @@
/* $NetBSD: libkmod.h,v 1.1 2009/06/20 04:12:55 agc Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LIBKMOD_H_
#define LIBKMOD_H_ 20090619
#include <sys/module.h>
#include <stdio.h>
/* this struct describes the loaded modules in the kernel */
typedef struct kernel_t {
size_t size; /* size of iovec array */
size_t c; /* counter during "read" operations */
struct iovec iov; /* iovecs from the modctl operation */
} kernel_t;
/* this struct describes a module */
typedef struct kmod_t {
char *name; /* module name */
char *class; /* module class */
char *source; /* source of module loading */
int refcnt; /* reference count */
unsigned size; /* size of binary module */
char *required; /* any pre-reqs module has */
} kmod_t;
/* low level open, read, write ops */
int openkmod(kernel_t *);
int readkmod(kernel_t *, kmod_t *);
void freekmod(kmod_t *);
int closekmod(kernel_t *);
/* high-level kmod operations */
int kmodstat(const char *, FILE *);
int kmodload(const char *);
int kmodunload(const char *);
#endif

View File

@ -1,332 +0,0 @@
/*
* Copyright © 2007 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#define FUSE_USE_VERSION 26
#include <fuse.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "virtdir.h"
#include "defs.h"
/* utility comparison routine for sorting and searching */
static int
compare(const void *vp1, const void *vp2)
{
const virt_dirent_t *tp1 = (const virt_dirent_t *) vp1;
const virt_dirent_t *tp2 = (const virt_dirent_t *) vp2;
return strcmp(tp1->name, tp2->name);
}
/* save `n' chars of `s' in allocated storage */
static char *
strnsave(const char *s, int n)
{
char *cp;
if (n < 0) {
n = strlen(s);
}
NEWARRAY(char, cp, n + 1, "strnsave", return NULL);
(void) memcpy(cp, s, n);
cp[n] = 0x0;
return cp;
}
/* ensure intermediate directories exist */
static void
mkdirs(virtdir_t *tp, const char *path, size_t size)
{
virt_dirent_t *ep;
char name[MAXPATHLEN];
char *slash;
(void) strlcpy(name, path, sizeof(name));
for (slash = name + 1 ; (slash = strchr(slash + 1, '/')) != NULL ; ) {
*slash = 0x0;
if ((ep = virtdir_find(tp, name, strlen(name))) == NULL) {
virtdir_add(tp, name, strlen(name), 'd', NULL, 0);
}
*slash = '/';
}
}
/* get rid of multiple slashes in input */
static int
normalise(const char *name, size_t namelen, char *path, size_t pathsize)
{
const char *np;
char *pp;
int done;
for (pp = path, np = name, done = 0 ;
!done && (unsigned)(pp - path) < pathsize - 1 &&
(unsigned)(np - name) <= namelen ; ) {
switch(*np) {
case '/':
if (pp == path || *(pp - 1) != '/') {
*pp++ = *np;
}
np += 1;
break;
case 0x0:
done = 1;
break;
default:
*pp++ = *np++;
break;
}
}
/* XXX - trailing slash? */
*pp = 0x0;
return (int)(pp - path);
}
/* initialise the tree */
int
virtdir_init(virtdir_t *tp, const char *rootdir, struct stat *d, struct stat *f, struct stat *l)
{
(void) memcpy(&tp->dir, d, sizeof(tp->dir));
tp->dir.st_mode = S_IFDIR | 0755;
tp->dir.st_nlink = 2;
(void) memcpy(&tp->file, f, sizeof(tp->file));
tp->file.st_mode = S_IFREG | 0644;
tp->file.st_nlink = 1;
(void) memcpy(&tp->lnk, l, sizeof(tp->lnk));
tp->lnk.st_mode = S_IFLNK | 0644;
tp->lnk.st_nlink = 1;
if (rootdir != NULL) {
tp->rootdir = strdup(rootdir);
}
return 1;
}
/* add an entry to the tree */
int
virtdir_add(virtdir_t *tp, const char *name, size_t size, uint8_t type, const char *tgt, size_t tgtlen)
{
struct stat st;
char path[MAXPATHLEN];
int pathlen;
if (tp->v == NULL) {
(void) stat(".", &st);
virtdir_init(tp, NULL, &st, &st, &st);
}
pathlen = normalise(name, size, path, sizeof(path));
if (virtdir_find(tp, path, pathlen) != NULL) {
/* attempt to add a duplicate directory entry */
return 0;
}
ALLOC(virt_dirent_t, tp->v, tp->size, tp->c, 10, 10, "virtdir_add",
return 0);
tp->v[tp->c].namelen = pathlen;
if ((tp->v[tp->c].name = strnsave(path, pathlen)) == NULL) {
return 0;
}
tp->v[tp->c].d_name = strrchr(tp->v[tp->c].name, '/') + 1;
tp->v[tp->c].type = type;
tp->v[tp->c].ino = (ino_t) random() & 0xfffff;
if (tgt != NULL) {
tp->v[tp->c].tgtlen = tgtlen;
tp->v[tp->c].tgt = strnsave(tgt, tgtlen);
}
tp->c += 1;
qsort(tp->v, tp->c, sizeof(tp->v[0]), compare);
mkdirs(tp, path, pathlen);
return 1;
}
/* delete an entry from the tree */
int
virtdir_del(virtdir_t *tp, const char *name, size_t size)
{
virt_dirent_t *ep;
unsigned i;
if ((ep = virtdir_find(tp, name, size)) == NULL) {
return 0;
}
i = (int)(ep - tp->v);
for (tp->c -= 1 ; i < tp->c ; i++) {
tp->v[i] = tp->v[i + 1];
}
return 1;
}
/* find an entry in the tree */
virt_dirent_t *
virtdir_find(virtdir_t *tp, const char *name, size_t namelen)
{
virt_dirent_t e;
char path[MAXPATHLEN];
(void) memset(&e, 0x0, sizeof(e));
e.namelen = normalise(name, namelen, path, sizeof(path));
e.name = path;
return bsearch(&e, tp->v, tp->c, sizeof(tp->v[0]), compare);
}
/* return the virtual offset in the tree */
int
virtdir_offset(virtdir_t *tp, virt_dirent_t *dp)
{
return (int)(dp - tp->v);
}
/* analogous to opendir(3) - open a directory, save information, and
* return a pointer to the dynamically allocated structure */
VIRTDIR *
openvirtdir(virtdir_t *tp, const char *d)
{
VIRTDIR *dirp;
NEW(VIRTDIR, dirp, "openvirtdir", exit(EXIT_FAILURE));
dirp->dirname = strdup(d);
dirp->dirnamelen = strlen(d);
dirp->tp = tp;
dirp->i = 0;
return dirp;
}
/* analogous to readdir(3) - read the next entry in the directory that
* was opened, and return a pointer to it */
virt_dirent_t *
readvirtdir(VIRTDIR *dirp)
{
char *from;
for ( ; dirp->i < dirp->tp->c ; dirp->i++) {
from = (strcmp(dirp->dirname, "/") == 0) ?
&dirp->tp->v[dirp->i].name[1] :
&dirp->tp->v[dirp->i].name[dirp->dirnamelen + 1];
if (strncmp(dirp->tp->v[dirp->i].name, dirp->dirname,
dirp->dirnamelen) == 0 &&
*from != 0x0 &&
strchr(from, '/') == NULL) {
return &dirp->tp->v[dirp->i++];
}
}
return NULL;
}
/* free the storage associated with the virtual directory structure */
void
closevirtdir(VIRTDIR *dirp)
{
free(dirp->dirname);
FREE(dirp);
}
/* find a target in the tree -- not quick! */
virt_dirent_t *
virtdir_find_tgt(virtdir_t *tp, const char *tgt, size_t tgtlen)
{
/* we don't need no stinking binary searches */
unsigned i;
char path[MAXPATHLEN];
(void) normalise(tgt, tgtlen, path, sizeof(path));
for (i = 0 ; i < tp->c ; i++) {
if (tp->v[i].tgt && strcmp(tp->v[i].tgt, path) == 0) {
return &tp->v[i];
}
}
return NULL;
}
/* kill all of the space allocated to the tree */
void
virtdir_drop(virtdir_t *tp)
{
unsigned i;
for (i = 0 ; i < tp->c ; i++) {
FREE(tp->v[i].name);
if (tp->v[i].tgt) {
FREE(tp->v[i].tgt);
}
}
FREE(tp->v);
}
/* return the value of the root directory of the tree */
char *
virtdir_rootdir(virtdir_t *tp)
{
return tp->rootdir;
}
#ifdef VIRTDIR_DEBUG
static void
ptree(virtdir_t * tp)
{
int i;
for (i = 0 ; i < tp->c ; i++) {
printf("%s, tgt %s\n", tp->v[i].name, tp->v[i].tgt);
}
}
#endif
#ifdef VIRTDIR_DEBUG
int
main(int argc, char **argv)
{
virt_dirent_t *tp;
virtdir_t t;
struct stat st;
(void) memset(&t, 0x0, sizeof(t));
stat(".", &st);
virtdir_add(&t, ".", 1, 'd', NULL, 0);
stat("..", &st);
virtdir_add(&t, "..", 2, 'd', NULL, 0);
st.st_mode = S_IFREG | 0644;
virtdir_add(&t, "file1", 5, 'f', NULL, 0);
ptree(&t);
virtdir_add(&t, "file2", 5, 'f', NULL, 0);
virtdir_add(&t, "file0", 5, 'f', NULL, 0);
virtdir_add(&t, "abcde", 5, 'f', NULL, 0);
virtdir_add(&t, "bcdef", 5, 'f', NULL, 0);
virtdir_add(&t, "a", 1, 'f', NULL, 0);
ptree(&t);
if ((tp = virtdir_find(&t, "a", 1)) == NULL) {
printf("borked2\n");
} else {
printf("a found\n");
}
virtdir_drop(&t);
exit(EXIT_SUCCESS);
}
#endif

View File

@ -1,83 +0,0 @@
/*
* Copyright © 2007 Alistair Crooks. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FUSE_TREE_H_
#define FUSE_TREE_H_ 20070405
#include <sys/types.h>
#include <sys/stat.h>
#include <fuse.h>
#include "defs.h"
/* this struct keeps a note of all the info related to a virtual directory entry */
typedef struct virt_dirent_t {
char *name; /* entry name - used as key */
size_t namelen; /* length of name */
char *d_name; /* component in this directory */
char *tgt; /* any symlink target */
size_t tgtlen; /* length of symlink target */
uint8_t type; /* entry type - file, dir, lnk */
ino_t ino; /* inode number */
} virt_dirent_t;
/* this defines the list of virtual directory entries,
sorted in name alpha order */
typedef struct virtdir_t {
uint32_t c; /* count of entries */
uint32_t size; /* size of allocated list */
virt_dirent_t *v; /* list */
char *rootdir; /* root directory of virtual fs */
struct stat file; /* stat struct for file entries */
struct stat dir; /* stat struct for dir entries */
struct stat lnk; /* stat struct for symlinks */
} virtdir_t;
/* this struct is used to walk through directories */
typedef struct VIRTDIR {
char *dirname; /* directory name */
int dirnamelen; /* length of directory name */
virtdir_t *tp; /* the directory tree */
unsigned i; /* current offset in dir tree */
} VIRTDIR;
int virtdir_init(virtdir_t *, const char *, struct stat *, struct stat *, struct stat *);
int virtdir_add(virtdir_t *, const char *, size_t, uint8_t, const char *, size_t);
int virtdir_del(virtdir_t *, const char *, size_t);
virt_dirent_t *virtdir_find(virtdir_t *, const char *, size_t);
virt_dirent_t *virtdir_find_tgt(virtdir_t *, const char *, size_t);
void virtdir_drop(virtdir_t *);
char *virtdir_rootdir(virtdir_t *);
VIRTDIR *openvirtdir(virtdir_t *, const char *);
virt_dirent_t *readvirtdir(VIRTDIR *);
void closevirtdir(VIRTDIR *);
int virtdir_offset(virtdir_t *, virt_dirent_t *);
#endif

View File

@ -1,21 +0,0 @@
# $NetBSD: Makefile,v 1.4 2009/04/22 15:23:04 lukem Exp $
.sinclude "${.CURDIR}/../../Makefile.inc"
.include <bsd.own.mk>
USE_FORT?=yes # network server
DIST= ${.CURDIR}/../../../dist/iscsi
.PATH: ${DIST}/src
PROG= iscsi-target
SRCS= iscsi-target.c
CPPFLAGS+= -DCONFIG_ISCSI_DEBUG
CPPFLAGS+= -I${DIST}/include
CPPFLAGS+= -pthread
LDADD+= -liscsi
LDFLAGS+= -pthread
MAN=iscsi-target.8 targets.5
.include <bsd.prog.mk>