Tue Jun 23 05:11:47 2009 UTC ()
Apply some fixes from HEO SeonMeyong to allow the iSCSI target to build
and operate on Mac OS X - with apologies for taking so long to apply them.


(agc)
diff -r1.9 -r1.10 src/dist/iscsi/include/compat.h
diff -r1.5 -r1.6 src/dist/iscsi/include/storage.h
diff -r1.39 -r1.40 src/dist/iscsi/src/disk.c
diff -r1.3 -r1.4 src/dist/iscsi/src/uuid.c

cvs diff -r1.9 -r1.10 src/dist/iscsi/include/Attic/compat.h (switch to unified diff)

--- src/dist/iscsi/include/Attic/compat.h 2007/12/06 00:08:05 1.9
+++ src/dist/iscsi/include/Attic/compat.h 2009/06/23 05:11:46 1.10
@@ -1,101 +1,77 @@ @@ -1,101 +1,77 @@
1#ifndef COMPAT_H_ 1#ifndef COMPAT_H_
2#define COMPAT_H_ 2#define COMPAT_H_
3 3
4#include "config.h" 4#include "config.h"
5 5
6#include <sys/types.h> 6#include <sys/types.h>
7 7
8#ifdef HAVE_STDINT_H 8#ifdef HAVE_STDINT_H
9#include <stdint.h> 9#include <stdint.h>
10#endif 10#endif
11 11
12#ifdef HAVE_ASM_BYTEORDER_H 12#ifdef HAVE_ASM_BYTEORDER_H
13#include <asm/byteorder.h> 13#include <asm/byteorder.h>
14#endif 14#endif
15 15
16#ifdef HAVE_SYS_BYTEORDER_H 16#ifdef HAVE_SYS_BYTEORDER_H
17# include <sys/byteorder.h> 17# include <sys/byteorder.h>
18# if defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) 18# if defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
19# undef _BIG_ENDIAN 19# undef _BIG_ENDIAN
20# define _BIG_ENDIAN 4321 20# define _BIG_ENDIAN 4321
21# define _BYTE_ORDER _BIG_ENDIAN 21# define _BYTE_ORDER _BIG_ENDIAN
22# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) 22# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
23# undef _LITTLE_ENDIAN 23# undef _LITTLE_ENDIAN
24# define _LITTLE_ENDIAN 1234 24# define _LITTLE_ENDIAN 1234
25# define _BYTE_ORDER _LITTLE_ENDIAN 25# define _BYTE_ORDER _LITTLE_ENDIAN
26# endif 26# endif
27#endif 27#endif
28 28
29#ifdef HAVE_BYTESWAP_H 29#ifdef HAVE_BYTESWAP_H
30#include <byteswap.h> 30#include <byteswap.h>
31#endif 31#endif
32  32
33#ifdef HAVE_MACHINE_ENDIAN_H 33#ifdef HAVE_MACHINE_ENDIAN_H
34#include <machine/endian.h> 34#include <machine/endian.h>
35#endif 35#endif
36 36
37#ifdef HAVE_LIBKERN_OSBYTEORDER_H 37#ifdef HAVE_LIBKERN_OSBYTEORDER_H
38#include <libkern/OSByteOrder.h> 38#include <libkern/OSByteOrder.h>
39#endif 39#endif
40 40
41#ifndef HAVE_STRLCPY 41#ifndef HAVE_STRLCPY
42size_t strlcpy(char *, const char *, size_t); 42size_t strlcpy(char *, const char *, size_t);
43#endif 43#endif
44 44
45#ifndef __UNCONST 45#ifndef __UNCONST
46#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a)) 46#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
47#endif 47#endif
48 48
49#ifdef HAVE_HTOBE64 49#ifdef HAVE_HTOBE64
50# define ISCSI_HTOBE64(x) htobe64(x) 50# define ISCSI_HTOBE64(x) htobe64(x)
51# define ISCSI_BE64TOH(x) be64toh(x) 51# define ISCSI_BE64TOH(x) be64toh(x)
52#else 52#else
53# if defined(HAVE_LIBKERN_OSBYTEORDER_H) 53# if defined(HAVE_LIBKERN_OSBYTEORDER_H)
54# define ISCSI_HTOBE64(x) (x) = OSSwapBigToHostInt64((u_int64_t)(x)) 54# define ISCSI_HTOBE64(x) (x) = OSSwapBigToHostInt64((u_int64_t)(x))
55# elif _BYTE_ORDER == _BIG_ENDIAN 55# elif _BYTE_ORDER == _BIG_ENDIAN
56# define ISCSI_HTOBE64(x) (x) 56# define ISCSI_HTOBE64(x) (x)
57# elif defined(HAVE___BSWAP64) 57# elif defined(HAVE___BSWAP64)
58# define ISCSI_HTOBE64(x) (x) = __bswap64((u_int64_t)(x)) 58# define ISCSI_HTOBE64(x) (x) = __bswap64((u_int64_t)(x))
59# else /* LITTLE_ENDIAN */ 59# else /* LITTLE_ENDIAN */
60# define ISCSI_HTOBE64(x) (((uint64_t)(ISCSI_NTOHL((uint32_t)(((x) << 32) >> 32))) << 32) | (uint32_t)ISCSI_NTOHL(((uint32_t)((x) >> 32)))) 60# define ISCSI_HTOBE64(x) (((uint64_t)(ISCSI_NTOHL((uint32_t)(((x) << 32) >> 32))) << 32) | (uint32_t)ISCSI_NTOHL(((uint32_t)((x) >> 32))))
61# endif /* LITTLE_ENDIAN */ 61# endif /* LITTLE_ENDIAN */
62# define ISCSI_BE64TOH(x) ISCSI_HTOBE64(x) 62# define ISCSI_BE64TOH(x) ISCSI_HTOBE64(x)
63#endif 63#endif
64 64
65#ifndef _DIAGASSERT 65#ifndef _DIAGASSERT
66# ifndef __static_cast 66# ifndef __static_cast
67# define __static_cast(x,y) (x)y 67# define __static_cast(x,y) (x)y
68# endif 68# endif
69#define _DIAGASSERT(e) (__static_cast(void,0)) 69#define _DIAGASSERT(e) (__static_cast(void,0))
70#endif 70#endif
71 71
72/* Added for busybox, which doesn't define INFTIM */ 72/* Added for busybox, which doesn't define INFTIM */
73#ifndef INFTIM 73#ifndef INFTIM
74#define INFTIM -1 74#define INFTIM -1
75#endif 75#endif
76 76
77#ifndef HAVE_UUID_H 
78/* Length of a node address (an IEEE 802 address). */ 
79#define _UUID_NODE_LEN 6 
80 
81/* 
82 * See also: 
83 * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt 
84 * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm 
85 * 
86 * A DCE 1.1 compatible source representation of UUIDs. 
87 */ 
88typedef struct uuid_t { 
89 uint32_t time_low; 
90 uint16_t time_mid; 
91 uint16_t time_hi_and_version; 
92 uint8_t clock_seq_hi_and_reserved; 
93 uint8_t clock_seq_low; 
94 uint8_t node[_UUID_NODE_LEN]; 
95} uuid_t; 
96 
97void uuid_create(uuid_t *, uint32_t *); 
98void uuid_to_string(uuid_t *, char **, uint32_t *); 
99#endif 
100 
101#endif /* COMPAT_H_ */ 77#endif /* COMPAT_H_ */

cvs diff -r1.5 -r1.6 src/dist/iscsi/include/Attic/storage.h (switch to unified diff)

--- src/dist/iscsi/include/Attic/storage.h 2007/12/09 09:16:42 1.5
+++ src/dist/iscsi/include/Attic/storage.h 2009/06/23 05:11:46 1.6
@@ -1,96 +1,118 @@ @@ -1,96 +1,118 @@
1/* $NetBSD: storage.h,v 1.5 2007/12/09 09:16:42 agc Exp $ */ 1/* $NetBSD: storage.h,v 1.6 2009/06/23 05:11:46 agc Exp $ */
2 2
3/* 3/*
4 * Copyright © 2006 Alistair Crooks. All rights reserved. 4 * Copyright © 2006 Alistair Crooks. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote 14 * 3. The name of the author may not be used to endorse or promote
15 * products derived from this software without specific prior written 15 * products derived from this software without specific prior written
16 * permission. 16 * permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30#ifndef STORAGE_H_ 30#ifndef STORAGE_H_
31#define STORAGE_H_ 31#define STORAGE_H_
32 32
33#include "defs.h" 33#include "defs.h"
34 34
 35/* Length of a node address (an IEEE 802 address). */
 36#define NB_UUID_NODE_LEN 6
 37
 38/*
 39 * See also:
 40 * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
 41 * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
 42 *
 43 * A DCE 1.1 compatible source representation of UUIDs.
 44 */
 45typedef struct nbuuid_t {
 46 uint32_t time_low;
 47 uint16_t time_mid;
 48 uint16_t time_hi_and_version;
 49 uint8_t clock_seq_hi_and_reserved;
 50 uint8_t clock_seq_low;
 51 uint8_t node[NB_UUID_NODE_LEN];
 52} nbuuid_t;
 53
 54void nbuuid_create(nbuuid_t *, uint32_t *);
 55void nbuuid_to_string(nbuuid_t *, char **, uint32_t *);
 56
35enum { 57enum {
36 DE_EXTENT, 58 DE_EXTENT,
37 DE_DEVICE 59 DE_DEVICE
38}; 60};
39 61
40/* a device can be made up of an extent or another device */ 62/* a device can be made up of an extent or another device */
41typedef struct disc_de_t { 63typedef struct disc_de_t {
42 int32_t type; /* device or extent */ 64 int32_t type; /* device or extent */
43 uint64_t size; /* size of underlying extent or device */ 65 uint64_t size; /* size of underlying extent or device */
44 union { 66 union {
45 struct disc_extent_t *xp; /* pointer to extent */ 67 struct disc_extent_t *xp; /* pointer to extent */
46 struct disc_device_t *dp; /* pointer to device */ 68 struct disc_device_t *dp; /* pointer to device */
47 } u; 69 } u;
48} disc_de_t; 70} disc_de_t;
49 71
50/* this struct describes an extent of storage */ 72/* this struct describes an extent of storage */
51typedef struct disc_extent_t { 73typedef struct disc_extent_t {
52 char *extent; /* extent name */ 74 char *extent; /* extent name */
53 char *dev; /* device associated with it */ 75 char *dev; /* device associated with it */
54 uint64_t sacred; /* offset of extent from start of device */ 76 uint64_t sacred; /* offset of extent from start of dev */
55 uint64_t len; /* size of extent */ 77 uint64_t len; /* size of extent */
56 int fd; /* in-core file descriptor */ 78 int fd; /* in-core file descriptor */
57 int used; /* extent has been used in a device */ 79 int used; /* extent has been used in a device */
58} disc_extent_t; 80} disc_extent_t;
59 81
60DEFINE_ARRAY(extv_t, disc_extent_t); 82DEFINE_ARRAY(extv_t, disc_extent_t);
61 83
62/* this struct describes a device */ 84/* this struct describes a device */
63typedef struct disc_device_t { 85typedef struct disc_device_t {
64 char *dev; /* device name */ 86 char *dev; /* device name */
65 int raid; /* RAID level */ 87 int raid; /* RAID level */
66 uint64_t off; /* current offset in device */ 88 uint64_t off; /* current offset in device */
67 uint64_t len; /* size of device */ 89 uint64_t len; /* size of device */
68 uint32_t size; /* size of device/extent array */ 90 uint32_t size; /* size of device/extent array */
69 uint32_t c; /* # of entries in device/extents */ 91 uint32_t c; /* # of entries in device/extents */
70 disc_de_t *xv; /* device/extent array */ 92 disc_de_t *xv; /* device/extent array */
71 int used; /* device has been used in a device/target */ 93 int used; /* device has been used in a device/target */
72} disc_device_t; 94} disc_device_t;
73 95
74DEFINE_ARRAY(devv_t, disc_device_t); 96DEFINE_ARRAY(devv_t, disc_device_t);
75 97
76enum { 98enum {
77 TARGET_READONLY = 0x01 99 TARGET_READONLY = 0x01
78}; 100};
79 101
80/* this struct describes an iscsi target's associated features */ 102/* this struct describes an iscsi target's associated features */
81typedef struct disc_target_t { 103typedef struct disc_target_t {
82 char *target; /* target name */ 104 char *target; /* target name */
83 disc_de_t de; /* pointer to its device */ 105 disc_de_t de; /* pointer to its device */
84 uint16_t port; /* port to listen on */ 106 uint16_t port; /* port to listen on */
85 char *mask; /* mask to export it to */ 107 char *mask; /* mask to export it to */
86 uint32_t flags; /* any flags */ 108 uint32_t flags; /* any flags */
87 uint16_t tsih; /* target session identifying handle */ 109 uint16_t tsih; /* target session identifying handle */
88 char *iqn; /* assigned iqn - can be NULL */ 110 char *iqn; /* assigned iqn - can be NULL */
89} disc_target_t; 111} disc_target_t;
90 112
91DEFINE_ARRAY(targv_t, disc_target_t); 113DEFINE_ARRAY(targv_t, disc_target_t);
92 114
93int read_conf_file(const char *, targv_t *, devv_t *, extv_t *); 115int read_conf_file(const char *, targv_t *, devv_t *, extv_t *);
94void write_pid_file(const char *); 116void write_pid_file(const char *);
95 117
96#endif /* !STORAGE_H_ */ 118#endif /* !STORAGE_H_ */

cvs diff -r1.39 -r1.40 src/dist/iscsi/src/Attic/disk.c (switch to unified diff)

--- src/dist/iscsi/src/Attic/disk.c 2009/01/25 14:25:27 1.39
+++ src/dist/iscsi/src/Attic/disk.c 2009/06/23 05:11:47 1.40
@@ -1,1298 +1,1294 @@ @@ -1,1298 +1,1294 @@
1/* $NetBSD: disk.c,v 1.39 2009/01/25 14:25:27 lukem Exp $ */ 1/* $NetBSD: disk.c,v 1.40 2009/06/23 05:11:47 agc Exp $ */
2 2
3/* 3/*
4 * Copyright © 2006 Alistair Crooks. All rights reserved. 4 * Copyright © 2006 Alistair Crooks. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote 14 * 3. The name of the author may not be used to endorse or promote
15 * products derived from this software without specific prior written 15 * products derived from this software without specific prior written
16 * permission. 16 * permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30/* 30/*
31 * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or 31 * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
32 * using the software you agree to this license. If you do not agree to this license, do not download, install, 32 * using the software you agree to this license. If you do not agree to this license, do not download, install,
33 * copy or use the software. 33 * copy or use the software.
34 * 34 *
35 * Intel License Agreement 35 * Intel License Agreement
36 * 36 *
37 * Copyright (c) 2000, Intel Corporation 37 * Copyright (c) 2000, Intel Corporation
38 * All rights reserved. 38 * All rights reserved.
39 * 39 *
40 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that 40 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
41 * the following conditions are met: 41 * the following conditions are met:
42 * 42 *
43 * -Redistributions of source code must retain the above copyright notice, this list of conditions and the 43 * -Redistributions of source code must retain the above copyright notice, this list of conditions and the
44 * following disclaimer. 44 * following disclaimer.
45 * 45 *
46 * -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 46 * -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
47 * following disclaimer in the documentation and/or other materials provided with the distribution. 47 * following disclaimer in the documentation and/or other materials provided with the distribution.
48 * 48 *
49 * -The name of Intel Corporation may not be used to endorse or promote products derived from this software 49 * -The name of Intel Corporation may not be used to endorse or promote products derived from this software
50 * without specific prior written permission. 50 * without specific prior written permission.
51 * 51 *
52 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 52 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
53 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 53 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
54 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 54 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
55 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 55 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
56 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
58 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 58 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59 * POSSIBILITY OF SUCH DAMAGE. 59 * POSSIBILITY OF SUCH DAMAGE.
60 */ 60 */
61#include "config.h" 61#include "config.h"
62 62
63#ifdef HAVE_INTTYPES_H 63#ifdef HAVE_INTTYPES_H
64#include <inttypes.h> 64#include <inttypes.h>
65#endif 65#endif
66 66
67#include <sys/types.h> 67#include <sys/types.h>
68 68
69#ifdef HAVE_SYS_PARAM_H 69#ifdef HAVE_SYS_PARAM_H
70#include <sys/param.h> 70#include <sys/param.h>
71#endif 71#endif
72 72
73#ifdef HAVE_SYS_STAT_H 73#ifdef HAVE_SYS_STAT_H
74#include <sys/stat.h> 74#include <sys/stat.h>
75#endif 75#endif
76 76
77#ifdef HAVE_SYS_UIO_H 77#ifdef HAVE_SYS_UIO_H
78#include <sys/uio.h> 78#include <sys/uio.h>
79#endif 79#endif
80 80
81#ifdef HAVE_SYS_TIME_H 81#ifdef HAVE_SYS_TIME_H
82#include <sys/time.h> 82#include <sys/time.h>
83#endif 83#endif
84 84
85#ifdef HAVE_SYS_MMAN_H 85#ifdef HAVE_SYS_MMAN_H
86#include <sys/mman.h> 86#include <sys/mman.h>
87#endif 87#endif
88 88
89#ifdef HAVE_NETINET_IN_H 89#ifdef HAVE_NETINET_IN_H
90#include <netinet/in.h> 90#include <netinet/in.h>
91#endif 91#endif
92 92
93#ifdef HAVE_ERRNO_H 93#ifdef HAVE_ERRNO_H
94#include <errno.h> 94#include <errno.h>
95#endif 95#endif
96 96
97#ifdef HAVE_FCNTL_H 97#ifdef HAVE_FCNTL_H
98#include <fcntl.h> 98#include <fcntl.h>
99#endif 99#endif
100 100
101#include <ctype.h> 101#include <ctype.h>
102#include <stdio.h> 102#include <stdio.h>
103#include <stdlib.h> 103#include <stdlib.h>
104 104
105#ifdef HAVE_STRING_H 105#ifdef HAVE_STRING_H
106#include <string.h> 106#include <string.h>
107#endif 107#endif
108 108
109#include <unistd.h> 109#include <unistd.h>
110 110
111#ifdef HAVE_UUID_H 
112#include <uuid.h> 
113#endif 
114 
115#include "scsi_cmd_codes.h" 111#include "scsi_cmd_codes.h"
116 112
117#include "iscsi.h" 113#include "iscsi.h"
118#include "compat.h" 114#include "compat.h"
119#include "iscsiutil.h" 115#include "iscsiutil.h"
120#include "device.h" 116#include "device.h"
121#include "target.h" 117#include "target.h"
122#include "defs.h" 118#include "defs.h"
123#include "storage.h" 119#include "storage.h"
124 120
125#define CONFIG_DISK_NUM_LUNS_DFLT 1 121#define CONFIG_DISK_NUM_LUNS_DFLT 1
126#define CONFIG_DISK_BLOCK_LEN_DFLT 512 122#define CONFIG_DISK_BLOCK_LEN_DFLT 512
127#define CONFIG_DISK_NUM_BLOCKS_DFLT 204800 123#define CONFIG_DISK_NUM_BLOCKS_DFLT 204800
128#define CONFIG_DISK_INITIAL_CHECK_CONDITION 0 124#define CONFIG_DISK_INITIAL_CHECK_CONDITION 0
129#define CONFIG_DISK_MAX_LUNS 8 125#define CONFIG_DISK_MAX_LUNS 8
130 126
131/* End disk configuration */ 127/* End disk configuration */
132 128
133/* 129/*
134 * Globals 130 * Globals
135 */ 131 */
136enum { 132enum {
137 MAX_RESERVATIONS = 32, 133 MAX_RESERVATIONS = 32,
138 134
139 ISCSI_FS = 0x03, 135 ISCSI_FS = 0x03,
140 ISCSI_CONTROL = 0x04 136 ISCSI_CONTROL = 0x04
141}; 137};
142 138
143#define MB(x) ((x) * 1024 * 1024) 139#define MB(x) ((x) * 1024 * 1024)
144 140
145/* this struct describes an iscsi LUN */ 141/* this struct describes an iscsi LUN */
146typedef struct iscsi_disk_t { 142typedef struct iscsi_disk_t {
147 int type; /* type of disk - fs/mmap and fs */ 143 int type; /* type of disk - fs/mmap and fs */
148 char filename[MAXPATHLEN]; /* filename for the disk itself */ 144 char filename[MAXPATHLEN]; /* filename for the disk itself */
149 uint8_t *buffer; /* buffer for disk read/write ops */ 145 uint8_t *buffer; /* buffer for disk read/write ops */
150 uint64_t blockc; /* # of blocks */ 146 uint64_t blockc; /* # of blocks */
151 uint64_t blocklen; /* block size */ 147 uint64_t blocklen; /* block size */
152 uint64_t luns; /* # of luns */ 148 uint64_t luns; /* # of luns */
153 uint64_t size; /* size of complete disk */ 149 uint64_t size; /* size of complete disk */
154 uuid_t uuid; /* disk's uuid */ 150 nbuuid_t uuid; /* disk's uuid */
155 char *uuid_string; /* uuid string */ 151 char *uuid_string; /* uuid string */
156 targv_t *tv; /* the component devices and extents */ 152 targv_t *tv; /* the component devices and extents */
157 uint32_t resc; /* # of reservation keys */ 153 uint32_t resc; /* # of reservation keys */
158 uint64_t reskeys[MAX_RESERVATIONS]; /* the reservation keys */ 154 uint64_t reskeys[MAX_RESERVATIONS]; /* the reservation keys */
159} iscsi_disk_t; 155} iscsi_disk_t;
160 156
161DEFINE_ARRAY(disks_t, iscsi_disk_t); 157DEFINE_ARRAY(disks_t, iscsi_disk_t);
162 158
163static disks_t disks; 159static disks_t disks;
164static iscsi_disk_t defaults; 160static iscsi_disk_t defaults;
165 161
166#ifndef FDATASYNC 162#ifndef FDATASYNC
167/* 163/*
168this means that we probably don't have the fsync_range(2) system call, 164this means that we probably don't have the fsync_range(2) system call,
169but no matter - define this here to preserve the abstraction for the 165but no matter - define this here to preserve the abstraction for the
170disk/extent code 166disk/extent code
171*/ 167*/
172#define FDATASYNC 0x0010 168#define FDATASYNC 0x0010
173#endif 169#endif
174 170
175/* 171/*
176 * Private Interface 172 * Private Interface
177 */ 173 */
178 174
179static int disk_read(target_session_t * , iscsi_scsi_cmd_args_t * , uint32_t , uint16_t , uint8_t); 175static int disk_read(target_session_t * , iscsi_scsi_cmd_args_t * , uint32_t , uint16_t , uint8_t);
180static int disk_write(target_session_t * , iscsi_scsi_cmd_args_t * , uint8_t , uint32_t , uint32_t); 176static int disk_write(target_session_t * , iscsi_scsi_cmd_args_t * , uint8_t , uint32_t , uint32_t);
181 177
182/* return the de index and offset within the device for RAID0 */ 178/* return the de index and offset within the device for RAID0 */
183static int 179static int
184raid0_getoff(disc_device_t *dp, uint64_t off, uint32_t *d, uint64_t *de_off) 180raid0_getoff(disc_device_t *dp, uint64_t off, uint32_t *d, uint64_t *de_off)
185{ 181{
186 uint64_t o; 182 uint64_t o;
187 183
188 for (o = 0, *d = 0 ; *d < dp->c ; o += dp->xv[*d].size, (*d)++) { 184 for (o = 0, *d = 0 ; *d < dp->c ; o += dp->xv[*d].size, (*d)++) {
189 if (off >= o && off < o + dp->xv[*d].size) { 185 if (off >= o && off < o + dp->xv[*d].size) {
190 break; 186 break;
191 } 187 }
192 } 188 }
193 *de_off = off - o; 189 *de_off = off - o;
194 return (*d < dp->c); 190 return (*d < dp->c);
195} 191}
196 192
197/* open the extent's device */ 193/* open the extent's device */
198static int 194static int
199extent_open(disc_extent_t *xp, int mode, int flags) 195extent_open(disc_extent_t *xp, int mode, int flags)
200{ 196{
201 return xp->fd = open(xp->dev, mode, flags); 197 return xp->fd = open(xp->dev, mode, flags);
202} 198}
203 199
204/* (recursively) open the device's devices */ 200/* (recursively) open the device's devices */
205static int 201static int
206device_open(disc_device_t *dp, int flags, int mode) 202device_open(disc_device_t *dp, int flags, int mode)
207{ 203{
208 int fd; 204 int fd;
209 uint32_t i; 205 uint32_t i;
210 206
211 for (fd = -1, i = 0 ; i < dp->c ; i++) { 207 for (fd = -1, i = 0 ; i < dp->c ; i++) {
212 switch (dp->xv[i].type) { 208 switch (dp->xv[i].type) {
213 case DE_DEVICE: 209 case DE_DEVICE:
214 if ((fd = device_open(dp->xv[i].u.dp, flags, mode)) < 0) { 210 if ((fd = device_open(dp->xv[i].u.dp, flags, mode)) < 0) {
215 return -1; 211 return -1;
216 } 212 }
217 break; 213 break;
218 case DE_EXTENT: 214 case DE_EXTENT:
219 if ((fd = extent_open(dp->xv[i].u.xp, flags, mode)) < 0) { 215 if ((fd = extent_open(dp->xv[i].u.xp, flags, mode)) < 0) {
220 return -1; 216 return -1;
221 } 217 }
222 break; 218 break;
223 default: 219 default:
224 break; 220 break;
225 } 221 }
226 } 222 }
227 return fd; 223 return fd;
228} 224}
229 225
230/* and for the undecided... */ 226/* and for the undecided... */
231static int 227static int
232de_open(disc_de_t *dp, int flags, int mode) 228de_open(disc_de_t *dp, int flags, int mode)
233{ 229{
234 switch(dp->type) { 230 switch(dp->type) {
235 case DE_DEVICE: 231 case DE_DEVICE:
236 return device_open(dp->u.dp, flags, mode); 232 return device_open(dp->u.dp, flags, mode);
237 case DE_EXTENT: 233 case DE_EXTENT:
238 return extent_open(dp->u.xp, flags, mode); 234 return extent_open(dp->u.xp, flags, mode);
239 default: 235 default:
240 return -1; 236 return -1;
241 } 237 }
242} 238}
243 239
244/* lseek on the extent */ 240/* lseek on the extent */
245static off_t 241static off_t
246extent_lseek(disc_extent_t *xp, off_t off, int whence) 242extent_lseek(disc_extent_t *xp, off_t off, int whence)
247{ 243{
248 return lseek(xp->fd, (long long)(xp->sacred + off), whence); 244 return lseek(xp->fd, (long long)(xp->sacred + off), whence);
249} 245}
250 246
251/* (recursively) lseek on the device's devices */ 247/* (recursively) lseek on the device's devices */
252static off_t 248static off_t
253device_lseek(disc_device_t *dp, off_t off, int whence) 249device_lseek(disc_device_t *dp, off_t off, int whence)
254{ 250{
255 uint64_t suboff; 251 uint64_t suboff;
256 off_t ret; 252 off_t ret;
257 uint32_t d; 253 uint32_t d;
258 254
259 ret = -1; 255 ret = -1;
260 switch(dp->raid) { 256 switch(dp->raid) {
261 case 0: 257 case 0:
262 if (raid0_getoff(dp, (uint64_t) off, &d, &suboff)) { 258 if (raid0_getoff(dp, (uint64_t) off, &d, &suboff)) {
263 switch (dp->xv[d].type) { 259 switch (dp->xv[d].type) {
264 case DE_DEVICE: 260 case DE_DEVICE:
265 if ((ret = device_lseek(dp->xv[d].u.dp, (off_t) suboff, whence)) < 0) { 261 if ((ret = device_lseek(dp->xv[d].u.dp, (off_t) suboff, whence)) < 0) {
266 return -1; 262 return -1;
267 } 263 }
268 break; 264 break;
269 case DE_EXTENT: 265 case DE_EXTENT:
270 if ((ret = extent_lseek(dp->xv[d].u.xp, (off_t) suboff, whence)) < 0) { 266 if ((ret = extent_lseek(dp->xv[d].u.xp, (off_t) suboff, whence)) < 0) {
271 return -1; 267 return -1;
272 } 268 }
273 break; 269 break;
274 default: 270 default:
275 break; 271 break;
276 } 272 }
277 } 273 }
278 break; 274 break;
279 case 1: 275 case 1:
280 for (d = 0 ; d < dp->c ; d++) { 276 for (d = 0 ; d < dp->c ; d++) {
281 switch (dp->xv[d].type) { 277 switch (dp->xv[d].type) {
282 case DE_DEVICE: 278 case DE_DEVICE:
283 if ((ret = device_lseek(dp->xv[d].u.dp, (off_t) off, whence)) < 0) { 279 if ((ret = device_lseek(dp->xv[d].u.dp, (off_t) off, whence)) < 0) {
284 return -1; 280 return -1;
285 } 281 }
286 break; 282 break;
287 case DE_EXTENT: 283 case DE_EXTENT:
288 if ((ret = extent_lseek(dp->xv[d].u.xp, (off_t) off, whence)) < 0) { 284 if ((ret = extent_lseek(dp->xv[d].u.xp, (off_t) off, whence)) < 0) {
289 return -1; 285 return -1;
290 } 286 }
291 break; 287 break;
292 default: 288 default:
293 break; 289 break;
294 } 290 }
295 } 291 }
296 break; 292 break;
297 default: 293 default:
298 break; 294 break;
299 } 295 }
300 return dp->off = ret; 296 return dp->off = ret;
301} 297}
302 298
303/* and for the undecided... */ 299/* and for the undecided... */
304static off_t 300static off_t
305de_lseek(disc_de_t *dp, off_t off, int whence) 301de_lseek(disc_de_t *dp, off_t off, int whence)
306{ 302{
307 switch(dp->type) { 303 switch(dp->type) {
308 case DE_DEVICE: 304 case DE_DEVICE:
309 return device_lseek(dp->u.dp, off, whence); 305 return device_lseek(dp->u.dp, off, whence);
310 case DE_EXTENT: 306 case DE_EXTENT:
311 return extent_lseek(dp->u.xp, off, whence); 307 return extent_lseek(dp->u.xp, off, whence);
312 default: 308 default:
313 return -1; 309 return -1;
314 } 310 }
315} 311}
316 312
317/* fsync_range on the extent */ 313/* fsync_range on the extent */
318static int 314static int
319extent_fsync_range(disc_extent_t *xp, int how, off_t from, off_t len) 315extent_fsync_range(disc_extent_t *xp, int how, off_t from, off_t len)
320{ 316{
321#ifdef HAVE_FSYNC_RANGE 317#ifdef HAVE_FSYNC_RANGE
322 return fsync_range(xp->fd, how, (off_t)(xp->sacred + from), len); 318 return fsync_range(xp->fd, how, (off_t)(xp->sacred + from), len);
323#else 319#else
324 return fsync(xp->fd); 320 return fsync(xp->fd);
325#endif 321#endif
326} 322}
327 323
328/* (recursively) fsync_range on the device's devices */ 324/* (recursively) fsync_range on the device's devices */
329static int 325static int
330device_fsync_range(disc_device_t *dp, int how, off_t from, off_t len) 326device_fsync_range(disc_device_t *dp, int how, off_t from, off_t len)
331{ 327{
332 uint64_t suboff; 328 uint64_t suboff;
333 int ret; 329 int ret;
334 uint32_t d; 330 uint32_t d;
335 331
336 ret = -1; 332 ret = -1;
337 switch(dp->raid) { 333 switch(dp->raid) {
338 case 0: 334 case 0:
339 if (raid0_getoff(dp, (uint64_t) from, &d, &suboff)) { 335 if (raid0_getoff(dp, (uint64_t) from, &d, &suboff)) {
340 switch (dp->xv[d].type) { 336 switch (dp->xv[d].type) {
341 case DE_DEVICE: 337 case DE_DEVICE:
342 if ((ret = device_fsync_range(dp->xv[d].u.dp, how, (off_t)suboff, len)) < 0) { 338 if ((ret = device_fsync_range(dp->xv[d].u.dp, how, (off_t)suboff, len)) < 0) {
343 return -1; 339 return -1;
344 } 340 }
345 break; 341 break;
346 case DE_EXTENT: 342 case DE_EXTENT:
347 if ((ret = extent_fsync_range(dp->xv[d].u.xp, how, (off_t)suboff, len)) < 0) { 343 if ((ret = extent_fsync_range(dp->xv[d].u.xp, how, (off_t)suboff, len)) < 0) {
348 return -1; 344 return -1;
349 } 345 }
350 break; 346 break;
351 default: 347 default:
352 break; 348 break;
353 } 349 }
354 } 350 }
355 break; 351 break;
356 case 1: 352 case 1:
357 for (d = 0 ; d < dp->c ; d++) { 353 for (d = 0 ; d < dp->c ; d++) {
358 switch (dp->xv[d].type) { 354 switch (dp->xv[d].type) {
359 case DE_DEVICE: 355 case DE_DEVICE:
360 if ((ret = device_fsync_range(dp->xv[d].u.dp, how, from, len)) < 0) { 356 if ((ret = device_fsync_range(dp->xv[d].u.dp, how, from, len)) < 0) {
361 return -1; 357 return -1;
362 } 358 }
363 break; 359 break;
364 case DE_EXTENT: 360 case DE_EXTENT:
365 if ((ret = extent_fsync_range(dp->xv[d].u.xp, how, from, len)) < 0) { 361 if ((ret = extent_fsync_range(dp->xv[d].u.xp, how, from, len)) < 0) {
366 return -1; 362 return -1;
367 } 363 }
368 break; 364 break;
369 default: 365 default:
370 break; 366 break;
371 } 367 }
372 } 368 }
373 break; 369 break;
374 default: 370 default:
375 break; 371 break;
376 } 372 }
377 dp->off = (uint64_t) ret; 373 dp->off = (uint64_t) ret;
378 return ret; 374 return ret;
379} 375}
380 376
381/* and for the undecided... */ 377/* and for the undecided... */
382static int 378static int
383de_fsync_range(disc_de_t *dp, int how, off_t from, off_t len) 379de_fsync_range(disc_de_t *dp, int how, off_t from, off_t len)
384{ 380{
385 switch(dp->type) { 381 switch(dp->type) {
386 case DE_DEVICE: 382 case DE_DEVICE:
387 return device_fsync_range(dp->u.dp, how, from, len); 383 return device_fsync_range(dp->u.dp, how, from, len);
388 case DE_EXTENT: 384 case DE_EXTENT:
389 return extent_fsync_range(dp->u.xp, how, from, len); 385 return extent_fsync_range(dp->u.xp, how, from, len);
390 default: 386 default:
391 return -1; 387 return -1;
392 } 388 }
393} 389}
394 390
395/* read from the extent */ 391/* read from the extent */
396static ssize_t 392static ssize_t
397extent_read(disc_extent_t *xp, void *buf, size_t cc) 393extent_read(disc_extent_t *xp, void *buf, size_t cc)
398{ 394{
399 return read(xp->fd, buf, cc); 395 return read(xp->fd, buf, cc);
400} 396}
401 397
402/* (recursively) read from the device's devices */ 398/* (recursively) read from the device's devices */
403static ssize_t 399static ssize_t
404device_read(disc_device_t *dp, void *buf, size_t cc) 400device_read(disc_device_t *dp, void *buf, size_t cc)
405{ 401{
406 uint64_t suboff; 402 uint64_t suboff;
407 uint64_t got; 403 uint64_t got;
408 ssize_t ret; 404 ssize_t ret;
409 size_t subcc; 405 size_t subcc;
410 char *cbuf; 406 char *cbuf;
411 uint32_t d; 407 uint32_t d;
412 408
413 ret = -1; 409 ret = -1;
414 switch(dp->raid) { 410 switch(dp->raid) {
415 case 0: 411 case 0:
416 for (cbuf = (char *) buf, got = 0 ; got < cc ; got += ret) { 412 for (cbuf = (char *) buf, got = 0 ; got < cc ; got += ret) {
417 if (!raid0_getoff(dp, dp->off, &d, &suboff)) { 413 if (!raid0_getoff(dp, dp->off, &d, &suboff)) {
418 return -1; 414 return -1;
419 } 415 }
420 if (device_lseek(dp, (off_t)dp->off, SEEK_SET) < 0) { 416 if (device_lseek(dp, (off_t)dp->off, SEEK_SET) < 0) {
421 return -1; 417 return -1;
422 } 418 }
423 subcc = MIN(cc - (size_t)got, (size_t)(dp->len - (size_t)dp->off)); 419 subcc = MIN(cc - (size_t)got, (size_t)(dp->len - (size_t)dp->off));
424 switch (dp->xv[d].type) { 420 switch (dp->xv[d].type) {
425 case DE_DEVICE: 421 case DE_DEVICE:
426 if ((ret = device_read(dp->xv[d].u.dp, &cbuf[(int)got], subcc)) < 0) { 422 if ((ret = device_read(dp->xv[d].u.dp, &cbuf[(int)got], subcc)) < 0) {
427 return -1; 423 return -1;
428 } 424 }
429 break; 425 break;
430 case DE_EXTENT: 426 case DE_EXTENT:
431 if ((ret = extent_read(dp->xv[d].u.xp, &cbuf[(int)got], subcc)) < 0) { 427 if ((ret = extent_read(dp->xv[d].u.xp, &cbuf[(int)got], subcc)) < 0) {
432 return -1; 428 return -1;
433 } 429 }
434 break; 430 break;
435 default: 431 default:
436 break; 432 break;
437 } 433 }
438 dp->off += ret; 434 dp->off += ret;
439 } 435 }
440 ret = (ssize_t)got; 436 ret = (ssize_t)got;
441 break; 437 break;
442 case 1: 438 case 1:
443 for (d = 0 ; d < dp->c ; d++) { 439 for (d = 0 ; d < dp->c ; d++) {
444 switch (dp->xv[d].type) { 440 switch (dp->xv[d].type) {
445 case DE_DEVICE: 441 case DE_DEVICE:
446 if ((ret = device_read(dp->xv[d].u.dp, buf, cc)) < 0) { 442 if ((ret = device_read(dp->xv[d].u.dp, buf, cc)) < 0) {
447 return -1; 443 return -1;
448 } 444 }
449 break; 445 break;
450 case DE_EXTENT: 446 case DE_EXTENT:
451 if ((ret = extent_read(dp->xv[d].u.xp, buf, cc)) < 0) { 447 if ((ret = extent_read(dp->xv[d].u.xp, buf, cc)) < 0) {
452 return -1; 448 return -1;
453 } 449 }
454 break; 450 break;
455 default: 451 default:
456 break; 452 break;
457 } 453 }
458 } 454 }
459 dp->off += ret; 455 dp->off += ret;
460 break; 456 break;
461 default: 457 default:
462 break; 458 break;
463 } 459 }
464 return ret; 460 return ret;
465} 461}
466 462
467/* and for the undecided... */ 463/* and for the undecided... */
468static ssize_t 464static ssize_t
469de_read(disc_de_t *dp, void *buf, size_t cc) 465de_read(disc_de_t *dp, void *buf, size_t cc)
470{ 466{
471 switch(dp->type) { 467 switch(dp->type) {
472 case DE_DEVICE: 468 case DE_DEVICE:
473 return device_read(dp->u.dp, buf, cc); 469 return device_read(dp->u.dp, buf, cc);
474 case DE_EXTENT: 470 case DE_EXTENT:
475 return extent_read(dp->u.xp, buf, cc); 471 return extent_read(dp->u.xp, buf, cc);
476 default: 472 default:
477 return -1; 473 return -1;
478 } 474 }
479} 475}
480 476
481/* write to the extent */ 477/* write to the extent */
482static ssize_t 478static ssize_t
483extent_write(disc_extent_t *xp, void *buf, size_t cc) 479extent_write(disc_extent_t *xp, void *buf, size_t cc)
484{ 480{
485 return write(xp->fd, buf, cc); 481 return write(xp->fd, buf, cc);
486} 482}
487 483
488/* (recursively) write to the device's devices */ 484/* (recursively) write to the device's devices */
489static ssize_t 485static ssize_t
490device_write(disc_device_t *dp, void *buf, size_t cc) 486device_write(disc_device_t *dp, void *buf, size_t cc)
491{ 487{
492 uint64_t suboff; 488 uint64_t suboff;
493 uint64_t done; 489 uint64_t done;
494 ssize_t ret; 490 ssize_t ret;
495 size_t subcc; 491 size_t subcc;
496 char *cbuf; 492 char *cbuf;
497 uint32_t d; 493 uint32_t d;
498 494
499 ret = -1; 495 ret = -1;
500 switch(dp->raid) { 496 switch(dp->raid) {
501 case 0: 497 case 0:
502 for (cbuf = (char *) buf, done = 0 ; done < cc ; done += ret) { 498 for (cbuf = (char *) buf, done = 0 ; done < cc ; done += ret) {
503 if (!raid0_getoff(dp, dp->off, &d, &suboff)) { 499 if (!raid0_getoff(dp, dp->off, &d, &suboff)) {
504 return -1; 500 return -1;
505 } 501 }
506 subcc = (size_t) MIN(cc - (size_t)done, (size_t)(dp->len - dp->off)); 502 subcc = (size_t) MIN(cc - (size_t)done, (size_t)(dp->len - dp->off));
507 if (device_lseek(dp, (off_t)dp->off, SEEK_SET) < 0) { 503 if (device_lseek(dp, (off_t)dp->off, SEEK_SET) < 0) {
508 return -1; 504 return -1;
509 } 505 }
510 switch (dp->xv[d].type) { 506 switch (dp->xv[d].type) {
511 case DE_DEVICE: 507 case DE_DEVICE:
512 if ((ret = device_write(dp->xv[d].u.dp, &cbuf[(int)done], subcc)) < 0) { 508 if ((ret = device_write(dp->xv[d].u.dp, &cbuf[(int)done], subcc)) < 0) {
513 return -1; 509 return -1;
514 } 510 }
515 break; 511 break;
516 case DE_EXTENT: 512 case DE_EXTENT:
517 if ((ret = extent_write(dp->xv[d].u.xp, &cbuf[(int)done], subcc)) < 0) { 513 if ((ret = extent_write(dp->xv[d].u.xp, &cbuf[(int)done], subcc)) < 0) {
518 return -1; 514 return -1;
519 } 515 }
520 break; 516 break;
521 default: 517 default:
522 break; 518 break;
523 } 519 }
524 dp->off += ret; 520 dp->off += ret;
525 } 521 }
526 ret = (ssize_t) done; 522 ret = (ssize_t) done;
527 break; 523 break;
528 case 1: 524 case 1:
529 for (d = 0 ; d < dp->c ; d++) { 525 for (d = 0 ; d < dp->c ; d++) {
530 switch (dp->xv[d].type) { 526 switch (dp->xv[d].type) {
531 case DE_DEVICE: 527 case DE_DEVICE:
532 if ((ret = device_write(dp->xv[d].u.dp, buf, cc)) < 0) { 528 if ((ret = device_write(dp->xv[d].u.dp, buf, cc)) < 0) {
533 iscsi_trace_error(__FILE__, __LINE__, "device_write RAID1 device write failure\n"); 529 iscsi_trace_error(__FILE__, __LINE__, "device_write RAID1 device write failure\n");
534 return -1; 530 return -1;
535 } 531 }
536 break; 532 break;
537 case DE_EXTENT: 533 case DE_EXTENT:
538 if ((ret = extent_write(dp->xv[d].u.xp, buf, cc)) < 0) { 534 if ((ret = extent_write(dp->xv[d].u.xp, buf, cc)) < 0) {
539 iscsi_trace_error(__FILE__, __LINE__, "device_write RAID1 extent write failure\n"); 535 iscsi_trace_error(__FILE__, __LINE__, "device_write RAID1 extent write failure\n");
540 return -1; 536 return -1;
541 } 537 }
542 break; 538 break;
543 default: 539 default:
544 break; 540 break;
545 } 541 }
546 } 542 }
547 dp->off += ret; 543 dp->off += ret;
548 break; 544 break;
549 default: 545 default:
550 break; 546 break;
551 } 547 }
552 return ret; 548 return ret;
553} 549}
554 550
555/* and for the undecided... */ 551/* and for the undecided... */
556static ssize_t 552static ssize_t
557de_write(disc_de_t *dp, void *buf, size_t cc) 553de_write(disc_de_t *dp, void *buf, size_t cc)
558{ 554{
559 switch(dp->type) { 555 switch(dp->type) {
560 case DE_DEVICE: 556 case DE_DEVICE:
561 return device_write(dp->u.dp, buf, cc); 557 return device_write(dp->u.dp, buf, cc);
562 case DE_EXTENT: 558 case DE_EXTENT:
563 return extent_write(dp->u.xp, buf, cc); 559 return extent_write(dp->u.xp, buf, cc);
564 default: 560 default:
565 return -1; 561 return -1;
566 } 562 }
567} 563}
568 564
569/* return non-zero if the target is writable */ 565/* return non-zero if the target is writable */
570static int 566static int
571target_writable(disc_target_t *tp) 567target_writable(disc_target_t *tp)
572{ 568{
573 return !(tp->flags & TARGET_READONLY); 569 return !(tp->flags & TARGET_READONLY);
574} 570}
575 571
576/* return size of the extent */ 572/* return size of the extent */
577static uint64_t 573static uint64_t
578extent_getsize(disc_extent_t *xp) 574extent_getsize(disc_extent_t *xp)
579{ 575{
580 return xp->len; 576 return xp->len;
581} 577}
582 578
583/* (recursively) return the size of the device's devices */ 579/* (recursively) return the size of the device's devices */
584static uint64_t 580static uint64_t
585device_getsize(disc_device_t *dp) 581device_getsize(disc_device_t *dp)
586{ 582{
587 uint64_t size; 583 uint64_t size;
588 uint32_t d; 584 uint32_t d;
589 585
590 size = 0; 586 size = 0;
591 switch(dp->raid) { 587 switch(dp->raid) {
592 case 0: 588 case 0:
593 for (d = 0 ; d < dp->c ; d++) { 589 for (d = 0 ; d < dp->c ; d++) {
594 switch (dp->xv[d].type) { 590 switch (dp->xv[d].type) {
595 case DE_DEVICE: 591 case DE_DEVICE:
596 size += device_getsize(dp->xv[d].u.dp); 592 size += device_getsize(dp->xv[d].u.dp);
597 break; 593 break;
598 case DE_EXTENT: 594 case DE_EXTENT:
599 size += extent_getsize(dp->xv[d].u.xp); 595 size += extent_getsize(dp->xv[d].u.xp);
600 break; 596 break;
601 default: 597 default:
602 break; 598 break;
603 } 599 }
604 } 600 }
605 break; 601 break;
606 case 1: 602 case 1:
607 size = dp->len; 603 size = dp->len;
608 break; 604 break;
609 default: 605 default:
610 break; 606 break;
611 } 607 }
612 return size; 608 return size;
613} 609}
614 610
615/* and for the undecided... */ 611/* and for the undecided... */
616static int64_t 612static int64_t
617de_getsize(disc_de_t *dp) 613de_getsize(disc_de_t *dp)
618{ 614{
619 switch(dp->type) { 615 switch(dp->type) {
620 case DE_DEVICE: 616 case DE_DEVICE:
621 return device_getsize(dp->u.dp); 617 return device_getsize(dp->u.dp);
622 case DE_EXTENT: 618 case DE_EXTENT:
623 return extent_getsize(dp->u.xp); 619 return extent_getsize(dp->u.xp);
624 default: 620 default:
625 return -1; 621 return -1;
626 } 622 }
627} 623}
628 624
629/* return a filename for the device or extent */ 625/* return a filename for the device or extent */
630static char * 626static char *
631disc_get_filename(disc_de_t *de) 627disc_get_filename(disc_de_t *de)
632{ 628{
633 switch (de->type) { 629 switch (de->type) {
634 case DE_EXTENT: 630 case DE_EXTENT:
635 return de->u.xp->dev; 631 return de->u.xp->dev;
636 case DE_DEVICE: 632 case DE_DEVICE:
637 return disc_get_filename(&de->u.dp->xv[0]); 633 return disc_get_filename(&de->u.dp->xv[0]);
638 default: 634 default:
639 return NULL; 635 return NULL;
640 } 636 }
641} 637}
642 638
643/* 639/*
644 * Public Interface (called by utarget and ktarket) 640 * Public Interface (called by utarget and ktarket)
645 */ 641 */
646 642
647 /* set various global variables */ 643 /* set various global variables */
648void 644void
649device_set_var(const char *var, char *arg) 645device_set_var(const char *var, char *arg)
650{ 646{
651 if (strcmp(var, "blocklen") == 0) { 647 if (strcmp(var, "blocklen") == 0) {
652 defaults.blocklen = strtoll(arg, (char **)NULL, 10); 648 defaults.blocklen = strtoll(arg, (char **)NULL, 10);
653 } else if (strcmp(var, "blocks") == 0) { 649 } else if (strcmp(var, "blocks") == 0) {
654 defaults.blockc = strtoll(arg, (char **)NULL, 10); 650 defaults.blockc = strtoll(arg, (char **)NULL, 10);
655 } else if (strcmp(var, "luns") == 0) { 651 } else if (strcmp(var, "luns") == 0) {
656 defaults.luns = strtoll(arg, (char **)NULL, 10); 652 defaults.luns = strtoll(arg, (char **)NULL, 10);
657 } else { 653 } else {
658 (void) fprintf(stderr, "Unrecognised variable: `%s'\n", var); 654 (void) fprintf(stderr, "Unrecognised variable: `%s'\n", var);
659 } 655 }
660} 656}
661 657
662/* allocate some space for a disk/extent, using an lseek, read and write combination */ 658/* allocate some space for a disk/extent, using an lseek, read and write combination */
663static int 659static int
664de_allocate(disc_de_t *de, char *filename) 660de_allocate(disc_de_t *de, char *filename)
665{ 661{
666 off_t size; 662 off_t size;
667 char block[DEFAULT_TARGET_BLOCK_LEN]; 663 char block[DEFAULT_TARGET_BLOCK_LEN];
668 664
669 size = de_getsize(de); 665 size = de_getsize(de);
670 if (de_lseek(de, size - sizeof(block), SEEK_SET) == -1) { 666 if (de_lseek(de, size - sizeof(block), SEEK_SET) == -1) {
671 iscsi_trace_error(__FILE__, __LINE__, "error seeking \"%s\"\n", filename); 667 iscsi_trace_error(__FILE__, __LINE__, "error seeking \"%s\"\n", filename);
672 return 0; 668 return 0;
673 } 669 }
674 if (de_read(de, block, sizeof(block)) == -1) { 670 if (de_read(de, block, sizeof(block)) == -1) {
675 iscsi_trace_error(__FILE__, __LINE__, "error reading \"%s\"", filename); 671 iscsi_trace_error(__FILE__, __LINE__, "error reading \"%s\"", filename);
676 return 0; 672 return 0;
677 } 673 }
678 if (de_write(de, block, sizeof(block)) == -1) { 674 if (de_write(de, block, sizeof(block)) == -1) {
679 iscsi_trace_error(__FILE__, __LINE__, "error writing \"%s\"", filename); 675 iscsi_trace_error(__FILE__, __LINE__, "error writing \"%s\"", filename);
680 return 0; 676 return 0;
681 } 677 }
682 return 1; 678 return 1;
683} 679}
684 680
685/* allocate space as desired */ 681/* allocate space as desired */
686static int 682static int
687allocate_space(disc_target_t *tp) 683allocate_space(disc_target_t *tp)
688{ 684{
689 uint32_t i; 685 uint32_t i;
690 686
691 /* Don't perform check for writability in the target here, as the 687 /* Don't perform check for writability in the target here, as the
692 following write() in de_allocate is non-destructive */ 688 following write() in de_allocate is non-destructive */
693 switch(tp->de.type) { 689 switch(tp->de.type) {
694 case DE_EXTENT: 690 case DE_EXTENT:
695 return de_allocate(&tp->de, tp->target); 691 return de_allocate(&tp->de, tp->target);
696 case DE_DEVICE: 692 case DE_DEVICE:
697 for (i = 0 ; i < tp->de.u.dp->c ; i++) { 693 for (i = 0 ; i < tp->de.u.dp->c ; i++) {
698 if (!de_allocate(&tp->de.u.dp->xv[i], tp->target)) { 694 if (!de_allocate(&tp->de.u.dp->xv[i], tp->target)) {
699 return 0; 695 return 0;
700 } 696 }
701 } 697 }
702 return 1; 698 return 1;
703 default: 699 default:
704 break; 700 break;
705 } 701 }
706 return 0; 702 return 0;
707} 703}
708 704
709/* copy src to dst, of size `n' bytes, padding any extra with `pad' */ 705/* copy src to dst, of size `n' bytes, padding any extra with `pad' */
710static void 706static void
711strpadcpy(uint8_t *dst, size_t dstlen, const char *src, const size_t srclen, char pad) 707strpadcpy(uint8_t *dst, size_t dstlen, const char *src, const size_t srclen, char pad)
712{ 708{
713 size_t i; 709 size_t i;
714 710
715 if (srclen < dstlen) { 711 if (srclen < dstlen) {
716 (void) memcpy(dst, src, srclen); 712 (void) memcpy(dst, src, srclen);
717 for (i = srclen ; i < dstlen ; i++) { 713 for (i = srclen ; i < dstlen ; i++) {
718 dst[i] = pad; 714 dst[i] = pad;
719 } 715 }
720 } else { 716 } else {
721 (void) memcpy(dst, src, dstlen); 717 (void) memcpy(dst, src, dstlen);
722 } 718 }
723}  719}
724 720
725/* handle REPORT LUNs SCSI command */ 721/* handle REPORT LUNs SCSI command */
726static int 722static int
727report_luns(uint64_t *data, int64_t luns) 723report_luns(uint64_t *data, int64_t luns)
728{ 724{
729 uint64_t lun; 725 uint64_t lun;
730 int32_t off; 726 int32_t off;
731 727
732 for (lun = 0, off = 8 ; lun < (uint64_t)luns ; lun++, off += sizeof(lun)) { 728 for (lun = 0, off = 8 ; lun < (uint64_t)luns ; lun++, off += sizeof(lun)) {
733 data[(int)lun] = ISCSI_HTONLL(lun); 729 data[(int)lun] = ISCSI_HTONLL(lun);
734 } 730 }
735 return off; 731 return off;
736} 732}
737 733
738/* handle persistent reserve in command */ 734/* handle persistent reserve in command */
739static int 735static int
740persistent_reserve_in(uint8_t action, uint8_t *data) 736persistent_reserve_in(uint8_t action, uint8_t *data)
741{ 737{
742 uint64_t key; 738 uint64_t key;
743 739
744 switch(action) { 740 switch(action) {
745 case PERSISTENT_RESERVE_IN_READ_KEYS: 741 case PERSISTENT_RESERVE_IN_READ_KEYS:
746 key = 0; /* simulate "just powered on" */ 742 key = 0; /* simulate "just powered on" */
747 *((uint32_t *) (void *)data) = (uint32_t) ISCSI_HTONL((uint32_t) 0); 743 *((uint32_t *) (void *)data) = (uint32_t) ISCSI_HTONL((uint32_t) 0);
748 *((uint32_t *) (void *)data + 4) = (uint32_t) ISCSI_HTONL((uint32_t) sizeof(key)); /* length in bytes of list of keys */ 744 *((uint32_t *) (void *)data + 4) = (uint32_t) ISCSI_HTONL((uint32_t) sizeof(key)); /* length in bytes of list of keys */
749 *((uint64_t *) (void *)data + 8) = (uint64_t) ISCSI_HTONLL(key); 745 *((uint64_t *) (void *)data + 8) = (uint64_t) ISCSI_HTONLL(key);
750 return 8 + sizeof(key); 746 return 8 + sizeof(key);
751 case PERSISTENT_RESERVE_IN_REPORT_CAPABILITIES: 747 case PERSISTENT_RESERVE_IN_REPORT_CAPABILITIES:
752 (void) memset(data, 0x0, 8); 748 (void) memset(data, 0x0, 8);
753 *((uint16_t *) (void *)data) = (uint16_t) ISCSI_HTONS((uint16_t) 8); /* length is fixed at 8 bytes */ 749 *((uint16_t *) (void *)data) = (uint16_t) ISCSI_HTONS((uint16_t) 8); /* length is fixed at 8 bytes */
754 data[2] = PERSISTENT_RESERVE_IN_CRH; /* also SIP_C, ATP_C and PTPL_C here */ 750 data[2] = PERSISTENT_RESERVE_IN_CRH; /* also SIP_C, ATP_C and PTPL_C here */
755 data[3] = 0; /* also TMV and PTPL_A here */ 751 data[3] = 0; /* also TMV and PTPL_A here */
756 data[4] = 0; /* also WR_EX_AR, EX_AC_RD, WR_EX_RD, EX_AC, WR_EX here */ 752 data[4] = 0; /* also WR_EX_AR, EX_AC_RD, WR_EX_RD, EX_AC, WR_EX here */
757 data[5] = 0; /* also EX_AC_AR here */ 753 data[5] = 0; /* also EX_AC_AR here */
758 return 8; 754 return 8;
759 default: 755 default:
760 iscsi_trace_error(__FILE__, __LINE__, "persistent_reserve_in: action %x unrecognised\n", action); 756 iscsi_trace_error(__FILE__, __LINE__, "persistent_reserve_in: action %x unrecognised\n", action);
761 return 0; 757 return 0;
762 } 758 }
763} 759}
764 760
765/* initialise the device */ 761/* initialise the device */
766/* ARGSUSED */ 762/* ARGSUSED */
767int  763int
768device_init(globals_t *gp __attribute__((__unused__)), targv_t *tvp, disc_target_t *tp) 764device_init(globals_t *gp __attribute__((__unused__)), targv_t *tvp, disc_target_t *tp)
769{ 765{
770 int mode; 766 int mode;
771 767
772 ALLOC(iscsi_disk_t, disks.v, disks.size, disks.c, 10, 10, "device_init", ;); 768 ALLOC(iscsi_disk_t, disks.v, disks.size, disks.c, 10, 10, "device_init", ;);
773 disks.v[disks.c].tv = tvp; 769 disks.v[disks.c].tv = tvp;
774 if ((disks.v[disks.c].luns = defaults.luns) == 0) { 770 if ((disks.v[disks.c].luns = defaults.luns) == 0) {
775 disks.v[disks.c].luns = CONFIG_DISK_NUM_LUNS_DFLT; 771 disks.v[disks.c].luns = CONFIG_DISK_NUM_LUNS_DFLT;
776 } 772 }
777 if ((disks.v[disks.c].blocklen = defaults.blocklen) == 0) { 773 if ((disks.v[disks.c].blocklen = defaults.blocklen) == 0) {
778 disks.v[disks.c].blocklen = CONFIG_DISK_BLOCK_LEN_DFLT; 774 disks.v[disks.c].blocklen = CONFIG_DISK_BLOCK_LEN_DFLT;
779 } 775 }
780 disks.v[disks.c].size = de_getsize(&tp->de); 776 disks.v[disks.c].size = de_getsize(&tp->de);
781 disks.v[disks.c].blockc = disks.v[disks.c].size / disks.v[disks.c].blocklen; 777 disks.v[disks.c].blockc = disks.v[disks.c].size / disks.v[disks.c].blocklen;
782 NEWARRAY(uint8_t, disks.v[disks.c].buffer, MB(1), "buffer1", ;); 778 NEWARRAY(uint8_t, disks.v[disks.c].buffer, MB(1), "buffer1", ;);
783 switch(disks.v[disks.c].blocklen) { 779 switch(disks.v[disks.c].blocklen) {
784 case 512: 780 case 512:
785 case 1024: 781 case 1024:
786 case 2048: 782 case 2048:
787 case 4096: 783 case 4096:
788 break; 784 break;
789 default: 785 default:
790 iscsi_trace_error(__FILE__, __LINE__, "Invalid block len %" PRIu64 ". Choose one of 512, 1024, 2048, 4096.\n", disks.v[disks.c].blocklen); 786 iscsi_trace_error(__FILE__, __LINE__, "Invalid block len %" PRIu64 ". Choose one of 512, 1024, 2048, 4096.\n", disks.v[disks.c].blocklen);
791 return -1; 787 return -1;
792 } 788 }
793 disks.v[disks.c].type = ISCSI_FS; 789 disks.v[disks.c].type = ISCSI_FS;
794 printf("DISK: %" PRIu64 " logical unit%s (%" PRIu64 " blocks, %" PRIu64 " bytes/block), type %s\n", 790 printf("DISK: %" PRIu64 " logical unit%s (%" PRIu64 " blocks, %" PRIu64 " bytes/block), type %s\n",
795 disks.v[disks.c].luns, 791 disks.v[disks.c].luns,
796 (disks.v[disks.c].luns == 1) ? "" : "s", 792 (disks.v[disks.c].luns == 1) ? "" : "s",
797 disks.v[disks.c].blockc, disks.v[disks.c].blocklen, 793 disks.v[disks.c].blockc, disks.v[disks.c].blocklen,
798 (disks.v[disks.c].type == ISCSI_FS) ? "iscsi fs" : "iscsi fs mmap"); 794 (disks.v[disks.c].type == ISCSI_FS) ? "iscsi fs" : "iscsi fs mmap");
799 printf("DISK: LUN 0: "); 795 printf("DISK: LUN 0: ");
800 (void) strlcpy(disks.v[disks.c].filename, disc_get_filename(&tp->de), sizeof(disks.v[disks.c].filename)); 796 (void) strlcpy(disks.v[disks.c].filename, disc_get_filename(&tp->de), sizeof(disks.v[disks.c].filename));
801 mode = (tp->flags & TARGET_READONLY) ? O_RDONLY : (O_CREAT | O_RDWR); 797 mode = (tp->flags & TARGET_READONLY) ? O_RDONLY : (O_CREAT | O_RDWR);
802 if (de_open(&tp->de, mode, 0666) == -1) { 798 if (de_open(&tp->de, mode, 0666) == -1) {
803 iscsi_trace_error(__FILE__, __LINE__, "error opening \"%s\"\n", disks.v[disks.c].filename); 799 iscsi_trace_error(__FILE__, __LINE__, "error opening \"%s\"\n", disks.v[disks.c].filename);
804 return -1; 800 return -1;
805 } 801 }
806 if (!(tp->flags & TARGET_READONLY) && !allocate_space(tp)) { 802 if (!(tp->flags & TARGET_READONLY) && !allocate_space(tp)) {
807 iscsi_trace_error(__FILE__, __LINE__, "error allocating space for \"%s\"", tp->target); 803 iscsi_trace_error(__FILE__, __LINE__, "error allocating space for \"%s\"", tp->target);
808 return -1; 804 return -1;
809 } 805 }
810 printf("%" PRIu64 " MB %sdisk storage for \"%s\"\n", 806 printf("%" PRIu64 " MB %sdisk storage for \"%s\"\n",
811 (de_getsize(&tp->de) / MB(1)), 807 (de_getsize(&tp->de) / MB(1)),
812 (tp->flags & TARGET_READONLY) ? "readonly " : "", 808 (tp->flags & TARGET_READONLY) ? "readonly " : "",
813 tp->target); 809 tp->target);
814 return disks.c++; 810 return disks.c++;
815} 811}
816 812
817/* handle MODE_SENSE_6 and MODE_SENSE_10 commands */ 813/* handle MODE_SENSE_6 and MODE_SENSE_10 commands */
818static int 814static int
819mode_sense(const int bytes, target_cmd_t *cmd) 815mode_sense(const int bytes, target_cmd_t *cmd)
820{ 816{
821 iscsi_scsi_cmd_args_t *args = cmd->scsi_cmd; 817 iscsi_scsi_cmd_args_t *args = cmd->scsi_cmd;
822 uint16_t len; 818 uint16_t len;
823 uint8_t *cp; 819 uint8_t *cp;
824 uint8_t *cdb = args->cdb; 820 uint8_t *cdb = args->cdb;
825 size_t mode_data_len; 821 size_t mode_data_len;
826 822
827 switch(bytes) { 823 switch(bytes) {
828 case 6: 824 case 6:
829 cp = args->send_data; 825 cp = args->send_data;
830 len = ISCSI_MODE_SENSE_LEN; 826 len = ISCSI_MODE_SENSE_LEN;
831 mode_data_len = len + 3; 827 mode_data_len = len + 3;
832 828
833 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "MODE_SENSE_6\n"); 829 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "MODE_SENSE_6\n");
834 (void) memset(cp, 0x0, mode_data_len); 830 (void) memset(cp, 0x0, mode_data_len);
835 831
836 cp[0] = mode_data_len; 832 cp[0] = mode_data_len;
837 cp[1] = 0; 833 cp[1] = 0;
838 cp[2] = 0; 834 cp[2] = 0;
839 cp[3] = 8; /* block descriptor length */ 835 cp[3] = 8; /* block descriptor length */
840 cp[10] = 2; /* density code and block length */ 836 cp[10] = 2; /* density code and block length */
841 837
842 args->input = 1; 838 args->input = 1;
843 args->length = (unsigned)(len); 839 args->length = (unsigned)(len);
844 args->status = SCSI_SUCCESS; 840 args->status = SCSI_SUCCESS;
845 return 1; 841 return 1;
846 case 10: 842 case 10:
847 cp = args->send_data; 843 cp = args->send_data;
848 len = ISCSI_MODE_SENSE_LEN; 844 len = ISCSI_MODE_SENSE_LEN;
849 mode_data_len = len + 3; 845 mode_data_len = len + 3;
850 846
851 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "MODE_SENSE_10\n"); 847 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "MODE_SENSE_10\n");
852 (void) memset(cp, 0x0, mode_data_len); 848 (void) memset(cp, 0x0, mode_data_len);
853 if (cdb[4] == 0) { 849 if (cdb[4] == 0) {
854 /* zero length cdb means just return success */ 850 /* zero length cdb means just return success */
855 args->input = 1; 851 args->input = 1;
856 args->length = (unsigned)(mode_data_len); 852 args->length = (unsigned)(mode_data_len);
857 args->status = SCSI_SUCCESS; 853 args->status = SCSI_SUCCESS;
858 return 1; 854 return 1;
859 } 855 }
860 if ((cdb[2] & PAGE_CONTROL_MASK) == PAGE_CONTROL_CHANGEABLE_VALUES) { 856 if ((cdb[2] & PAGE_CONTROL_MASK) == PAGE_CONTROL_CHANGEABLE_VALUES) {
861 /* just send back a CHECK CONDITION */ 857 /* just send back a CHECK CONDITION */
862 args->input = 1; 858 args->input = 1;
863 args->length = (unsigned)(len); 859 args->length = (unsigned)(len);
864 args->status = SCSI_CHECK_CONDITION; 860 args->status = SCSI_CHECK_CONDITION;
865 cp[2] = SCSI_SKEY_ILLEGAL_REQUEST; 861 cp[2] = SCSI_SKEY_ILLEGAL_REQUEST;
866 cp[12] = ASC_LUN_UNSUPPORTED; 862 cp[12] = ASC_LUN_UNSUPPORTED;
867 cp[13] = ASCQ_LUN_UNSUPPORTED; 863 cp[13] = ASCQ_LUN_UNSUPPORTED;
868 return 1; 864 return 1;
869 } 865 }
870 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "PC %02x\n", cdb[2]); 866 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "PC %02x\n", cdb[2]);
871 867
872 cp[0] = mode_data_len; 868 cp[0] = mode_data_len;
873 cp[1] = 0; 869 cp[1] = 0;
874 cp[2] = 0; 870 cp[2] = 0;
875 cp[3] = 8; /* block descriptor length */ 871 cp[3] = 8; /* block descriptor length */
876 cp[10] = 2; /* density code and block length */ 872 cp[10] = 2; /* density code and block length */
877 873
878 args->input = 1; 874 args->input = 1;
879 args->length = (unsigned)(len); 875 args->length = (unsigned)(len);
880 args->status = SCSI_SUCCESS; 876 args->status = SCSI_SUCCESS;
881 return 1; 877 return 1;
882 } 878 }
883 return 0; 879 return 0;
884} 880}
885 881
886 882
887int  883int
888device_command(target_session_t * sess, target_cmd_t * cmd) 884device_command(target_session_t * sess, target_cmd_t * cmd)
889{ 885{
890 iscsi_scsi_cmd_args_t *args = cmd->scsi_cmd; 886 iscsi_scsi_cmd_args_t *args = cmd->scsi_cmd;
891 uint32_t status; 887 uint32_t status;
892 uint32_t lba; 888 uint32_t lba;
893 uint16_t len; 889 uint16_t len;
894 uint8_t *totsize; 890 uint8_t *totsize;
895 uint8_t *totlen; 891 uint8_t *totlen;
896 uint8_t *cp; 892 uint8_t *cp;
897 uint8_t *data; 893 uint8_t *data;
898 uint8_t *cdb = args->cdb; 894 uint8_t *cdb = args->cdb;
899 uint8_t lun = (uint8_t) (args->lun >> 32); 895 uint8_t lun = (uint8_t) (args->lun >> 32);
900 896
901 totsize = &cdb[4]; 897 totsize = &cdb[4];
902 898
903 /* 899 /*
904 * added section to return no device equivalent for lun request 900 * added section to return no device equivalent for lun request
905 * beyond available lun 901 * beyond available lun
906 */ 902 */
907 if (lun >= disks.v[sess->d].luns) { 903 if (lun >= disks.v[sess->d].luns) {
908 data = args->send_data; 904 data = args->send_data;
909 (void) memset(data, 0x0, (size_t) *totsize); 905 (void) memset(data, 0x0, (size_t) *totsize);
910 /* 906 /*
911 * data[0] = 0x7F; means no device 907 * data[0] = 0x7F; means no device
912 */ 908 */
913 data[0] = 0x1F; /* device type */ 909 data[0] = 0x1F; /* device type */
914 data[0] |= 0x60;/* peripheral qualifier */ 910 data[0] |= 0x60;/* peripheral qualifier */
915 args->input = 1; 911 args->input = 1;
916 args->length = cdb[4] + 1; 912 args->length = cdb[4] + 1;
917 args->status = SCSI_SUCCESS; 913 args->status = SCSI_SUCCESS;
918 return 0; 914 return 0;
919 } 915 }
920 916
921 lun = (uint8_t) sess->d; 917 lun = (uint8_t) sess->d;
922 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "SCSI op %#x (lun %d): \n", cdb[0], lun); 918 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "SCSI op %#x (lun %d): \n", cdb[0], lun);
923 919
924 switch (cdb[0]) { 920 switch (cdb[0]) {
925 921
926 case TEST_UNIT_READY: 922 case TEST_UNIT_READY:
927 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "TEST_UNIT_READY\n"); 923 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "TEST_UNIT_READY\n");
928 args->status = SCSI_SUCCESS; 924 args->status = SCSI_SUCCESS;
929 args->length = 0; 925 args->length = 0;
930 break; 926 break;
931 927
932 case INQUIRY: 928 case INQUIRY:
933 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "INQUIRY%s\n", (cdb[1] & INQUIRY_EVPD_BIT) ? " for Vital Product Data" : ""); 929 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "INQUIRY%s\n", (cdb[1] & INQUIRY_EVPD_BIT) ? " for Vital Product Data" : "");
934 data = args->send_data; 930 data = args->send_data;
935 args->status = SCSI_SUCCESS; 931 args->status = SCSI_SUCCESS;
936 (void) memset(data, 0x0, (unsigned) *totsize); /* Clear allocated buffer */ 932 (void) memset(data, 0x0, (unsigned) *totsize); /* Clear allocated buffer */
937 if (cdb[1] & INQUIRY_EVPD_BIT) { 933 if (cdb[1] & INQUIRY_EVPD_BIT) {
938 totlen = &data[3]; 934 totlen = &data[3];
939 switch(cdb[2]) { 935 switch(cdb[2]) {
940 case INQUIRY_UNIT_SERIAL_NUMBER_VPD: 936 case INQUIRY_UNIT_SERIAL_NUMBER_VPD:
941 data[0] = DISK_PERIPHERAL_DEVICE; 937 data[0] = DISK_PERIPHERAL_DEVICE;
942 data[1] = INQUIRY_DEVICE_IDENTIFICATION_VPD; 938 data[1] = INQUIRY_DEVICE_IDENTIFICATION_VPD;
943 len = 16; 939 len = 16;
944 *totlen = len; 940 *totlen = len;
945 /* add target device's Unit Serial Number */ 941 /* add target device's Unit Serial Number */
946 /* section 7.6.10 of SPC-3 says that if there is no serial number, use spaces */ 942 /* section 7.6.10 of SPC-3 says that if there is no serial number, use spaces */
947 strpadcpy(&data[4], (unsigned)len, " ", strlen(" "), ' '); 943 strpadcpy(&data[4], (unsigned)len, " ", strlen(" "), ' ');
948 break; 944 break;
949 case INQUIRY_DEVICE_IDENTIFICATION_VPD: 945 case INQUIRY_DEVICE_IDENTIFICATION_VPD:
950 data[0] = DISK_PERIPHERAL_DEVICE; 946 data[0] = DISK_PERIPHERAL_DEVICE;
951 data[1] = INQUIRY_DEVICE_IDENTIFICATION_VPD; 947 data[1] = INQUIRY_DEVICE_IDENTIFICATION_VPD;
952 *totlen = 0; 948 *totlen = 0;
953 cp = &data[4]; 949 cp = &data[4];
954 /* add target device's IQN */ 950 /* add target device's IQN */
955 cp[0] = (INQUIRY_DEVICE_ISCSI_PROTOCOL << 4) | INQUIRY_DEVICE_CODESET_UTF8; 951 cp[0] = (INQUIRY_DEVICE_ISCSI_PROTOCOL << 4) | INQUIRY_DEVICE_CODESET_UTF8;
956 cp[1] = (INQUIRY_DEVICE_PIV << 7) | (INQUIRY_DEVICE_ASSOCIATION_TARGET_DEVICE << 4) | INQUIRY_DEVICE_IDENTIFIER_SCSI_NAME; 952 cp[1] = (INQUIRY_DEVICE_PIV << 7) | (INQUIRY_DEVICE_ASSOCIATION_TARGET_DEVICE << 4) | INQUIRY_DEVICE_IDENTIFIER_SCSI_NAME;
957 len = (uint8_t) snprintf((char *)&cp[4], 953 len = (uint8_t) snprintf((char *)&cp[4],
958 (unsigned)(*totsize - (int)(cp - &data[4])), 954 (unsigned)(*totsize - (int)(cp - &data[4])),
959 "%s", 955 "%s",
960 sess->globals->targetname); 956 sess->globals->targetname);
961 cp[3] = len; 957 cp[3] = len;
962 *totlen += len + 4; 958 *totlen += len + 4;
963 cp += len + 4; 959 cp += len + 4;
964 /* add target port's IQN + LUN */ 960 /* add target port's IQN + LUN */
965 cp[0] = (INQUIRY_DEVICE_ISCSI_PROTOCOL << 4) | INQUIRY_DEVICE_CODESET_UTF8; 961 cp[0] = (INQUIRY_DEVICE_ISCSI_PROTOCOL << 4) | INQUIRY_DEVICE_CODESET_UTF8;
966 cp[1] = (INQUIRY_DEVICE_PIV << 7) | (INQUIRY_DEVICE_ASSOCIATION_TARGET_PORT << 4) | INQUIRY_DEVICE_IDENTIFIER_SCSI_NAME; 962 cp[1] = (INQUIRY_DEVICE_PIV << 7) | (INQUIRY_DEVICE_ASSOCIATION_TARGET_PORT << 4) | INQUIRY_DEVICE_IDENTIFIER_SCSI_NAME;
967 len = (uint8_t) snprintf((char *)&cp[4], 963 len = (uint8_t) snprintf((char *)&cp[4],
968 (unsigned)(*totsize - (int)(cp - &data[4])), 964 (unsigned)(*totsize - (int)(cp - &data[4])),
969 "%s,t,%#x", 965 "%s,t,%#x",
970 sess->globals->targetname, 966 sess->globals->targetname,
971 lun); 967 lun);
972 cp[3] = len; 968 cp[3] = len;
973 *totlen += len + 4; 969 *totlen += len + 4;
974 cp += len + 4; 970 cp += len + 4;
975 /* add target port's IQN + LUN extension */ 971 /* add target port's IQN + LUN extension */
976 cp[0] = (INQUIRY_DEVICE_ISCSI_PROTOCOL << 4) | INQUIRY_DEVICE_CODESET_UTF8; 972 cp[0] = (INQUIRY_DEVICE_ISCSI_PROTOCOL << 4) | INQUIRY_DEVICE_CODESET_UTF8;
977 cp[1] = (INQUIRY_DEVICE_PIV << 7) | (INQUIRY_DEVICE_ASSOCIATION_LOGICAL_UNIT << 4) | INQUIRY_DEVICE_IDENTIFIER_SCSI_NAME; 973 cp[1] = (INQUIRY_DEVICE_PIV << 7) | (INQUIRY_DEVICE_ASSOCIATION_LOGICAL_UNIT << 4) | INQUIRY_DEVICE_IDENTIFIER_SCSI_NAME;
978 if (disks.v[sess->d].uuid_string == NULL) { 974 if (disks.v[sess->d].uuid_string == NULL) {
979 uuid_create(&disks.v[sess->d].uuid, &status); 975 nbuuid_create(&disks.v[sess->d].uuid, &status);
980 uuid_to_string(&disks.v[sess->d].uuid, &disks.v[sess->d].uuid_string, &status); 976 nbuuid_to_string(&disks.v[sess->d].uuid, &disks.v[sess->d].uuid_string, &status);
981 } 977 }
982 len = (uint8_t) snprintf((char *)&cp[4], 978 len = (uint8_t) snprintf((char *)&cp[4],
983 (unsigned)(*totsize - (int)(cp - &data[4])), 979 (unsigned)(*totsize - (int)(cp - &data[4])),
984 "%s,L,0x%8.8s%4.4s%4.4s", 980 "%s,L,0x%8.8s%4.4s%4.4s",
985 sess->globals->targetname, 981 sess->globals->targetname,
986 disks.v[sess->d].uuid_string, 982 disks.v[sess->d].uuid_string,
987 &disks.v[sess->d].uuid_string[9], 983 &disks.v[sess->d].uuid_string[9],
988 &disks.v[sess->d].uuid_string[14]); 984 &disks.v[sess->d].uuid_string[14]);
989 cp[3] = len; 985 cp[3] = len;
990 *totlen += len + 4; 986 *totlen += len + 4;
991 cp += len + 4; 987 cp += len + 4;
992 /* add target's uuid as a T10 identifier */ 988 /* add target's uuid as a T10 identifier */
993 cp[0] = (INQUIRY_DEVICE_ISCSI_PROTOCOL << 4) | INQUIRY_DEVICE_CODESET_UTF8; 989 cp[0] = (INQUIRY_DEVICE_ISCSI_PROTOCOL << 4) | INQUIRY_DEVICE_CODESET_UTF8;
994 cp[1] = (INQUIRY_DEVICE_PIV << 7) | (INQUIRY_DEVICE_ASSOCIATION_TARGET_DEVICE << 4) | INQUIRY_IDENTIFIER_TYPE_T10; 990 cp[1] = (INQUIRY_DEVICE_PIV << 7) | (INQUIRY_DEVICE_ASSOCIATION_TARGET_DEVICE << 4) | INQUIRY_IDENTIFIER_TYPE_T10;
995 strpadcpy(&cp[4], 8, ISCSI_VENDOR, strlen(ISCSI_VENDOR), ' '); 991 strpadcpy(&cp[4], 8, ISCSI_VENDOR, strlen(ISCSI_VENDOR), ' ');
996 len = 8; 992 len = 8;
997 len += (uint8_t) snprintf((char *)&cp[8 + 4], 993 len += (uint8_t) snprintf((char *)&cp[8 + 4],
998 (unsigned)(*totsize - (int)(cp - &data[4])), 994 (unsigned)(*totsize - (int)(cp - &data[4])),
999 "0x%8.8s%4.4s%4.4s", 995 "0x%8.8s%4.4s%4.4s",
1000 disks.v[sess->d].uuid_string, 996 disks.v[sess->d].uuid_string,
1001 &disks.v[sess->d].uuid_string[9], 997 &disks.v[sess->d].uuid_string[9],
1002 &disks.v[sess->d].uuid_string[14]); 998 &disks.v[sess->d].uuid_string[14]);
1003 cp[3] = len; 999 cp[3] = len;
1004 *totlen += len + 4; 1000 *totlen += len + 4;
1005 args->length = *totlen + 6; 1001 args->length = *totlen + 6;
1006 break; 1002 break;
1007 case INQUIRY_SUPPORTED_VPD_PAGES: 1003 case INQUIRY_SUPPORTED_VPD_PAGES:
1008 data[0] = DISK_PERIPHERAL_DEVICE; 1004 data[0] = DISK_PERIPHERAL_DEVICE;
1009 data[1] = INQUIRY_SUPPORTED_VPD_PAGES; 1005 data[1] = INQUIRY_SUPPORTED_VPD_PAGES;
1010 *totlen = 3; /* # of supported pages */ 1006 *totlen = 3; /* # of supported pages */
1011 data[4] = INQUIRY_SUPPORTED_VPD_PAGES; 1007 data[4] = INQUIRY_SUPPORTED_VPD_PAGES;
1012 data[5] = INQUIRY_DEVICE_IDENTIFICATION_VPD; 1008 data[5] = INQUIRY_DEVICE_IDENTIFICATION_VPD;
1013 data[6] = EXTENDED_INQUIRY_DATA_VPD; 1009 data[6] = EXTENDED_INQUIRY_DATA_VPD;
1014 args->length = *totsize + 1; 1010 args->length = *totsize + 1;
1015 break; 1011 break;
1016 case EXTENDED_INQUIRY_DATA_VPD: 1012 case EXTENDED_INQUIRY_DATA_VPD:
1017 data[0] = DISK_PERIPHERAL_DEVICE; 1013 data[0] = DISK_PERIPHERAL_DEVICE;
1018 data[1] = EXTENDED_INQUIRY_DATA_VPD; 1014 data[1] = EXTENDED_INQUIRY_DATA_VPD;
1019 data[3] = 0x3c; /* length is defined to be 60 */ 1015 data[3] = 0x3c; /* length is defined to be 60 */
1020 data[4] = 0; 1016 data[4] = 0;
1021 data[5] = 0; 1017 data[5] = 0;
1022 args->length = 64; 1018 args->length = 64;
1023 break; 1019 break;
1024 default: 1020 default:
1025 iscsi_trace_error(__FILE__, __LINE__, "Unsupported INQUIRY VPD page %x\n", cdb[2]); 1021 iscsi_trace_error(__FILE__, __LINE__, "Unsupported INQUIRY VPD page %x\n", cdb[2]);
1026 args->status = SCSI_CHECK_CONDITION; 1022 args->status = SCSI_CHECK_CONDITION;
1027 break; 1023 break;
1028 } 1024 }
1029 } else { 1025 } else {
1030 char versionstr[8]; 1026 char versionstr[8];
1031 1027
1032 data[0] = DISK_PERIPHERAL_DEVICE; 1028 data[0] = DISK_PERIPHERAL_DEVICE;
1033 data[2] = SCSI_VERSION_SPC; 1029 data[2] = SCSI_VERSION_SPC;
1034 data[4] = *totsize - 4; /* Additional length */ 1030 data[4] = *totsize - 4; /* Additional length */
1035 data[7] |= (WIDE_BUS_32 | WIDE_BUS_16); 1031 data[7] |= (WIDE_BUS_32 | WIDE_BUS_16);
1036 strpadcpy(&data[8], 8, ISCSI_VENDOR, strlen(ISCSI_VENDOR), ' '); 1032 strpadcpy(&data[8], 8, ISCSI_VENDOR, strlen(ISCSI_VENDOR), ' ');
1037 strpadcpy(&data[16], 16, ISCSI_PRODUCT, strlen(ISCSI_PRODUCT), ' '); 1033 strpadcpy(&data[16], 16, ISCSI_PRODUCT, strlen(ISCSI_PRODUCT), ' ');
1038 (void) snprintf(versionstr, sizeof(versionstr), "%d", ISCSI_VERSION); 1034 (void) snprintf(versionstr, sizeof(versionstr), "%d", ISCSI_VERSION);
1039 strpadcpy(&data[32], 4, versionstr, strlen(versionstr), ' '); 1035 strpadcpy(&data[32], 4, versionstr, strlen(versionstr), ' ');
1040 args->length = cdb[4] + 1; 1036 args->length = cdb[4] + 1;
1041 } 1037 }
1042 if (args->status == SCSI_SUCCESS) { 1038 if (args->status == SCSI_SUCCESS) {
1043 args->input = 1; 1039 args->input = 1;
1044 } 1040 }
1045 break; 1041 break;
1046 1042
1047 case MODE_SELECT_6: 1043 case MODE_SELECT_6:
1048 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "MODE_SELECT_6\n"); 1044 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "MODE_SELECT_6\n");
1049 args->status = SCSI_SUCCESS; 1045 args->status = SCSI_SUCCESS;
1050 args->length = 0; 1046 args->length = 0;
1051 break; 1047 break;
1052 1048
1053 case STOP_START_UNIT: 1049 case STOP_START_UNIT:
1054 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "STOP_START_UNIT\n"); 1050 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "STOP_START_UNIT\n");
1055 args->status = SCSI_SUCCESS; 1051 args->status = SCSI_SUCCESS;
1056 args->length = 0; 1052 args->length = 0;
1057 break; 1053 break;
1058 1054
1059 case READ_CAPACITY: 1055 case READ_CAPACITY:
1060 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "READ_CAPACITY\n"); 1056 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "READ_CAPACITY\n");
1061 data = args->send_data; 1057 data = args->send_data;
1062 *((uint32_t *) (void *)data) = (uint32_t) ISCSI_HTONL((uint32_t) disks.v[sess->d].blockc - 1); /* Max LBA */ 1058 *((uint32_t *) (void *)data) = (uint32_t) ISCSI_HTONL((uint32_t) disks.v[sess->d].blockc - 1); /* Max LBA */
1063 *((uint32_t *) (void *)(data + 4)) = (uint32_t) ISCSI_HTONL((uint32_t) disks.v[sess->d].blocklen); /* Block len */ 1059 *((uint32_t *) (void *)(data + 4)) = (uint32_t) ISCSI_HTONL((uint32_t) disks.v[sess->d].blocklen); /* Block len */
1064 args->input = 8; 1060 args->input = 8;
1065 args->length = 8; 1061 args->length = 8;
1066 args->status = SCSI_SUCCESS; 1062 args->status = SCSI_SUCCESS;
1067 break; 1063 break;
1068 1064
1069 case WRITE_6: 1065 case WRITE_6:
1070 lba = ISCSI_NTOHL(*((uint32_t *) (void *)cdb)) & 0x001fffff; 1066 lba = ISCSI_NTOHL(*((uint32_t *) (void *)cdb)) & 0x001fffff;
1071 if ((len = *totsize) == 0) { 1067 if ((len = *totsize) == 0) {
1072 len = 256; 1068 len = 256;
1073 } 1069 }
1074 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "WRITE_6(lba %u, len %u blocks)\n", lba, len); 1070 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "WRITE_6(lba %u, len %u blocks)\n", lba, len);
1075 if (disk_write(sess, args, lun, lba, (unsigned) len) != 0) { 1071 if (disk_write(sess, args, lun, lba, (unsigned) len) != 0) {
1076 iscsi_trace_error(__FILE__, __LINE__, "disk_write() failed\n"); 1072 iscsi_trace_error(__FILE__, __LINE__, "disk_write() failed\n");
1077 args->status = SCSI_CHECK_CONDITION; 1073 args->status = SCSI_CHECK_CONDITION;
1078 } 1074 }
1079 args->length = 0; 1075 args->length = 0;
1080 break; 1076 break;
1081 1077
1082 1078
1083 case READ_6: 1079 case READ_6:
1084 lba = ISCSI_NTOHL(*((uint32_t *) (void *)cdb)) & 0x001fffff; 1080 lba = ISCSI_NTOHL(*((uint32_t *) (void *)cdb)) & 0x001fffff;
1085 if ((len = *totsize) == 0) { 1081 if ((len = *totsize) == 0) {
1086 len = 256; 1082 len = 256;
1087 } 1083 }
1088 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "READ_6(lba %u, len %u blocks)\n", lba, len); 1084 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "READ_6(lba %u, len %u blocks)\n", lba, len);
1089 if (disk_read(sess, args, lba, len, lun) != 0) { 1085 if (disk_read(sess, args, lba, len, lun) != 0) {
1090 iscsi_trace_error(__FILE__, __LINE__, "disk_read() failed\n"); 1086 iscsi_trace_error(__FILE__, __LINE__, "disk_read() failed\n");
1091 args->status = SCSI_CHECK_CONDITION; 1087 args->status = SCSI_CHECK_CONDITION;
1092 } 1088 }
1093 args->input = 1; 1089 args->input = 1;
1094 break; 1090 break;
1095 1091
1096 case MODE_SENSE_6: 1092 case MODE_SENSE_6:
1097 mode_sense(6, cmd); 1093 mode_sense(6, cmd);
1098 break; 1094 break;
1099 1095
1100 case WRITE_10: 1096 case WRITE_10:
1101 case WRITE_VERIFY: 1097 case WRITE_VERIFY:
1102 cdb2lba(&lba, &len, cdb); 1098 cdb2lba(&lba, &len, cdb);
1103 1099
1104 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "WRITE_10 | WRITE_VERIFY(lba %u, len %u blocks)\n", lba, len); 1100 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "WRITE_10 | WRITE_VERIFY(lba %u, len %u blocks)\n", lba, len);
1105 if (disk_write(sess, args, lun, lba, (unsigned) len) != 0) { 1101 if (disk_write(sess, args, lun, lba, (unsigned) len) != 0) {
1106 iscsi_trace_error(__FILE__, __LINE__, "disk_write() failed\n"); 1102 iscsi_trace_error(__FILE__, __LINE__, "disk_write() failed\n");
1107 args->status = SCSI_CHECK_CONDITION; 1103 args->status = SCSI_CHECK_CONDITION;
1108 } 1104 }
1109 args->length = 0; 1105 args->length = 0;
1110 break; 1106 break;
1111 1107
1112 case READ_10: 1108 case READ_10:
1113 cdb2lba(&lba, &len, cdb); 1109 cdb2lba(&lba, &len, cdb);
1114 1110
1115 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "READ_10(lba %u, len %u blocks)\n", lba, len); 1111 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "READ_10(lba %u, len %u blocks)\n", lba, len);
1116 if (disk_read(sess, args, lba, len, lun) != 0) { 1112 if (disk_read(sess, args, lba, len, lun) != 0) {
1117 iscsi_trace_error(__FILE__, __LINE__, "disk_read() failed\n"); 1113 iscsi_trace_error(__FILE__, __LINE__, "disk_read() failed\n");
1118 args->status = SCSI_CHECK_CONDITION; 1114 args->status = SCSI_CHECK_CONDITION;
1119 } 1115 }
1120 args->input = 1; 1116 args->input = 1;
1121 break; 1117 break;
1122 1118
1123 case VERIFY: 1119 case VERIFY:
1124 /* For now just set the status to success. */ 1120 /* For now just set the status to success. */
1125 args->status = SCSI_SUCCESS; 1121 args->status = SCSI_SUCCESS;
1126 break; 1122 break;
1127 1123
1128 case SYNC_CACHE: 1124 case SYNC_CACHE:
1129 cdb2lba(&lba, &len, cdb); 1125 cdb2lba(&lba, &len, cdb);
1130 1126
1131 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "SYNC_CACHE (lba %u, len %u blocks)\n", lba, len); 1127 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "SYNC_CACHE (lba %u, len %u blocks)\n", lba, len);
1132 if (de_fsync_range(&disks.v[sess->d].tv->v[lun].de, FDATASYNC, lba, (off_t)(len * disks.v[sess->d].blocklen)) < 0) { 1128 if (de_fsync_range(&disks.v[sess->d].tv->v[lun].de, FDATASYNC, lba, (off_t)(len * disks.v[sess->d].blocklen)) < 0) {
1133 iscsi_trace_error(__FILE__, __LINE__, "disk_read() failed\n"); 1129 iscsi_trace_error(__FILE__, __LINE__, "disk_read() failed\n");
1134 args->status = SCSI_CHECK_CONDITION; 1130 args->status = SCSI_CHECK_CONDITION;
1135 } else { 1131 } else {
1136 args->status = SCSI_SUCCESS; 1132 args->status = SCSI_SUCCESS;
1137 args->length = 0; 1133 args->length = 0;
1138 } 1134 }
1139 break; 1135 break;
1140 1136
1141 case LOG_SENSE: 1137 case LOG_SENSE:
1142 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "LOG_SENSE\n"); 1138 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "LOG_SENSE\n");
1143 args->status = SCSI_SUCCESS; 1139 args->status = SCSI_SUCCESS;
1144 args->length = 0; 1140 args->length = 0;
1145 break; 1141 break;
1146 1142
1147 case MODE_SENSE_10: 1143 case MODE_SENSE_10:
1148 mode_sense(10, cmd); 1144 mode_sense(10, cmd);
1149 break; 1145 break;
1150 1146
1151 case MODE_SELECT_10: 1147 case MODE_SELECT_10:
1152 /* XXX still to do */ 1148 /* XXX still to do */
1153 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "MODE_SELECT_10\n"); 1149 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "MODE_SELECT_10\n");
1154 args->status = SCSI_SUCCESS; 1150 args->status = SCSI_SUCCESS;
1155 args->length = 0; 1151 args->length = 0;
1156 break; 1152 break;
1157 1153
1158 case PERSISTENT_RESERVE_IN: 1154 case PERSISTENT_RESERVE_IN:
1159 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "PERSISTENT_RESERVE_IN\n"); 1155 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "PERSISTENT_RESERVE_IN\n");
1160 args->length = persistent_reserve_in((cdb[1] & PERSISTENT_RESERVE_IN_SERVICE_ACTION_MASK), args->send_data); 1156 args->length = persistent_reserve_in((cdb[1] & PERSISTENT_RESERVE_IN_SERVICE_ACTION_MASK), args->send_data);
1161 args->status = SCSI_SUCCESS; 1157 args->status = SCSI_SUCCESS;
1162 break; 1158 break;
1163 1159
1164 case REPORT_LUNS: 1160 case REPORT_LUNS:
1165 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "REPORT LUNS\n"); 1161 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "REPORT LUNS\n");
1166 args->length = report_luns((uint64_t *)(void *)&args->send_data[8], (off_t)disks.v[sess->d].luns); 1162 args->length = report_luns((uint64_t *)(void *)&args->send_data[8], (off_t)disks.v[sess->d].luns);
1167 *((uint32_t *) (void *)args->send_data) = ISCSI_HTONL(disks.v[sess->d].luns * sizeof(uint64_t)); 1163 *((uint32_t *) (void *)args->send_data) = ISCSI_HTONL(disks.v[sess->d].luns * sizeof(uint64_t));
1168 args->input = 8; 1164 args->input = 8;
1169 args->status = SCSI_SUCCESS; 1165 args->status = SCSI_SUCCESS;
1170 break; 1166 break;
1171 1167
1172 case RESERVE_6: 1168 case RESERVE_6:
1173 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "RESERVE_6\n"); 1169 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "RESERVE_6\n");
1174 args->status = SCSI_SUCCESS; 1170 args->status = SCSI_SUCCESS;
1175 args->length = 0; 1171 args->length = 0;
1176 break; 1172 break;
1177 1173
1178 case RELEASE_6: 1174 case RELEASE_6:
1179 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "RELEASE_6\n"); 1175 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "RELEASE_6\n");
1180 args->status = SCSI_SUCCESS; 1176 args->status = SCSI_SUCCESS;
1181 args->length = 0; 1177 args->length = 0;
1182 break; 1178 break;
1183 1179
1184 case RESERVE_10: 1180 case RESERVE_10:
1185 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "RESERVE_10\n"); 1181 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "RESERVE_10\n");
1186 args->status = SCSI_SUCCESS; 1182 args->status = SCSI_SUCCESS;
1187 args->length = 0; 1183 args->length = 0;
1188 break; 1184 break;
1189 1185
1190 case RELEASE_10: 1186 case RELEASE_10:
1191 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "RELEASE_10\n"); 1187 iscsi_trace(TRACE_SCSI_CMD, __FILE__, __LINE__, "RELEASE_10\n");
1192 args->status = SCSI_SUCCESS; 1188 args->status = SCSI_SUCCESS;
1193 args->length = 0; 1189 args->length = 0;
1194 break; 1190 break;
1195 1191
1196 default: 1192 default:
1197 iscsi_trace_error(__FILE__, __LINE__, "UNKNOWN OPCODE %#x\n", cdb[0]); 1193 iscsi_trace_error(__FILE__, __LINE__, "UNKNOWN OPCODE %#x\n", cdb[0]);
1198 /* to not cause confusion with some initiators */ 1194 /* to not cause confusion with some initiators */
1199 args->status = SCSI_CHECK_CONDITION; 1195 args->status = SCSI_CHECK_CONDITION;
1200 break; 1196 break;
1201 } 1197 }
1202 iscsi_trace(TRACE_SCSI_DEBUG, __FILE__, __LINE__, "SCSI op %#x: done (status %#x)\n", cdb[0], args->status); 1198 iscsi_trace(TRACE_SCSI_DEBUG, __FILE__, __LINE__, "SCSI op %#x: done (status %#x)\n", cdb[0], args->status);
1203 return 0; 1199 return 0;
1204} 1200}
1205 1201
1206/*ARGSUSED*/ 1202/*ARGSUSED*/
1207int  1203int
1208device_shutdown(target_session_t *sess) 1204device_shutdown(target_session_t *sess)
1209{ 1205{
1210 return 1; 1206 return 1;
1211} 1207}
1212 1208
1213/* 1209/*
1214 * Private Interface 1210 * Private Interface
1215 */ 1211 */
1216 1212
1217static int  1213static int
1218disk_write(target_session_t *sess, iscsi_scsi_cmd_args_t *args, uint8_t lun, uint32_t lba, uint32_t len) 1214disk_write(target_session_t *sess, iscsi_scsi_cmd_args_t *args, uint8_t lun, uint32_t lba, uint32_t len)
1219{ 1215{
1220 uint64_t byte_offset = lba * disks.v[sess->d].blocklen; 1216 uint64_t byte_offset = lba * disks.v[sess->d].blocklen;
1221 uint64_t num_bytes = len * disks.v[sess->d].blocklen; 1217 uint64_t num_bytes = len * disks.v[sess->d].blocklen;
1222 uint8_t *ptr = NULL; 1218 uint8_t *ptr = NULL;
1223 struct iovec sg; 1219 struct iovec sg;
1224 1220
1225 iscsi_trace(TRACE_SCSI_DATA, __FILE__, __LINE__, "writing %" PRIu64 " bytes from socket into device at byte offset %" PRIu64 "\n", num_bytes, byte_offset); 1221 iscsi_trace(TRACE_SCSI_DATA, __FILE__, __LINE__, "writing %" PRIu64 " bytes from socket into device at byte offset %" PRIu64 "\n", num_bytes, byte_offset);
1226 1222
1227 /* Assign ptr for write data */ 1223 /* Assign ptr for write data */
1228 1224
1229 RETURN_GREATER("num_bytes (FIX ME)", (unsigned) num_bytes, MB(1), NO_CLEANUP, -1); 1225 RETURN_GREATER("num_bytes (FIX ME)", (unsigned) num_bytes, MB(1), NO_CLEANUP, -1);
1230 ptr = disks.v[sess->d].buffer; 1226 ptr = disks.v[sess->d].buffer;
1231 1227
1232 /* Have target do data transfer */ 1228 /* Have target do data transfer */
1233 1229
1234 sg.iov_base = ptr; 1230 sg.iov_base = ptr;
1235 sg.iov_len = (unsigned)num_bytes; 1231 sg.iov_len = (unsigned)num_bytes;
1236 if (target_transfer_data(sess, args, &sg, 1) != 0) { 1232 if (target_transfer_data(sess, args, &sg, 1) != 0) {
1237 iscsi_trace_error(__FILE__, __LINE__, "target_transfer_data() failed\n"); 1233 iscsi_trace_error(__FILE__, __LINE__, "target_transfer_data() failed\n");
1238 } 1234 }
1239 /* Finish up write */ 1235 /* Finish up write */
1240 if (de_lseek(&disks.v[sess->d].tv->v[lun].de, (off_t) byte_offset, SEEK_SET) == -1) { 1236 if (de_lseek(&disks.v[sess->d].tv->v[lun].de, (off_t) byte_offset, SEEK_SET) == -1) {
1241 iscsi_trace_error(__FILE__, __LINE__, "lseek() to offset %" PRIu64 " failed\n", byte_offset); 1237 iscsi_trace_error(__FILE__, __LINE__, "lseek() to offset %" PRIu64 " failed\n", byte_offset);
1242 return -1; 1238 return -1;
1243 } 1239 }
1244 if (!target_writable(&disks.v[sess->d].tv->v[lun])) { 1240 if (!target_writable(&disks.v[sess->d].tv->v[lun])) {
1245 iscsi_trace_error(__FILE__, __LINE__, "write() of %" PRIu64 " bytes failed at offset %" PRIu64 ", size %" PRIu64 "[READONLY TARGET]\n", num_bytes, byte_offset, de_getsize(&disks.v[sess->d].tv->v[lun].de)); 1241 iscsi_trace_error(__FILE__, __LINE__, "write() of %" PRIu64 " bytes failed at offset %" PRIu64 ", size %" PRIu64 "[READONLY TARGET]\n", num_bytes, byte_offset, de_getsize(&disks.v[sess->d].tv->v[lun].de));
1246 return -1; 1242 return -1;
1247 } 1243 }
1248 if ((uint64_t)de_write(&disks.v[sess->d].tv->v[lun].de, ptr, (unsigned) num_bytes) != num_bytes) { 1244 if ((uint64_t)de_write(&disks.v[sess->d].tv->v[lun].de, ptr, (unsigned) num_bytes) != num_bytes) {
1249 iscsi_trace_error(__FILE__, __LINE__, "write() of %" PRIu64 " bytes failed at offset %" PRIu64 ", size %" PRIu64 "\n", num_bytes, byte_offset, de_getsize(&disks.v[sess->d].tv->v[lun].de)); 1245 iscsi_trace_error(__FILE__, __LINE__, "write() of %" PRIu64 " bytes failed at offset %" PRIu64 ", size %" PRIu64 "\n", num_bytes, byte_offset, de_getsize(&disks.v[sess->d].tv->v[lun].de));
1250 return -1; 1246 return -1;
1251 } 1247 }
1252 iscsi_trace(TRACE_SCSI_DATA, __FILE__, __LINE__, "wrote %" PRIu64 " bytes to device OK\n", num_bytes); 1248 iscsi_trace(TRACE_SCSI_DATA, __FILE__, __LINE__, "wrote %" PRIu64 " bytes to device OK\n", num_bytes);
1253 return 0; 1249 return 0;
1254} 1250}
1255 1251
1256static int  1252static int
1257disk_read(target_session_t * sess, iscsi_scsi_cmd_args_t * args, uint32_t lba, uint16_t len, uint8_t lun) 1253disk_read(target_session_t * sess, iscsi_scsi_cmd_args_t * args, uint32_t lba, uint16_t len, uint8_t lun)
1258{ 1254{
1259 uint64_t byte_offset = lba * disks.v[sess->d].blocklen; 1255 uint64_t byte_offset = lba * disks.v[sess->d].blocklen;
1260 uint64_t num_bytes = len * disks.v[sess->d].blocklen; 1256 uint64_t num_bytes = len * disks.v[sess->d].blocklen;
1261 uint64_t extra = 0; 1257 uint64_t extra = 0;
1262 uint8_t *ptr = NULL; 1258 uint8_t *ptr = NULL;
1263 uint32_t n; 1259 uint32_t n;
1264 int rc; 1260 int rc;
1265 1261
1266 RETURN_EQUAL("len", len, 0, NO_CLEANUP, -1); 1262 RETURN_EQUAL("len", len, 0, NO_CLEANUP, -1);
1267 if ((lba > (disks.v[sess->d].blockc - 1)) || ((lba + len) > disks.v[sess->d].blockc)) { 1263 if ((lba > (disks.v[sess->d].blockc - 1)) || ((lba + len) > disks.v[sess->d].blockc)) {
1268 iscsi_trace_error(__FILE__, __LINE__, "attempt to read beyond end of media\n"); 1264 iscsi_trace_error(__FILE__, __LINE__, "attempt to read beyond end of media\n");
1269 iscsi_trace_error(__FILE__, __LINE__, "max_lba = %" PRIu64 ", requested lba = %u, len = %u\n", disks.v[sess->d].blockc - 1, lba, len); 1265 iscsi_trace_error(__FILE__, __LINE__, "max_lba = %" PRIu64 ", requested lba = %u, len = %u\n", disks.v[sess->d].blockc - 1, lba, len);
1270 return -1; 1266 return -1;
1271 } 1267 }
1272 RETURN_GREATER("num_bytes (FIX ME)", (unsigned) num_bytes, MB(1), NO_CLEANUP, -1); 1268 RETURN_GREATER("num_bytes (FIX ME)", (unsigned) num_bytes, MB(1), NO_CLEANUP, -1);
1273 ptr = disks.v[sess->d].buffer; 1269 ptr = disks.v[sess->d].buffer;
1274 n = 0; 1270 n = 0;
1275 do { 1271 do {
1276 if (de_lseek(&disks.v[sess->d].tv->v[lun].de, (off_t)(n + byte_offset), SEEK_SET) == -1) { 1272 if (de_lseek(&disks.v[sess->d].tv->v[lun].de, (off_t)(n + byte_offset), SEEK_SET) == -1) {
1277 iscsi_trace_error(__FILE__, __LINE__, "lseek() failed\n"); 1273 iscsi_trace_error(__FILE__, __LINE__, "lseek() failed\n");
1278 return -1; 1274 return -1;
1279 } 1275 }
1280 rc = de_read(&disks.v[sess->d].tv->v[lun].de, ptr + n, (size_t)(num_bytes - n)); 1276 rc = de_read(&disks.v[sess->d].tv->v[lun].de, ptr + n, (size_t)(num_bytes - n));
1281 if (rc <= 0) { 1277 if (rc <= 0) {
1282 iscsi_trace_error(__FILE__, __LINE__, "read() failed: rc %d errno %d\n", rc, errno); 1278 iscsi_trace_error(__FILE__, __LINE__, "read() failed: rc %d errno %d\n", rc, errno);
1283 return -1; 1279 return -1;
1284 } 1280 }
1285 n += rc; 1281 n += rc;
1286 if (n < num_bytes) { 1282 if (n < num_bytes) {
1287 iscsi_trace_error(__FILE__, __LINE__, "Got partial file read: %d bytes of %" PRIu64 "\n", rc, num_bytes - n + rc); 1283 iscsi_trace_error(__FILE__, __LINE__, "Got partial file read: %d bytes of %" PRIu64 "\n", rc, num_bytes - n + rc);
1288 } 1284 }
1289 } while (n < num_bytes); 1285 } while (n < num_bytes);
1290 1286
1291 ((struct iovec *) (void *)args->send_data)[0].iov_base = ptr + (unsigned) extra; 1287 ((struct iovec *) (void *)args->send_data)[0].iov_base = ptr + (unsigned) extra;
1292 ((struct iovec *) (void *)args->send_data)[0].iov_len = (unsigned) num_bytes; 1288 ((struct iovec *) (void *)args->send_data)[0].iov_len = (unsigned) num_bytes;
1293 args->length = (unsigned) num_bytes; 1289 args->length = (unsigned) num_bytes;
1294 args->send_sg_len = 1; 1290 args->send_sg_len = 1;
1295 args->status = 0; 1291 args->status = 0;
1296 1292
1297 return 0; 1293 return 0;
1298} 1294}

cvs diff -r1.3 -r1.4 src/dist/iscsi/src/Attic/uuid.c (switch to unified diff)

--- src/dist/iscsi/src/Attic/uuid.c 2007/06/16 23:13:26 1.3
+++ src/dist/iscsi/src/Attic/uuid.c 2009/06/23 05:11:47 1.4
@@ -1,100 +1,93 @@ @@ -1,100 +1,93 @@
1/* $NetBSD: uuid.c,v 1.3 2007/06/16 23:13:26 agc Exp $ */ 1/* $NetBSD: uuid.c,v 1.4 2009/06/23 05:11:47 agc Exp $ */
2 2
3/* 3/*
4 * Copyright © 2006 Alistair Crooks. All rights reserved. 4 * Copyright © 2006 Alistair Crooks. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote 14 * 3. The name of the author may not be used to endorse or promote
15 * products derived from this software without specific prior written 15 * products derived from this software without specific prior written
16 * permission. 16 * permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30#include "config.h" 30#include "config.h"
31  31
32#ifdef HAVE_INTTYPES_H 32#ifdef HAVE_INTTYPES_H
33#include <inttypes.h> 33#include <inttypes.h>
34#endif 34#endif
35  35
36#include <sys/types.h> 36#include <sys/types.h>
37  37
38#ifdef HAVE_SYS_PARAM_H 38#ifdef HAVE_SYS_PARAM_H
39#include <sys/param.h> 39#include <sys/param.h>
40#endif 40#endif
41  41
42#ifdef HAVE_SYS_TIME_H 42#ifdef HAVE_SYS_TIME_H
43#include <sys/time.h> 43#include <sys/time.h>
44#endif 44#endif
45 45
46#include <stdio.h> 46#include <stdio.h>
47#include <stdlib.h> 47#include <stdlib.h>
48#include <string.h> 48#include <string.h>
49#include <unistd.h> 49#include <unistd.h>
50 50
51#ifdef HAVE_UUID_H 51#include "storage.h"
52#include <uuid.h> 
53#endif 
54 
55#include "compat.h" 52#include "compat.h"
56#include "defs.h" 53#include "defs.h"
57 54
58#ifndef HAVE_UUID_CREATE 
59/* just fill the struct with random values for now */ 55/* just fill the struct with random values for now */
60void 56void
61uuid_create(uuid_t *uuid, uint32_t *status) 57nbuuid_create(nbuuid_t *uuid, uint32_t *status)
62{ 58{
63 uint64_t ether; 59 uint64_t ether;
64 time_t t; 60 time_t t;
65 61
66 (void) time(&t); 62 (void) time(&t);
67 ether = (random() << 32) | random(); 63 ether = ((uint64_t)random() << 32) | random();
68 uuid->time_low = t; 64 uuid->time_low = t;
69 uuid->time_mid = (uint16_t)(random() & 0xffff); 65 uuid->time_mid = (uint16_t)(random() & 0xffff);
70 uuid->time_hi_and_version = (uint16_t)(random() & 0xffff); 66 uuid->time_hi_and_version = (uint16_t)(random() & 0xffff);
71 uuid->clock_seq_low = random() & 0xff; 67 uuid->clock_seq_low = random() & 0xff;
72 uuid->clock_seq_hi_and_reserved = random() & 0xff; 68 uuid->clock_seq_hi_and_reserved = random() & 0xff;
73 (void) memcpy(&uuid->node, &ether, sizeof(uuid->node)); 69 (void) memcpy(&uuid->node, &ether, sizeof(uuid->node));
74 *status = 0; 70 *status = 0;
75} 71}
76#endif 
77 72
78#ifndef HAVE_UUID_TO_STRING 
79/* convert the struct to a printable string */ 73/* convert the struct to a printable string */
80void 74void
81uuid_to_string(uuid_t *uuid, char **str, uint32_t *status) 75nbuuid_to_string(nbuuid_t *uuid, char **str, uint32_t *status)
82{ 76{
83 char s[64]; 77 char s[64];
84 78
85 (void) snprintf(s, sizeof(s), "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", 79 (void) snprintf(s, sizeof(s), "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
86 uuid->time_low, 80 uuid->time_low,
87 uuid->time_mid, 81 uuid->time_mid,
88 uuid->time_hi_and_version, 82 uuid->time_hi_and_version,
89 uuid->clock_seq_hi_and_reserved, 83 uuid->clock_seq_hi_and_reserved,
90 uuid->clock_seq_low, 84 uuid->clock_seq_low,
91 uuid->node[0], 85 uuid->node[0],
92 uuid->node[1], 86 uuid->node[1],
93 uuid->node[2], 87 uuid->node[2],
94 uuid->node[3], 88 uuid->node[3],
95 uuid->node[4], 89 uuid->node[4],
96 uuid->node[5]); 90 uuid->node[5]);
97 *str = strdup(s); 91 *str = strdup(s);
98 *status = 0; 92 *status = 0;
99} 93}
100#endif