diff options
author | mav <mav@FreeBSD.org> | 2014-07-24 15:31:45 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2014-07-24 15:31:45 +0000 |
commit | 65d6dfa894ef65753d5a9b8cfd692f07a47801ec (patch) | |
tree | 2231e52edc4866e57e0e0baa7e23a74a0fd93703 /sys/dev/iscsi | |
parent | c739145ff0dbb31f2524799e8e0ca862acc13ab6 (diff) | |
download | FreeBSD-src-65d6dfa894ef65753d5a9b8cfd692f07a47801ec.zip FreeBSD-src-65d6dfa894ef65753d5a9b8cfd692f07a47801ec.tar.gz |
MFC r267613 (by trasz):
Implement redirection handling in initiator.
Diffstat (limited to 'sys/dev/iscsi')
-rw-r--r-- | sys/dev/iscsi/iscsi.c | 77 | ||||
-rw-r--r-- | sys/dev/iscsi/iscsi_ioctl.h | 7 |
2 files changed, 71 insertions, 13 deletions
diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c index 188b378..d8685fd 100644 --- a/sys/dev/iscsi/iscsi.c +++ b/sys/dev/iscsi/iscsi.c @@ -1635,6 +1635,33 @@ iscsi_sanitize_session_conf(struct iscsi_session_conf *isc) isc->isc_mutual_secret[ISCSI_SECRET_LEN - 1] = '\0'; } +static bool +iscsi_valid_session_conf(const struct iscsi_session_conf *isc) +{ + + if (isc->isc_initiator[0] == '\0') { + ISCSI_DEBUG("empty isc_initiator"); + return (false); + } + + if (isc->isc_target_addr[0] == '\0') { + ISCSI_DEBUG("empty isc_target_addr"); + return (false); + } + + if (isc->isc_discovery != 0 && isc->isc_target[0] != 0) { + ISCSI_DEBUG("non-empty isc_target for discovery session"); + return (false); + } + + if (isc->isc_discovery == 0 && isc->isc_target[0] == 0) { + ISCSI_DEBUG("empty isc_target for non-discovery session"); + return (false); + } + + return (true); +} + static int iscsi_ioctl_session_add(struct iscsi_softc *sc, struct iscsi_session_add *isa) { @@ -1643,22 +1670,12 @@ iscsi_ioctl_session_add(struct iscsi_softc *sc, struct iscsi_session_add *isa) int error; iscsi_sanitize_session_conf(&isa->isa_conf); + if (iscsi_valid_session_conf(&isa->isa_conf) == false) + return (EINVAL); is = malloc(sizeof(*is), M_ISCSI, M_ZERO | M_WAITOK); memcpy(&is->is_conf, &isa->isa_conf, sizeof(is->is_conf)); - if (is->is_conf.isc_initiator[0] == '\0' || - is->is_conf.isc_target_addr[0] == '\0') { - free(is, M_ISCSI); - return (EINVAL); - } - - if ((is->is_conf.isc_discovery != 0 && is->is_conf.isc_target[0] != 0) || - (is->is_conf.isc_discovery == 0 && is->is_conf.isc_target[0] == 0)) { - free(is, M_ISCSI); - return (EINVAL); - } - sx_xlock(&sc->sc_lock); /* @@ -1818,7 +1835,38 @@ iscsi_ioctl_session_list(struct iscsi_softc *sc, struct iscsi_session_list *isl) return (0); } - + +static int +iscsi_ioctl_session_modify(struct iscsi_softc *sc, + struct iscsi_session_modify *ism) +{ + struct iscsi_session *is; + + iscsi_sanitize_session_conf(&ism->ism_conf); + if (iscsi_valid_session_conf(&ism->ism_conf) == false) + return (EINVAL); + + sx_xlock(&sc->sc_lock); + TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { + ISCSI_SESSION_LOCK(is); + if (is->is_id == ism->ism_session_id) + break; + ISCSI_SESSION_UNLOCK(is); + } + if (is == NULL) { + sx_xunlock(&sc->sc_lock); + return (ESRCH); + } + sx_xunlock(&sc->sc_lock); + + memcpy(&is->is_conf, &ism->ism_conf, sizeof(is->is_conf)); + ISCSI_SESSION_UNLOCK(is); + + iscsi_session_reconnect(is); + + return (0); +} + static int iscsi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int mode, struct thread *td) @@ -1857,6 +1905,9 @@ iscsi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int mode, case ISCSISLIST: return (iscsi_ioctl_session_list(sc, (struct iscsi_session_list *)arg)); + case ISCSISMODIFY: + return (iscsi_ioctl_session_modify(sc, + (struct iscsi_session_modify *)arg)); default: return (EINVAL); } diff --git a/sys/dev/iscsi/iscsi_ioctl.h b/sys/dev/iscsi/iscsi_ioctl.h index 4e06b87..b7cb47d 100644 --- a/sys/dev/iscsi/iscsi_ioctl.h +++ b/sys/dev/iscsi/iscsi_ioctl.h @@ -202,8 +202,15 @@ struct iscsi_session_list { int isl_spare[4]; }; +struct iscsi_session_modify { + unsigned int ism_session_id; + struct iscsi_session_conf ism_conf; + int ism_spare[4]; +}; + #define ISCSISADD _IOW('I', 0x11, struct iscsi_session_add) #define ISCSISREMOVE _IOW('I', 0x12, struct iscsi_session_remove) #define ISCSISLIST _IOWR('I', 0x13, struct iscsi_session_list) +#define ISCSISMODIFY _IOWR('I', 0x14, struct iscsi_session_modify) #endif /* !ISCSI_IOCTL_H */ |