Create thread per iSCSI target. Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp> Signed-off-by: Chandra Seetharaman <sekharan at us.ibm.com> --- usr/iscsi/iscsid.h | 7 ++++++ usr/iscsi/target.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 2 deletions(-) struct it_nexus { Index: tgt-1.0.8.4/usr/iscsi/iscsid.h =================================================================== --- tgt-1.0.8.4.orig/usr/iscsi/iscsid.h +++ tgt-1.0.8.4/usr/iscsi/iscsid.h @@ -251,6 +251,13 @@ struct iscsi_target { } redirect_info; struct list_head isns_list; + + int efd; + pthread_mutex_t event_lock; + struct list_head events_list; + + pthread_t thread; + int stop_pthread; }; enum task_flags { Index: tgt-1.0.8.4/usr/iscsi/target.c =================================================================== --- tgt-1.0.8.4.orig/usr/iscsi/target.c +++ tgt-1.0.8.4/usr/iscsi/target.c @@ -25,6 +25,7 @@ #include <unistd.h> #include <netdb.h> #include <sys/stat.h> +#include <sys/epoll.h> #include <sys/un.h> #include <netinet/in.h> #include <sys/socket.h> @@ -32,10 +33,12 @@ #include <netinet/tcp.h> #include <netinet/ip.h> #include <arpa/inet.h> +#include <pthread.h> #include "iscsid.h" #include "tgtadm.h" #include "tgtd.h" #include "target.h" +#include "util.h" LIST_HEAD(iscsi_targets_list); @@ -303,12 +306,53 @@ void iscsi_target_destroy(int tid) } list_del(&target->tlist); + + if (target->thread) { + target->stop_pthread = 1; + pthread_kill(target->thread, SIGUSR2); + + pthread_join(target->thread, NULL); + } + + close(target->efd); free(target); isns_target_deregister(tgt_targetname(tid)); return; } +static void *iscsi_thread_fn(void *arg) +{ + struct iscsi_target *t = arg; + struct epoll_event events[1024]; + struct event_data *tev; + sigset_t mask; + int nevent, i; + + sigemptyset(&mask); + sigaddset(&mask, SIGUSR2); + pthread_sigmask(SIG_BLOCK, &mask, NULL); + +retry: + nevent = epoll_wait(t->efd, events, ARRAY_SIZE(events), 1000); + if (nevent < 0) { + if (errno != EINTR) { + eprintf("%m\n"); + exit(1); + } + } else if (nevent) { + for (i = 0; i < nevent; i++) { + tev = (struct event_data *) events[i].data.ptr; + tev->handler(tev->fd, events[i].events, tev->data); + } + } + + if (!t->stop_pthread) + goto retry; + + pthread_exit(NULL); +} + int iscsi_target_create(struct target *t) { int tid = t->tid; @@ -339,11 +383,15 @@ int iscsi_target_create(struct target *t [ISCSI_PARAM_MAX_OUTST_PDU] = {0, 0}, /* not in open-iscsi */ }; - target = malloc(sizeof(*target)); + target = zalloc(sizeof(*target)); if (!target) return -ENOMEM; - memset(target, 0, sizeof(*target)); + target->efd = epoll_create(128); + if (target->efd < 0) { + free(target); + return -EINVAL; + } memcpy(target->session_param, default_tgt_session_param, sizeof(target->session_param)); @@ -351,10 +399,24 @@ int iscsi_target_create(struct target *t INIT_LIST_HEAD(&target->tlist); INIT_LIST_HEAD(&target->sessions_list); INIT_LIST_HEAD(&target->isns_list); + INIT_LIST_HEAD(&target->events_list); + pthread_mutex_init(&target->event_lock, NULL); target->tid = tid; list_add_tail(&target->tlist, &iscsi_targets_list); isns_target_register(tgt_targetname(tid)); + + if (iscsi_pthread_per_target()) { + int ret; + + ret = pthread_create(&target->thread, + NULL, iscsi_thread_fn, target); + + if (!ret) + eprintf("created thread %u for target %s\n", + (unsigned)target->thread, tgt_targetname(tid)); + } + return 0; } -- To unsubscribe from this list: send the line "unsubscribe stgt" in the body of a message to majordomo at vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html |