Introduce a backwards compatible change to the targets configuration

file.

The new file specifies whether targets should be presented as readonly
or read-write.

If a target is marked as read-only, don't allow any writes to be made
to it.

Also, add syntax recognition of "any" and "all" in the netmask recognition
code.
This commit is contained in:
agc 2006-02-16 19:19:38 +00:00
parent 6fa7cdbb77
commit ec095879d4
4 changed files with 81 additions and 13 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: storage.h,v 1.2 2006/02/09 23:08:31 agc Exp $ */
/* $NetBSD: storage.h,v 1.3 2006/02/16 19:19:38 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
@ -73,12 +73,17 @@ typedef struct disc_device_t {
DEFINE_ARRAY(devv_t, disc_device_t);
enum {
TARGET_READONLY = 0x01
};
/* this struct describes an iscsi target's associated features */
typedef struct disc_target_t {
char *target; /* target name */
disc_de_t de; /* pointer to its device */
uint16_t port; /* port to listen on */
char *mask; /* mask to export it to */
uint32_t flags; /* any flags */
} disc_target_t;
DEFINE_ARRAY(targv_t, disc_target_t);

13
dist/iscsi/src/disk.c vendored
View File

@ -444,6 +444,13 @@ de_write(disc_de_t *dp, void *buf, size_t cc)
}
}
/* return non-zero if the target is writable */
static int
target_writable(disc_target_t *tp)
{
return !(tp->flags & TARGET_READONLY);
}
/* return size of the extent */
static uint64_t
extent_getsize(disc_extent_t *xp)
@ -651,6 +658,8 @@ allocate_space(disc_target_t *tp)
{
int i;
/* Don't perform check for writability in the target here, as the
following write() in de_allocate is non-destructive */
switch(tp->de.type) {
case DE_EXTENT:
return de_allocate(&tp->de, tp->target);
@ -1050,6 +1059,10 @@ disk_write(target_session_t *sess, iscsi_scsi_cmd_args_t *args, uint8_t lun, uin
TRACE_ERROR("lseek() to offset %" PRIu64 " failed\n", byte_offset);
return -1;
}
if (!target_writable(&disks.v[sess->d].tv->v[sess->d])) {
TRACE_ERROR("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[0].de));
return -1;
}
if (de_write(&disks.v[sess->d].tv->v[sess->d].de, ptr, (unsigned) num_bytes) != num_bytes) {
TRACE_ERROR("write() of %" PRIu64 " bytes failed at offset %" PRIu64 ", size %" PRIu64 "\n", num_bytes, byte_offset, de_getsize(&disks.v[sess->d].tv->v[0].de));
return -1;

View File

@ -1,4 +1,4 @@
/* $NetBSD: netmask.c,v 1.2 2006/02/12 15:33:26 agc Exp $ */
/* $NetBSD: netmask.c,v 1.3 2006/02/16 19:19:38 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
@ -36,7 +36,7 @@
#ifndef lint
__COPYRIGHT("@(#) Copyright © 2006 \
The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: netmask.c,v 1.2 2006/02/12 15:33:26 agc Exp $");
__RCSID("$NetBSD: netmask.c,v 1.3 2006/02/16 19:19:38 agc Exp $");
#endif
#include <sys/types.h>
@ -55,21 +55,46 @@ enum {
NETMASK_BUFFER_SIZE = 256
};
/* this struct is used to define a magic netmask value */
typedef struct magic_t {
const char *magic; /* string to match */
const char *xform; /* string to transform it into */
} magic_t;
static magic_t magics[] = {
{ "any", "0/0" },
{ "all", "0/0" },
{ "none", "0/32" },
{ NULL, }
};
#ifndef ISCSI_HTONL
#define ISCSI_HTONL(x) htonl(x)
#endif
/* return 1 if address is in netmask's range */
int
allow_netmask(const char *netmask, const char *addr)
allow_netmask(const char *netmaskarg, const char *addr)
{
struct in_addr a;
struct in_addr m;
const char *netmask;
magic_t *mp;
char maskaddr[NETMASK_BUFFER_SIZE];
char *cp;
int slash;
int i;
/* firstly check for any magic values in the netmask */
netmask = netmaskarg;
for (mp = magics ; mp->magic ; mp++) {
if (strcmp(netmask, mp->magic) == 0) {
netmask = mp->xform;
break;
}
}
/* find out if slash notation has been used */
(void) memset(&a, 0x0, sizeof(a));
if ((cp = strchr(netmask, '/')) == NULL) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: storage.c,v 1.1 2006/02/09 23:08:31 agc Exp $ */
/* $NetBSD: storage.c,v 1.2 2006/02/16 19:19:38 agc Exp $ */
/*
* Copyright © 2006 Alistair Crooks. All rights reserved.
@ -68,10 +68,15 @@ enum {
DEVICE_LENGTH_COL = 2,
TARGET_NAME_COL = 0,
TARGET_DEVICE_COL = 1,
TARGET_NETMASK_COL = 2
TARGET_V1_DEVICE_COL = 1,
TARGET_V1_NETMASK_COL = 2,
TARGET_V2_FLAGS_COL = 1,
TARGET_V2_DEVICE_COL = 2,
TARGET_V2_NETMASK_COL = 3
};
#define DEFAULT_FLAGS "ro"
/* find an extent by name */
static disc_extent_t *
@ -237,6 +242,9 @@ do_target(conffile_t *cf, targv_t *tvp, devv_t *devvp, extv_t *evp, ent_t *ep)
{
disc_extent_t *xp;
disc_device_t *dp;
const char *flags;
int netmaskcol;
int devcol;
if (find_target(tvp, ep->sv.v[TARGET_NAME_COL]) != NULL) {
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
@ -244,24 +252,41 @@ do_target(conffile_t *cf, targv_t *tvp, devv_t *devvp, extv_t *evp, ent_t *ep)
return 0;
}
ALLOC(disc_target_t, tvp->v, tvp->size, tvp->c, 14, 14, "do_target", exit(EXIT_FAILURE));
if ((dp = find_device(devvp, ep->sv.v[TARGET_DEVICE_COL])) != NULL) {
if (ep->sv.c == 3) {
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Warning: old 3 field \"targets\" entry, assuming read-only target\n");
devcol = TARGET_V1_DEVICE_COL;
netmaskcol = TARGET_V1_NETMASK_COL;
flags = DEFAULT_FLAGS;
} else {
devcol = TARGET_V2_DEVICE_COL;
flags = ep->sv.v[TARGET_V2_FLAGS_COL];
netmaskcol = TARGET_V2_NETMASK_COL;
}
if ((dp = find_device(devvp, ep->sv.v[devcol])) != NULL) {
tvp->v[tvp->c].de.type = DE_DEVICE;
tvp->v[tvp->c].de.u.dp = dp;
tvp->v[tvp->c].target = strdup(ep->sv.v[TARGET_NAME_COL]);
tvp->v[tvp->c].mask = strdup(ep->sv.v[TARGET_NETMASK_COL]);
tvp->v[tvp->c].mask = strdup(ep->sv.v[netmaskcol]);
if (strcmp(flags, "readonly") == 0 || strcmp(flags, "ro") == 0 || strcmp(flags, "r") == 0) {
tvp->v[tvp->c].flags |= TARGET_READONLY;
}
tvp->c += 1;
return 1;
}
if ((xp = find_extent(evp, ep->sv.v[TARGET_DEVICE_COL])) != NULL) {
if ((xp = find_extent(evp, ep->sv.v[devcol])) != NULL) {
tvp->v[tvp->c].de.type = DE_EXTENT;
tvp->v[tvp->c].de.u.xp = xp;
tvp->v[tvp->c].target = strdup(ep->sv.v[TARGET_NAME_COL]);
tvp->v[tvp->c].mask = strdup(ep->sv.v[TARGET_NETMASK_COL]);
tvp->v[tvp->c].mask = strdup(ep->sv.v[netmaskcol]);
if (strcmp(flags, "readonly") == 0 || strcmp(flags, "ro") == 0 || strcmp(flags, "r") == 0) {
tvp->v[tvp->c].flags |= TARGET_READONLY;
}
tvp->c += 1;
return 1;
}
(void) fprintf(stderr, "%s:%d: ", conffile_get_name(cf), conffile_get_lineno(cf));
(void) fprintf(stderr, "Error: no device or extent found for `%s'\n", ep->sv.v[TARGET_DEVICE_COL]);
(void) fprintf(stderr, "Error: no device or extent found for `%s'\n", ep->sv.v[devcol]);
return 0;
}
@ -318,7 +343,7 @@ ptarget(disc_target_t *tp, int indent)
for (i = 0 ; i < indent ; i++) {
(void) fputc('\t', stdout);
}
printf("%s:%s\n", tp->target, tp->mask);
printf("%s:%s:%s\n", tp->target, (tp->flags & TARGET_READONLY) ? "ro" : "rw", tp->mask);
pu(&tp->de, indent + 1);
}