summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ctld
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2014-05-07 07:29:39 +0000
committertrasz <trasz@FreeBSD.org>2014-05-07 07:29:39 +0000
commit690b7a7a127bf05683bcac2f8623f493fa28647f (patch)
tree45ec51b4a29a711d6386f8830a84b1a439c93a3f /usr.sbin/ctld
parent7420d3ad268a728f49008826fe586a7d613617bf (diff)
downloadFreeBSD-src-690b7a7a127bf05683bcac2f8623f493fa28647f.zip
FreeBSD-src-690b7a7a127bf05683bcac2f8623f493fa28647f.tar.gz
MFC r264524:
Make it possible for the iSCSI target side to operate in both normal and ICL_KERNEL_PROXY mode, and fix some bit rot so the latter actually works again. Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'usr.sbin/ctld')
-rw-r--r--usr.sbin/ctld/ctld.c155
-rw-r--r--usr.sbin/ctld/kernel.c11
-rw-r--r--usr.sbin/ctld/pdu.c32
3 files changed, 112 insertions, 86 deletions
diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c
index 1090a52..354d0ed 100644
--- a/usr.sbin/ctld/ctld.c
+++ b/usr.sbin/ctld/ctld.c
@@ -48,6 +48,8 @@
#include "ctld.h"
+bool proxy_mode = false;
+
static volatile bool sighup_received = false;
static volatile bool sigterm_received = false;
static volatile bool sigalrm_received = false;
@@ -553,14 +555,6 @@ portal_group_add_listen(struct portal_group *pg, const char *value, bool iser)
const char *port;
int error, colons = 0;
-#ifndef ICL_KERNEL_PROXY
- if (iser) {
- log_warnx("ctld(8) compiled without ICL_KERNEL_PROXY "
- "does not support iSER protocol");
- return (-1);
- }
-#endif
-
portal = portal_new(pg);
portal->p_listen = checked_strdup(value);
portal->p_iser = iser;
@@ -1180,9 +1174,7 @@ conf_apply(struct conf *oldconf, struct conf *newconf)
struct portal *oldp, *newp;
pid_t otherpid;
int changed, cumulated_error = 0, error;
-#ifndef ICL_KERNEL_PROXY
int one = 1;
-#endif
if (oldconf->conf_debug != newconf->conf_debug) {
log_debugx("changing debug level to %d", newconf->conf_debug);
@@ -1415,10 +1407,14 @@ conf_apply(struct conf *oldconf, struct conf *newconf)
}
#ifdef ICL_KERNEL_PROXY
- log_debugx("listening on %s, portal-group \"%s\" using ICL proxy",
- newp->p_listen, newpg->pg_name);
- kernel_listen(newp->p_ai, newp->p_iser);
-#else
+ if (proxy_mode) {
+ log_debugx("listening on %s, portal-group \"%s\" using ICL proxy",
+ newp->p_listen, newpg->pg_name);
+ kernel_listen(newp->p_ai, newp->p_iser);
+ continue;
+ }
+#endif
+ assert(proxy_mode == false);
assert(newp->p_iser == false);
log_debugx("listening on %s, portal-group \"%s\"",
@@ -1461,7 +1457,6 @@ conf_apply(struct conf *oldconf, struct conf *newconf)
cumulated_error++;
continue;
}
-#endif /* !ICL_KERNEL_PROXY */
}
}
@@ -1579,11 +1574,9 @@ static void
handle_connection(struct portal *portal, int fd, bool dont_fork)
{
struct connection *conn;
-#ifndef ICL_KERNEL_PROXY
struct sockaddr_storage ss;
socklen_t sslen = sizeof(ss);
int error;
-#endif
pid_t pid;
char host[NI_MAXHOST + 1];
struct conf *conf;
@@ -1619,20 +1612,25 @@ handle_connection(struct portal *portal, int fd, bool dont_fork)
/*
* XXX
*/
- log_set_peer_addr("XXX");
-#else
- error = getpeername(fd, (struct sockaddr *)&ss, &sslen);
- if (error != 0)
- log_err(1, "getpeername");
- error = getnameinfo((struct sockaddr *)&ss, sslen,
- host, sizeof(host), NULL, 0, NI_NUMERICHOST);
- if (error != 0)
- log_errx(1, "getaddrinfo: %s", gai_strerror(error));
-
- log_debugx("accepted connection from %s; portal group \"%s\"",
- host, portal->p_portal_group->pg_name);
- log_set_peer_addr(host);
- setproctitle("%s", host);
+ if (proxy_mode) {
+ log_set_peer_addr("XXX");
+ } else {
+#endif
+ assert(proxy_mode == false);
+ error = getpeername(fd, (struct sockaddr *)&ss, &sslen);
+ if (error != 0)
+ log_err(1, "getpeername");
+ error = getnameinfo((struct sockaddr *)&ss, sslen,
+ host, sizeof(host), NULL, 0, NI_NUMERICHOST);
+ if (error != 0)
+ log_errx(1, "getaddrinfo: %s", gai_strerror(error));
+
+ log_debugx("accepted connection from %s; portal group \"%s\"",
+ host, portal->p_portal_group->pg_name);
+ log_set_peer_addr(host);
+ setproctitle("%s", host);
+#ifdef ICL_KERNEL_PROXY
+ }
#endif
conn = connection_new(portal, fd, host);
@@ -1650,7 +1648,6 @@ handle_connection(struct portal *portal, int fd, bool dont_fork)
exit(0);
}
-#ifndef ICL_KERNEL_PROXY
static int
fd_add(int fd, fd_set *fdset, int nfds)
{
@@ -1666,7 +1663,6 @@ fd_add(int fd, fd_set *fdset, int nfds)
nfds = fd;
return (nfds);
}
-#endif
static void
main_loop(struct conf *conf, bool dont_fork)
@@ -1675,10 +1671,9 @@ main_loop(struct conf *conf, bool dont_fork)
struct portal *portal;
#ifdef ICL_KERNEL_PROXY
int connection_id;
-#else
+#endif
fd_set fdset;
int error, nfds, client_fd;
-#endif
pidfile_write(conf->conf_pidfh);
@@ -1687,42 +1682,48 @@ main_loop(struct conf *conf, bool dont_fork)
return;
#ifdef ICL_KERNEL_PROXY
- connection_id = kernel_accept();
- if (connection_id == 0)
- continue;
+ if (proxy_mode) {
+ connection_id = kernel_accept();
+ if (connection_id == 0)
+ continue;
- /*
- * XXX: This is obviously temporary.
- */
- pg = TAILQ_FIRST(&conf->conf_portal_groups);
- portal = TAILQ_FIRST(&pg->pg_portals);
-
- handle_connection(portal, connection_id, dont_fork);
-#else
- FD_ZERO(&fdset);
- nfds = 0;
- TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) {
- TAILQ_FOREACH(portal, &pg->pg_portals, p_next)
- nfds = fd_add(portal->p_socket, &fdset, nfds);
- }
- error = select(nfds + 1, &fdset, NULL, NULL, NULL);
- if (error <= 0) {
- if (errno == EINTR)
- return;
- log_err(1, "select");
- }
- TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) {
- TAILQ_FOREACH(portal, &pg->pg_portals, p_next) {
- if (!FD_ISSET(portal->p_socket, &fdset))
- continue;
- client_fd = accept(portal->p_socket, NULL, 0);
- if (client_fd < 0)
- log_err(1, "accept");
- handle_connection(portal, client_fd, dont_fork);
- break;
+ /*
+ * XXX: This is obviously temporary.
+ */
+ pg = TAILQ_FIRST(&conf->conf_portal_groups);
+ portal = TAILQ_FIRST(&pg->pg_portals);
+
+ handle_connection(portal, connection_id, dont_fork);
+ } else {
+#endif
+ assert(proxy_mode == false);
+
+ FD_ZERO(&fdset);
+ nfds = 0;
+ TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) {
+ TAILQ_FOREACH(portal, &pg->pg_portals, p_next)
+ nfds = fd_add(portal->p_socket, &fdset, nfds);
+ }
+ error = select(nfds + 1, &fdset, NULL, NULL, NULL);
+ if (error <= 0) {
+ if (errno == EINTR)
+ return;
+ log_err(1, "select");
}
+ TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) {
+ TAILQ_FOREACH(portal, &pg->pg_portals, p_next) {
+ if (!FD_ISSET(portal->p_socket, &fdset))
+ continue;
+ client_fd = accept(portal->p_socket, NULL, 0);
+ if (client_fd < 0)
+ log_err(1, "accept");
+ handle_connection(portal, client_fd, dont_fork);
+ break;
+ }
+ }
+#ifdef ICL_KERNEL_PROXY
}
-#endif /* !ICL_KERNEL_PROXY */
+#endif
}
}
@@ -1788,7 +1789,7 @@ main(int argc, char **argv)
int debug = 0, ch, error;
bool dont_daemonize = false;
- while ((ch = getopt(argc, argv, "df:")) != -1) {
+ while ((ch = getopt(argc, argv, "df:R")) != -1) {
switch (ch) {
case 'd':
dont_daemonize = true;
@@ -1797,6 +1798,13 @@ main(int argc, char **argv)
case 'f':
config_path = optarg;
break;
+ case 'R':
+#ifndef ICL_KERNEL_PROXY
+ log_errx(1, "ctld(8) compiled without ICL_KERNEL_PROXY "
+ "does not support iSER protocol");
+#endif
+ proxy_mode = true;
+ break;
case '?':
default:
usage();
@@ -1818,12 +1826,10 @@ main(int argc, char **argv)
newconf->conf_debug = debug;
}
-#ifdef ICL_KERNEL_PROXY
log_debugx("enabling CTL iSCSI port");
error = kernel_port_on();
if (error != 0)
log_errx(1, "failed to enable CTL iSCSI port, exiting");
-#endif
error = conf_apply(oldconf, newconf);
if (error != 0)
@@ -1833,13 +1839,6 @@ main(int argc, char **argv)
register_signals();
-#ifndef ICL_KERNEL_PROXY
- log_debugx("enabling CTL iSCSI port");
- error = kernel_port_on();
- if (error != 0)
- log_errx(1, "failed to enable CTL iSCSI port, exiting");
-#endif
-
if (dont_daemonize == false) {
log_debugx("daemonizing");
if (daemon(0, 0) == -1) {
diff --git a/usr.sbin/ctld/kernel.c b/usr.sbin/ctld/kernel.c
index 4796a68..a0e68ba 100644
--- a/usr.sbin/ctld/kernel.c
+++ b/usr.sbin/ctld/kernel.c
@@ -65,11 +65,13 @@
#include <cam/ctl/ctl_util.h>
#include <cam/ctl/ctl_scsi_all.h>
+#include "ctld.h"
+
#ifdef ICL_KERNEL_PROXY
#include <netdb.h>
#endif
-#include "ctld.h"
+extern bool proxy_mode;
static int ctl_fd = 0;
@@ -599,7 +601,14 @@ kernel_handoff(struct connection *conn)
}
strlcpy(req.data.handoff.target_name,
conn->conn_target->t_name, sizeof(req.data.handoff.target_name));
+#ifdef ICL_KERNEL_PROXY
+ if (proxy_mode)
+ req.data.handoff.connection_id = conn->conn_socket;
+ else
+ req.data.handoff.socket = conn->conn_socket;
+#else
req.data.handoff.socket = conn->conn_socket;
+#endif
req.data.handoff.portal_group_tag =
conn->conn_portal->p_portal_group->pg_tag;
if (conn->conn_header_digest == CONN_DIGEST_CRC32C)
diff --git a/usr.sbin/ctld/pdu.c b/usr.sbin/ctld/pdu.c
index eb8921e..084423c 100644
--- a/usr.sbin/ctld/pdu.c
+++ b/usr.sbin/ctld/pdu.c
@@ -44,6 +44,8 @@
#include <sys/ioctl.h>
#endif
+extern bool proxy_mode;
+
static int
pdu_ahs_length(const struct pdu *pdu)
{
@@ -101,11 +103,13 @@ pdu_new_response(struct pdu *request)
#ifdef ICL_KERNEL_PROXY
-void
-pdu_receive(struct pdu *pdu)
+static void
+pdu_receive_proxy(struct pdu *pdu)
{
size_t len;
+ assert(proxy_mode);
+
kernel_receive(pdu);
len = pdu_ahs_length(pdu);
@@ -117,15 +121,17 @@ pdu_receive(struct pdu *pdu)
pdu->pdu_data_len = len;
}
-void
-pdu_send(struct pdu *pdu)
+static void
+pdu_send_proxy(struct pdu *pdu)
{
+ assert(proxy_mode);
+
pdu_set_data_segment_length(pdu, pdu->pdu_data_len);
kernel_send(pdu);
}
-#else /* !ICL_KERNEL_PROXY */
+#endif /* ICL_KERNEL_PROXY */
static size_t
pdu_padding(const struct pdu *pdu)
@@ -161,6 +167,13 @@ pdu_receive(struct pdu *pdu)
size_t len, padding;
char dummy[4];
+#ifdef ICL_KERNEL_PROXY
+ if (proxy_mode)
+ return (pdu_receive_proxy(pdu));
+#endif
+
+ assert(proxy_mode == false);
+
pdu_read(pdu->pdu_connection->conn_socket,
(char *)pdu->pdu_bhs, sizeof(*pdu->pdu_bhs));
@@ -202,6 +215,13 @@ pdu_send(struct pdu *pdu)
struct iovec iov[3];
int iovcnt;
+#ifdef ICL_KERNEL_PROXY
+ if (proxy_mode)
+ return (pdu_send_proxy(pdu));
+#endif
+
+ assert(proxy_mode == false);
+
pdu_set_data_segment_length(pdu, pdu->pdu_data_len);
iov[0].iov_base = pdu->pdu_bhs;
iov[0].iov_len = sizeof(*pdu->pdu_bhs);
@@ -234,8 +254,6 @@ pdu_send(struct pdu *pdu)
log_errx(1, "short write");
}
-#endif /* !ICL_KERNEL_PROXY */
-
void
pdu_delete(struct pdu *pdu)
{
OpenPOWER on IntegriCloud