117680Spst/*	$NetBSD: ffs_wapbl.c,v 1.12 2009/02/22 20:28:06 ad Exp $	*/
217680Spst
317680Spst/*-
417680Spst * Copyright (c) 2004,2009 The NetBSD Foundation, Inc.
517680Spst * All rights reserved.
617680Spst *
717680Spst * This code is derived from software contributed to The NetBSD Foundation
817680Spst * by Wasabi Systems, Inc.
917680Spst *
1017680Spst * Redistribution and use in source and binary forms, with or without
1117680Spst * modification, are permitted provided that the following conditions
1217680Spst * are met:
1317680Spst * 1. Redistributions of source code must retain the above copyright
1417680Spst *    notice, this list of conditions and the following disclaimer.
1517680Spst * 2. Redistributions in binary form must reproduce the above copyright
1617680Spst *    notice, this list of conditions and the following disclaimer in the
1717680Spst *    documentation and/or other materials provided with the distribution.
1817680Spst *
1917680Spst * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2017680Spst * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2117680Spst * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2217680Spst * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2317680Spst * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2417680Spst * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2517680Spst * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2617680Spst * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2717680Spst * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2817680Spst * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2917680Spst * POSSIBILITY OF SUCH DAMAGE.
3017680Spst */
3117680Spst
3217680Spst#include <sys/cdefs.h>
3317680Spst__RCSID("$NetBSD: ffs_wapbl.c,v 1.12 2009/02/22 20:28:06 ad Exp $");
3417680Spst
3517680Spst/*
3617680Spst * isns.c
3717680Spst */
3817680Spst
3917680Spst#include <sys/types.h>
4017680Spst#include <sys/param.h>
4117680Spst#include <sys/uio.h>
4217680Spst#include <sys/poll.h>
4317680Spst
4417680Spst#include <errno.h>
4517680Spst#include <stdio.h>
4617680Spst#include <string.h>
4717680Spst#include <unistd.h>
4817680Spst
4917680Spst#include "isns.h"
5017680Spst#include "isns_config.h"
5117680Spst
5217680Spst
5317680Spst
5417680Spst/*
5517680Spst * isns_init()
5617680Spst */
5717680Spstint
5817680Spstisns_init(ISNS_HANDLE *isns_handle_p, int is_server)
5917680Spst{
6017680Spst	struct isns_config_s *cfg_p;
6117680Spst	int rval;
6217680Spst
6317680Spst	*isns_handle_p = NULL;
6417680Spst
6517680Spst	if ((cfg_p = isns_new_config()) == NULL) {
6617680Spst		DBG("isns_init: error on isns_new_config()\n");
6717680Spst		return ENOMEM;
6817680Spst	}
6917680Spst
7017680Spst	cfg_p->is_server = is_server;
7117680Spst	cfg_p->curtask_p = NULL;
7217680Spst
7317680Spst	if ((rval = pipe(cfg_p->pipe_fds)) != 0) {
7417680Spst		DBG("isns_init: error on wepe_sys_pipe()\n");
7517680Spst		isns_destroy_config(cfg_p);
7617680Spst		return rval;
7717680Spst	}
7817680Spst
7917680Spst	if ((cfg_p->kq = kqueue()) == -1) {
8017680Spst		DBG("isns_init: error on kqueue()\n");
8117680Spst		isns_destroy_config(cfg_p);
8217680Spst		return -1;
8317680Spst	}
8417680Spst
8517680Spst	rval = isns_change_kevent_list(cfg_p, (uintptr_t)cfg_p->pipe_fds[0],
8617680Spst	    EVFILT_READ, EV_ADD | EV_ENABLE, (int64_t)0,
8717680Spst	    (intptr_t)isns_kevent_pipe);
8817680Spst	if (rval == -1) {
8917680Spst		DBG("isns_init: error on isns_change_kevent_list() "
9017680Spst		    "for isns_kevent_pipe\n");
9117680Spst		isns_destroy_config(cfg_p);
9217680Spst		return rval;
9317680Spst	}
9417680Spst
9517680Spst	isns_init_buffer_pool();
9617680Spst	rval = isns_add_buffer_pool(ISNS_BUF_SIZE, ISNS_BUF_COUNT);
9717680Spst	if (rval != 0) {
9817680Spst		DBG("isns_init: error on isns_init_buffer_pool()\n");
9917680Spst		isns_destroy_config(cfg_p);
10017680Spst		return rval;
10117680Spst	}
10217680Spst	rval = isns_add_buffer_pool((int)ISNS_SMALL_BUF_SIZE, ISNS_SMALL_BUF_COUNT);
10317680Spst	if (rval != 0) {
10417680Spst		DBG("isns_init: error on isns_init_buffer_pool() [small]\n");
10517680Spst		isns_destroy_config(cfg_p);
10617680Spst		isns_destroy_buffer_pool();
10717680Spst		return rval;
10817680Spst	}
10917680Spst
11017680Spst	if ((rval = isns_thread_create(cfg_p)) != 0) {
11117680Spst		DBG("isns_init: error on isns_thread_create()\n");
11217680Spst		isns_destroy_config(cfg_p);
11317680Spst		isns_destroy_buffer_pool();
11417680Spst		return rval;
11517680Spst	}
11617680Spst
11717680Spst	*isns_handle_p = (ISNS_HANDLE)cfg_p;
11817680Spst
11917680Spst	return 0;
12017680Spst}
12117680Spst
12217680Spst
12317680Spst/*
12417680Spst * isns_add_servercon()
12517680Spst */
12617680Spstint
12717680Spstisns_add_servercon(ISNS_HANDLE isns_handle, int fd, struct addrinfo *ai)
12817680Spst{
12917680Spst	struct isns_config_s *cfg_p;
13017680Spst	struct isns_task_s *task_p;
13117680Spst	struct addrinfo *ai_p;
13217680Spst	size_t len;
13317680Spst
13417680Spst	if (isns_handle == ISNS_INVALID_HANDLE)
13517680Spst		return EINVAL;
13617680Spst
13717680Spst	cfg_p = (struct isns_config_s *)isns_handle;
13817680Spst
13917680Spst	ai_p = (struct addrinfo *)isns_malloc(sizeof(struct addrinfo));
14017680Spst	if (ai_p == NULL)
14117680Spst		return ENOMEM;
14217680Spst
14317680Spst	ai_p->ai_flags = ai->ai_flags;
14417680Spst	ai_p->ai_family = ai->ai_family;
14517680Spst	ai_p->ai_socktype = ai->ai_socktype;
14617680Spst	ai_p->ai_protocol = ai->ai_protocol;
14717680Spst	ai_p->ai_addrlen = ai->ai_addrlen;
14817680Spst	if (ai->ai_canonname != NULL) {
14917680Spst		len = strlen(ai->ai_canonname);
15017680Spst		ai_p->ai_canonname = (char *)isns_malloc(len + 1);
15117680Spst		if (ai_p->ai_canonname == NULL) {
15217680Spst			isns_free(ai_p);
15317680Spst			return ENOMEM;
15417680Spst		}
15517680Spst		memset(ai_p->ai_canonname, '\0', len + 1);
15617680Spst		strncpy(ai_p->ai_canonname, ai->ai_canonname, len);
15717680Spst	} else
15817680Spst		ai_p->ai_canonname = NULL;
15917680Spst	if (ai->ai_addr != NULL) {
16017680Spst		ai_p->ai_addr = (struct sockaddr *)isns_malloc(ai_p->
16117680Spst		    ai_addrlen);
16217680Spst		if (ai_p->ai_addr == NULL) {
16317680Spst			if (ai_p->ai_canonname != NULL)
16417680Spst				isns_free(ai_p->ai_canonname);
16517680Spst			isns_free(ai_p);
16617680Spst			return ENOMEM;
16717680Spst		}
16817680Spst		memcpy(ai_p->ai_addr, ai->ai_addr, ai_p->ai_addrlen);
16917680Spst	} else
17017680Spst		ai_p->ai_addr = NULL;
17117680Spst	ai_p->ai_next = NULL;
17217680Spst
17317680Spst	/* Build task and kick off task processing */
17417680Spst	task_p = isns_new_task(cfg_p, ISNS_TASK_INIT_SOCKET_IO, 1);
17517680Spst	task_p->var.init_socket_io.sd = fd;
17617680Spst	task_p->var.init_socket_io.ai_p = ai_p;
17717680Spst
17817680Spst	isns_taskq_insert_head(cfg_p, task_p);
17917680Spst	isns_issue_cmd(cfg_p, ISNS_CMD_PROCESS_TASKQ);
18017680Spst	isns_wait_task(task_p, NULL);
18117680Spst
18217680Spst	return 0;
18317680Spst}
18417680Spst
18517680Spst
18617680Spst/*
18717680Spst * isns_init_reg_refresh()
18817680Spst */
18917680Spstint
19017680Spstisns_init_reg_refresh(ISNS_HANDLE isns_handle, const char *node, int interval)
19117680Spst{
19217680Spst	struct isns_config_s *cfg_p;
19317680Spst	struct isns_task_s *task_p;
19417680Spst	struct isns_refresh_s *ref_p;
19517680Spst
19617680Spst	if (isns_handle == ISNS_INVALID_HANDLE)
19717680Spst		return EINVAL;
19817680Spst
19917680Spst	/* Build INIT_REFRESH task with info provided. */
20017680Spst	cfg_p = (struct isns_config_s *)isns_handle;
20117680Spst	task_p = isns_new_task(cfg_p, ISNS_TASK_INIT_REFRESH, 0);
20217680Spst	if (task_p == NULL)
20317680Spst		return ENOMEM;
20417680Spst
20517680Spst	ref_p = (struct isns_refresh_s *)
20617680Spst	    isns_malloc(sizeof(struct isns_refresh_s));
20717680Spst	if (ref_p == NULL) {
20817680Spst		isns_free_task(task_p);
20917680Spst		return ENOMEM;
21017680Spst	}
21117680Spst
21217680Spst	(void) snprintf(ref_p->node, sizeof(ref_p->node), "%.*s",
21317680Spst		(int)sizeof(ref_p->node)-1, node);
21417680Spst	ref_p->interval = interval;
21517680Spst	ref_p->trans_p = NULL;
21617680Spst	task_p->var.init_refresh.ref_p = ref_p;
21717680Spst
21817680Spst	isns_taskq_insert_tail(cfg_p, task_p);
21917680Spst	isns_issue_cmd(cfg_p, ISNS_CMD_PROCESS_TASKQ);
22017680Spst
22117680Spst	return 0;
22217680Spst}
22317680Spst
22417680Spst
22517680Spst/*
22617680Spst * isns_stop()
22717680Spst */
22817680Spstvoid isns_stop(ISNS_HANDLE isns_handle)
22917680Spst{
23017680Spst	struct isns_config_s *cfg_p = (struct isns_config_s *)isns_handle;
23117680Spst
23217680Spst	DBG("isns_stop: entered\n");
23317680Spst
23417680Spst	isns_issue_cmd(cfg_p, ISNS_CMD_STOP);
23517680Spst
23617680Spst	isns_thread_destroy(cfg_p);
23717680Spst	isns_destroy_config(cfg_p);
23817680Spst	isns_destroy_buffer_pool();
23917680Spst}
24017680Spst