fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
08dcd69c259e91563982b9e7715366f99fee816eJack Meng * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
33f5ff17089e3a43e6e730bf80384c233123dbd9Milan Jurik * Copyright 2012 Milan Jurik. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Local Defines
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * -------------
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define ISCSI_DISCOVERY_POLL_DELAY1 1 /* Seconds */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define ISCSI_DISCOVERY_POLL_DELAY2 60 /* Seconds */
aefdd1313598221872b3e520302b40e1874f2dc7bing zhao - Sun Microsystems - Beijing China#define ISCSI_SMF_OFFLINE_DELAY 10 /* Seconds */
aefdd1313598221872b3e520302b40e1874f2dc7bing zhao - Sun Microsystems - Beijing China#define ISCSI_SMF_OFFLINE_MAX_RETRY_TIMES 60
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Global Variables related to the synchronization of the child process
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * --------------------------------------------------------------------
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Global Variables related to the door accessed by the kernel
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * -----------------------------------------------------------
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Prototypes of Functions the body of which is defined farther down
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in this file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * -----------------------------------------------------------------
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * main -- Entry point of the iSCSI door server daemon
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function forks, waits for the child process feedback and exits.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get the locale set up before calling any other routines
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with messages to ouput.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte openlog("ISCSI_DOOR_DAEMON_SYSLOG_PP", LOG_PID, LOG_DAEMON);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The child semaphore is created. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The door for the child is created. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_child_door_handle = door_create(iscsi_child_door, NULL, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* A signal handler is set for SIGCHLD. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Here begins the daemonizing code
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * --------------------------------
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The fork failed. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_DAEMON | LOG_ERR, gettext("Cannot fork"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The parent exits after the child has provided feedback. This
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * waiting phase is to meet one of greenline's requirements.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We shouldn't return till we are sure the service is ready to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be provided.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stdout and stderr are redirected to "/dev/null".
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Here ends the daemonizing code
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ------------------------------
4246c8e92ef9ad6ada2b992b7af02832ff071bf7Jack Meng * Block out all signals
4246c8e92ef9ad6ada2b992b7af02832ff071bf7Jack Meng (void) pthread_sigmask(SIG_BLOCK, &allsigs, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* setup the door handle */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_kernel_door_handle = door_create(iscsi_kernel_door, NULL, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_DAEMON | LOG_ERR, gettext("door_create failed"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The iSCSI driver is opened.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_dev_handle = open(ISCSI_DRIVER_DEVCTL, O_RDWR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The driver couldn't be opened. */
4246c8e92ef9ad6ada2b992b7af02832ff071bf7Jack Meng * Keep the dev open, so to keep iscsi module from unloaded.
4246c8e92ef9ad6ada2b992b7af02832ff071bf7Jack Meng * This is crutial to guarantee the consistency of the
4246c8e92ef9ad6ada2b992b7af02832ff071bf7Jack Meng * door_handle and service state in kernel.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We have to wait for the discovery process to finish. */
4246c8e92ef9ad6ada2b992b7af02832ff071bf7Jack Meng /* We let the parent know that everything is ok. */
4246c8e92ef9ad6ada2b992b7af02832ff071bf7Jack Meng /* now set up signals we care about */
4246c8e92ef9ad6ada2b992b7af02832ff071bf7Jack Meng /* make sure signals to be enqueued */
4246c8e92ef9ad6ada2b992b7af02832ff071bf7Jack Meng /* wait and process signals */
aefdd1313598221872b3e520302b40e1874f2dc7bing zhao - Sun Microsystems - Beijing China ret = ioctl(iscsi_dev_handle,
aefdd1313598221872b3e520302b40e1874f2dc7bing zhao - Sun Microsystems - Beijing China if (ret == -1) {
aefdd1313598221872b3e520302b40e1874f2dc7bing zhao - Sun Microsystems - Beijing China * Keep retrying if unable
aefdd1313598221872b3e520302b40e1874f2dc7bing zhao - Sun Microsystems - Beijing China (void) sleep(ISCSI_SMF_OFFLINE_DELAY);
08dcd69c259e91563982b9e7715366f99fee816eJack Meng " service exited with sessions left."));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sigchld_handler -- SIGCHLD Handler
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This is the default code. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret_pid = waitpid(iscsi_child_pid, &status, WNOHANG);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_child_door -- Child process door entry point
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function is executed when a driver calls door_ki_upcall().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (alen >= sizeof (iscsi_child_smf_exit_code)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_kernel_door -- Kernel door entry point
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function is executed when a driver calls door_ki_upcall().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Local variables pre-initialization */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The validity of the request is checked before going any farther.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A request has to be passed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (alen < sizeof (iscsi_door_msg_hdr_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The buffer containing the request must be at least as big
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as message header.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (req->hdr.signature != ISCSI_DOOR_REQ_SIGNATURE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The request must be correctly signed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (req->hdr.version != ISCSI_DOOR_REQ_VERSION_1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The version of the request must be supported by the server.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The request is treated according to the opcode.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte err_code = door_return((char *)cnf, cnf_len, NULL, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr, "door_return error(%s,%d)", err_txt, err_code);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _getipnodebyname_req
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function executes the request ISCSI_DOOR_GETIPNODEBYNAME_REQ. It
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * calls getipnodebyname() but doesn't return all the information. The
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * confirmation structure only contains one IP address of the list returned
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by getipnodebyname().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getipnodebyname_cnf_t *cnf = (getipnodebyname_cnf_t *)req;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The opcode is changed immediately. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnf->hdr.opcode = ISCSI_DOOR_GETIPNODEBYNAME_CNF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The size of the request is checked against the minimum required. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The pointer to the name has to stay inside the request but
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * after the header.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((name < ((char *)req + sizeof (getipnodebyname_req_t))) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((name + req->name_length) > ((char *)req + req_len))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The library function is called. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The call was successful. Now starts the painful work of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * parsing the data. However, for version 1 we will only
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return the first address.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnf->h_size_needed = sizeof (getipnodebyname_cnf_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnf->h_addr_list_offset = sizeof (getipnodebyname_cnf_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnf->h_addr_list_offset = sizeof (getipnodebyname_cnf_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnf->h_name_offset = sizeof (getipnodebyname_cnf_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnf->h_alias_list_offset = sizeof (getipnodebyname_cnf_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnf->h_size_needed = sizeof (getipnodebyname_cnf_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * call_child_door -- This function calls the child door with the value
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * provided by the caller.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) door_call(iscsi_child_door_handle, &door_arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * get_luns_count --
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lun_list = (iscsi_lun_list_t *)malloc(sizeof (*lun_list));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The Ioctl didn't go well. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lun_list->ll_in_cnt >= lun_list->ll_out_cnt) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We got it all. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We didn't get all the targets. Let's build a new Ioctl with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a new size.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* No resources. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * discovery_event_wait -- Waits for the discovery process to finish.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The status discovery flags are read. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* IO problem */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Discovery over */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Let's check if the driver is making progress. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* No progress */