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:
parent
6fa7cdbb77
commit
ec095879d4
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue