Add the reachover framework for the iSCSI target and initiator, in
preparation for moving it from dist/iscsi to the external framework external/bsd/iscsi.
This commit is contained in:
parent
1b829b2a68
commit
6a58b20453
11
external/bsd/iscsi/Makefile
vendored
Normal file
11
external/bsd/iscsi/Makefile
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
# $NetBSD: Makefile,v 1.1 2009/06/21 21:11:16 agc Exp $
|
||||
|
||||
.if exists(${.CURDIR}/../../Makefile.inc)
|
||||
.include "${.CURDIR}/../../Makefile.inc"
|
||||
.endif
|
||||
|
||||
SUBDIR= lib .WAIT
|
||||
|
||||
SUBDIR+= target initiator
|
||||
|
||||
.include <bsd.subdir.mk>
|
25
external/bsd/iscsi/initiator/Makefile
vendored
Normal file
25
external/bsd/iscsi/initiator/Makefile
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
# $NetBSD: Makefile,v 1.1 2009/06/21 21:11:16 agc Exp $
|
||||
|
||||
.sinclude "${.CURDIR}/../../Makefile.inc"
|
||||
|
||||
USE_FORT?=yes # network client
|
||||
|
||||
PROG=iscsi-initiator
|
||||
SRCS=iscsi-initiator.c virtdir.c initiator.c libkmod.c
|
||||
LDADD+= -lrefuse -liscsi
|
||||
DPADD+= ${LIBREFUSE} ${LIBISCSI}
|
||||
CPPFLAGS+= -g -I${ISCSI_DIST}/include
|
||||
MAN=iscsi-initiator.8
|
||||
WARNS=4
|
||||
|
||||
ISCSI_DIST=${.CURDIR}/../dist
|
||||
|
||||
.ifdef MODULAR_KERNEL
|
||||
CPPFLAGS+= -DUSE_LIBKMOD
|
||||
LDADD+= -lprop
|
||||
DPADD+= ${LIBPROP}
|
||||
.endif
|
||||
|
||||
.PATH: ${ISCSI_DIST}/src
|
||||
|
||||
.include <bsd.prog.mk>
|
150
external/bsd/iscsi/initiator/iscsi-initiator.8
vendored
Normal file
150
external/bsd/iscsi/initiator/iscsi-initiator.8
vendored
Normal file
@ -0,0 +1,150 @@
|
||||
.\" $NetBSD: iscsi-initiator.8,v 1.1 2009/06/21 21:11:16 agc 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 .
|
715
external/bsd/iscsi/initiator/iscsi-initiator.c
vendored
Normal file
715
external/bsd/iscsi/initiator/iscsi-initiator.c
vendored
Normal file
@ -0,0 +1,715 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
219
external/bsd/iscsi/initiator/libkmod.c
vendored
Normal file
219
external/bsd/iscsi/initiator/libkmod.c
vendored
Normal file
@ -0,0 +1,219 @@
|
||||
/* $NetBSD: libkmod.c,v 1.1 2009/06/21 21:11:16 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/21 21:11:16 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 */
|
63
external/bsd/iscsi/initiator/libkmod.h
vendored
Normal file
63
external/bsd/iscsi/initiator/libkmod.h
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
/* $NetBSD: libkmod.h,v 1.1 2009/06/21 21:11:16 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
|
332
external/bsd/iscsi/initiator/virtdir.c
vendored
Normal file
332
external/bsd/iscsi/initiator/virtdir.c
vendored
Normal file
@ -0,0 +1,332 @@
|
||||
/*
|
||||
* 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
|
83
external/bsd/iscsi/initiator/virtdir.h
vendored
Normal file
83
external/bsd/iscsi/initiator/virtdir.h
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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
|
22
external/bsd/iscsi/lib/Makefile
vendored
Normal file
22
external/bsd/iscsi/lib/Makefile
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
# $NetBSD: Makefile,v 1.1 2009/06/21 21:11:16 agc Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
USE_FORT?= yes # network protocol library
|
||||
|
||||
LIB= iscsi
|
||||
SRCS= conffile.c disk.c target.c iscsi.c util.c parameters.c storage.c
|
||||
SRCS+= netmask.c md5c.c md5hl.c
|
||||
CPPFLAGS+= -DCONFIG_ISCSI_DEBUG -DHAVE_CONFIG_H
|
||||
CPPFLAGS+= -I${ISCSI_DIST}/include
|
||||
CPPFLAGS+= -pthread
|
||||
LDFLAGS+= -pthread
|
||||
NOMAN= # defined
|
||||
WARNS=4
|
||||
|
||||
ISCSI_DIST= ${.CURDIR}/../dist
|
||||
.PATH: ${ISCSI_DIST}/src
|
||||
|
||||
LIBDPLIBS+= pthread ${NETBSDSRCDIR}/lib/libpthread
|
||||
|
||||
.include <bsd.lib.mk>
|
5
external/bsd/iscsi/lib/shlib_version
vendored
Normal file
5
external/bsd/iscsi/lib/shlib_version
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# $NetBSD: shlib_version,v 1.1 2009/06/21 21:11:16 agc Exp $
|
||||
# Remember to update distrib/sets/lists/base/shl.* when changing
|
||||
#
|
||||
major=1
|
||||
minor=0
|
21
external/bsd/iscsi/target/Makefile
vendored
Normal file
21
external/bsd/iscsi/target/Makefile
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# $NetBSD: Makefile,v 1.1 2009/06/21 21:11:17 agc Exp $
|
||||
|
||||
.sinclude "${.CURDIR}/../../Makefile.inc"
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
USE_FORT?=yes # network server
|
||||
|
||||
ISCSI_DIST= ${.CURDIR}/../dist
|
||||
.PATH: ${ISCSI_DIST}/src
|
||||
|
||||
PROG= iscsi-target
|
||||
SRCS= iscsi-target.c
|
||||
CPPFLAGS+= -DCONFIG_ISCSI_DEBUG
|
||||
CPPFLAGS+= -I${ISCSI_DIST}/include
|
||||
CPPFLAGS+= -pthread
|
||||
LDADD+= -liscsi
|
||||
LDFLAGS+= -pthread
|
||||
MAN=iscsi-target.8 targets.5
|
||||
|
||||
.include <bsd.prog.mk>
|
Loading…
x
Reference in New Issue
Block a user