1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte */ 25*fcf3ce44SJohn Forte 26*fcf3ce44SJohn Forte #include <sys/types.h> 27*fcf3ce44SJohn Forte #include <sys/stat.h> 28*fcf3ce44SJohn Forte #include <sys/socket.h> 29*fcf3ce44SJohn Forte #include <locale.h> 30*fcf3ce44SJohn Forte #include <syslog.h> 31*fcf3ce44SJohn Forte #include <netdb.h> 32*fcf3ce44SJohn Forte #include <stdlib.h> 33*fcf3ce44SJohn Forte #include <string.h> 34*fcf3ce44SJohn Forte #include <fcntl.h> 35*fcf3ce44SJohn Forte #include <unistd.h> 36*fcf3ce44SJohn Forte #include <stdio.h> 37*fcf3ce44SJohn Forte #include <errno.h> 38*fcf3ce44SJohn Forte #include <door.h> 39*fcf3ce44SJohn Forte #include <meta.h> 40*fcf3ce44SJohn Forte #include <libsysevent.h> 41*fcf3ce44SJohn Forte #include <wait.h> 42*fcf3ce44SJohn Forte #include <semaphore.h> 43*fcf3ce44SJohn Forte #include <libscf.h> 44*fcf3ce44SJohn Forte 45*fcf3ce44SJohn Forte #include <sys/scsi/adapters/iscsi_door.h> 46*fcf3ce44SJohn Forte #include <sys/scsi/adapters/iscsi_if.h> 47*fcf3ce44SJohn Forte 48*fcf3ce44SJohn Forte /* 49*fcf3ce44SJohn Forte * Local Defines 50*fcf3ce44SJohn Forte * ------------- 51*fcf3ce44SJohn Forte */ 52*fcf3ce44SJohn Forte #define ISCSI_DOOR_DAEMON_SYSLOG_PP "iscsid" 53*fcf3ce44SJohn Forte #define ISCSI_DISCOVERY_POLL_DELAY1 1 /* Seconds */ 54*fcf3ce44SJohn Forte #define ISCSI_DISCOVERY_POLL_DELAY2 60 /* Seconds */ 55*fcf3ce44SJohn Forte 56*fcf3ce44SJohn Forte #if !defined(SMF_EXIT_ERR_OTHER) 57*fcf3ce44SJohn Forte #define SMF_EXIT_ERR_OTHER -1 58*fcf3ce44SJohn Forte #endif 59*fcf3ce44SJohn Forte 60*fcf3ce44SJohn Forte /* 61*fcf3ce44SJohn Forte * Global Variables related to the synchronization of the child process 62*fcf3ce44SJohn Forte * -------------------------------------------------------------------- 63*fcf3ce44SJohn Forte */ 64*fcf3ce44SJohn Forte static pid_t iscsi_child_pid; 65*fcf3ce44SJohn Forte static sem_t iscsi_child_sem; 66*fcf3ce44SJohn Forte static int iscsi_child_door_handle; 67*fcf3ce44SJohn Forte static int iscsi_child_smf_exit_code; 68*fcf3ce44SJohn Forte 69*fcf3ce44SJohn Forte /* 70*fcf3ce44SJohn Forte * Global Variables related to the door accessed by the kernel 71*fcf3ce44SJohn Forte * ----------------------------------------------------------- 72*fcf3ce44SJohn Forte */ 73*fcf3ce44SJohn Forte static int iscsi_dev_handle; 74*fcf3ce44SJohn Forte static int iscsi_kernel_door_handle; 75*fcf3ce44SJohn Forte 76*fcf3ce44SJohn Forte /* 77*fcf3ce44SJohn Forte * Prototypes of Functions the body of which is defined farther down 78*fcf3ce44SJohn Forte * in this file. 79*fcf3ce44SJohn Forte * ----------------------------------------------------------------- 80*fcf3ce44SJohn Forte */ 81*fcf3ce44SJohn Forte static void call_child_door(int value); 82*fcf3ce44SJohn Forte static void sigchld_handler(int sig); 83*fcf3ce44SJohn Forte static boolean_t discovery_event_wait(int did); 84*fcf3ce44SJohn Forte 85*fcf3ce44SJohn Forte static 86*fcf3ce44SJohn Forte void 87*fcf3ce44SJohn Forte iscsi_child_door( 88*fcf3ce44SJohn Forte void *cookie, 89*fcf3ce44SJohn Forte char *args, 90*fcf3ce44SJohn Forte size_t alen, 91*fcf3ce44SJohn Forte door_desc_t *ddp, 92*fcf3ce44SJohn Forte uint_t ndid 93*fcf3ce44SJohn Forte ); 94*fcf3ce44SJohn Forte 95*fcf3ce44SJohn Forte static 96*fcf3ce44SJohn Forte void 97*fcf3ce44SJohn Forte iscsi_kernel_door( 98*fcf3ce44SJohn Forte void *cookie, 99*fcf3ce44SJohn Forte char *args, 100*fcf3ce44SJohn Forte size_t alen, 101*fcf3ce44SJohn Forte door_desc_t *ddp, 102*fcf3ce44SJohn Forte uint_t ndid 103*fcf3ce44SJohn Forte ); 104*fcf3ce44SJohn Forte 105*fcf3ce44SJohn Forte static 106*fcf3ce44SJohn Forte iscsi_door_cnf_t * 107*fcf3ce44SJohn Forte _getipnodebyname_req( 108*fcf3ce44SJohn Forte getipnodebyname_req_t *req, 109*fcf3ce44SJohn Forte int req_len, 110*fcf3ce44SJohn Forte size_t *pcnf_len 111*fcf3ce44SJohn Forte ); 112*fcf3ce44SJohn Forte 113*fcf3ce44SJohn Forte /* 114*fcf3ce44SJohn Forte * main -- Entry point of the iSCSI door server daemon 115*fcf3ce44SJohn Forte * 116*fcf3ce44SJohn Forte * This function forks, waits for the child process feedback and exits. 117*fcf3ce44SJohn Forte */ 118*fcf3ce44SJohn Forte /* ARGSUSED */ 119*fcf3ce44SJohn Forte int 120*fcf3ce44SJohn Forte main( 121*fcf3ce44SJohn Forte int argc, 122*fcf3ce44SJohn Forte char *argv[] 123*fcf3ce44SJohn Forte ) 124*fcf3ce44SJohn Forte { 125*fcf3ce44SJohn Forte int i; 126*fcf3ce44SJohn Forte 127*fcf3ce44SJohn Forte /* 128*fcf3ce44SJohn Forte * Get the locale set up before calling any other routines 129*fcf3ce44SJohn Forte * with messages to ouput. 130*fcf3ce44SJohn Forte */ 131*fcf3ce44SJohn Forte (void) setlocale(LC_ALL, ""); 132*fcf3ce44SJohn Forte openlog("ISCSI_DOOR_DAEMON_SYSLOG_PP", LOG_PID, LOG_DAEMON); 133*fcf3ce44SJohn Forte 134*fcf3ce44SJohn Forte /* The child semaphore is created. */ 135*fcf3ce44SJohn Forte if (sem_init(&iscsi_child_sem, 0, 0) == -1) { 136*fcf3ce44SJohn Forte exit(SMF_EXIT_ERR_OTHER); 137*fcf3ce44SJohn Forte } 138*fcf3ce44SJohn Forte 139*fcf3ce44SJohn Forte /* The door for the child is created. */ 140*fcf3ce44SJohn Forte iscsi_child_door_handle = door_create(iscsi_child_door, NULL, 0); 141*fcf3ce44SJohn Forte if (iscsi_child_door_handle == -1) { 142*fcf3ce44SJohn Forte (void) sem_destroy(&iscsi_child_sem); 143*fcf3ce44SJohn Forte exit(SMF_EXIT_ERR_OTHER); 144*fcf3ce44SJohn Forte } 145*fcf3ce44SJohn Forte 146*fcf3ce44SJohn Forte /* A signal handler is set for SIGCHLD. */ 147*fcf3ce44SJohn Forte (void) signal(SIGCHLD, sigchld_handler); 148*fcf3ce44SJohn Forte 149*fcf3ce44SJohn Forte /* 150*fcf3ce44SJohn Forte * Here begins the daemonizing code 151*fcf3ce44SJohn Forte * -------------------------------- 152*fcf3ce44SJohn Forte */ 153*fcf3ce44SJohn Forte iscsi_child_pid = fork(); 154*fcf3ce44SJohn Forte if (iscsi_child_pid < 0) { 155*fcf3ce44SJohn Forte /* The fork failed. */ 156*fcf3ce44SJohn Forte syslog(LOG_DAEMON | LOG_ERR, gettext("Cannot fork")); 157*fcf3ce44SJohn Forte (void) sem_destroy(&iscsi_child_sem); 158*fcf3ce44SJohn Forte exit(SMF_EXIT_ERR_OTHER); 159*fcf3ce44SJohn Forte } 160*fcf3ce44SJohn Forte 161*fcf3ce44SJohn Forte if (iscsi_child_pid) { 162*fcf3ce44SJohn Forte /* 163*fcf3ce44SJohn Forte * The parent exits after the child has provided feedback. This 164*fcf3ce44SJohn Forte * waiting phase is to meet one of greenline's requirements. 165*fcf3ce44SJohn Forte * We shouldn't return till we are sure the service is ready to 166*fcf3ce44SJohn Forte * be provided. 167*fcf3ce44SJohn Forte */ 168*fcf3ce44SJohn Forte (void) sem_wait(&iscsi_child_sem); 169*fcf3ce44SJohn Forte (void) sem_destroy(&iscsi_child_sem); 170*fcf3ce44SJohn Forte exit(iscsi_child_smf_exit_code); 171*fcf3ce44SJohn Forte } 172*fcf3ce44SJohn Forte 173*fcf3ce44SJohn Forte /* 174*fcf3ce44SJohn Forte * stdout and stderr are redirected to "/dev/null". 175*fcf3ce44SJohn Forte */ 176*fcf3ce44SJohn Forte i = open("/dev/null", O_RDWR); 177*fcf3ce44SJohn Forte (void) dup2(i, 1); 178*fcf3ce44SJohn Forte (void) dup2(i, 2); 179*fcf3ce44SJohn Forte 180*fcf3ce44SJohn Forte /* 181*fcf3ce44SJohn Forte * Here ends the daemonizing code 182*fcf3ce44SJohn Forte * ------------------------------ 183*fcf3ce44SJohn Forte */ 184*fcf3ce44SJohn Forte 185*fcf3ce44SJohn Forte /* 186*fcf3ce44SJohn Forte * Block out the usual signals so we don't get killed unintentionally. 187*fcf3ce44SJohn Forte */ 188*fcf3ce44SJohn Forte (void) signal(SIGHUP, SIG_IGN); 189*fcf3ce44SJohn Forte (void) signal(SIGINT, SIG_IGN); 190*fcf3ce44SJohn Forte (void) signal(SIGQUIT, SIG_IGN); 191*fcf3ce44SJohn Forte 192*fcf3ce44SJohn Forte /* setup the door handle */ 193*fcf3ce44SJohn Forte iscsi_kernel_door_handle = door_create(iscsi_kernel_door, NULL, 0); 194*fcf3ce44SJohn Forte if (iscsi_kernel_door_handle == -1) { 195*fcf3ce44SJohn Forte perror(gettext("door_create failed")); 196*fcf3ce44SJohn Forte syslog(LOG_DAEMON | LOG_ERR, gettext("door_create failed")); 197*fcf3ce44SJohn Forte exit(SMF_EXIT_ERR_OTHER); 198*fcf3ce44SJohn Forte } 199*fcf3ce44SJohn Forte 200*fcf3ce44SJohn Forte /* 201*fcf3ce44SJohn Forte * The iSCSI driver is opened. 202*fcf3ce44SJohn Forte */ 203*fcf3ce44SJohn Forte iscsi_dev_handle = open(ISCSI_DRIVER_DEVCTL, O_RDWR); 204*fcf3ce44SJohn Forte if (iscsi_dev_handle == -1) { 205*fcf3ce44SJohn Forte /* The driver couldn't be opened. */ 206*fcf3ce44SJohn Forte perror(gettext("iscsi device open failed")); 207*fcf3ce44SJohn Forte exit(SMF_EXIT_ERR_OTHER); 208*fcf3ce44SJohn Forte } 209*fcf3ce44SJohn Forte 210*fcf3ce44SJohn Forte if (ioctl( 211*fcf3ce44SJohn Forte iscsi_dev_handle, 212*fcf3ce44SJohn Forte ISCSI_DOOR_HANDLE_SET, 213*fcf3ce44SJohn Forte &iscsi_kernel_door_handle) == -1) { 214*fcf3ce44SJohn Forte (void) close(iscsi_dev_handle); 215*fcf3ce44SJohn Forte perror(gettext("ioctl: set door handle")); 216*fcf3ce44SJohn Forte exit(SMF_EXIT_ERR_OTHER); 217*fcf3ce44SJohn Forte } 218*fcf3ce44SJohn Forte 219*fcf3ce44SJohn Forte /* We have to wait for the discovery process to finish. */ 220*fcf3ce44SJohn Forte (void) discovery_event_wait(iscsi_dev_handle); 221*fcf3ce44SJohn Forte 222*fcf3ce44SJohn Forte /* We don't need to keep the device opened. */ 223*fcf3ce44SJohn Forte (void) close(iscsi_dev_handle); 224*fcf3ce44SJohn Forte 225*fcf3ce44SJohn Forte /* We let know the parent that everything is ok. */ 226*fcf3ce44SJohn Forte call_child_door(SMF_EXIT_OK); 227*fcf3ce44SJohn Forte for (;;) { 228*fcf3ce44SJohn Forte (void) pause(); 229*fcf3ce44SJohn Forte } 230*fcf3ce44SJohn Forte } 231*fcf3ce44SJohn Forte 232*fcf3ce44SJohn Forte /* 233*fcf3ce44SJohn Forte * sigchld_handler -- SIGCHLD Handler 234*fcf3ce44SJohn Forte * 235*fcf3ce44SJohn Forte */ 236*fcf3ce44SJohn Forte /* ARGSUSED */ 237*fcf3ce44SJohn Forte static 238*fcf3ce44SJohn Forte void 239*fcf3ce44SJohn Forte sigchld_handler( 240*fcf3ce44SJohn Forte int sig 241*fcf3ce44SJohn Forte ) 242*fcf3ce44SJohn Forte { 243*fcf3ce44SJohn Forte int status; 244*fcf3ce44SJohn Forte pid_t ret_pid; 245*fcf3ce44SJohn Forte 246*fcf3ce44SJohn Forte /* This is the default code. */ 247*fcf3ce44SJohn Forte iscsi_child_smf_exit_code = SMF_EXIT_ERR_OTHER; 248*fcf3ce44SJohn Forte 249*fcf3ce44SJohn Forte ret_pid = waitpid(iscsi_child_pid, &status, WNOHANG); 250*fcf3ce44SJohn Forte 251*fcf3ce44SJohn Forte if (ret_pid == iscsi_child_pid) { 252*fcf3ce44SJohn Forte if (WIFEXITED(status)) { 253*fcf3ce44SJohn Forte iscsi_child_smf_exit_code = WEXITSTATUS(status); 254*fcf3ce44SJohn Forte } 255*fcf3ce44SJohn Forte } 256*fcf3ce44SJohn Forte (void) sem_post(&iscsi_child_sem); 257*fcf3ce44SJohn Forte } 258*fcf3ce44SJohn Forte 259*fcf3ce44SJohn Forte /* 260*fcf3ce44SJohn Forte * iscsi_child_door -- Child process door entry point 261*fcf3ce44SJohn Forte * 262*fcf3ce44SJohn Forte * This function is executed when a driver calls door_ki_upcall(). 263*fcf3ce44SJohn Forte */ 264*fcf3ce44SJohn Forte /* ARGSUSED */ 265*fcf3ce44SJohn Forte static 266*fcf3ce44SJohn Forte void 267*fcf3ce44SJohn Forte iscsi_child_door( 268*fcf3ce44SJohn Forte void *cookie, 269*fcf3ce44SJohn Forte char *args, 270*fcf3ce44SJohn Forte size_t alen, 271*fcf3ce44SJohn Forte door_desc_t *ddp, 272*fcf3ce44SJohn Forte uint_t ndid 273*fcf3ce44SJohn Forte ) 274*fcf3ce44SJohn Forte { 275*fcf3ce44SJohn Forte int *ptr = (int *)args; 276*fcf3ce44SJohn Forte 277*fcf3ce44SJohn Forte iscsi_child_smf_exit_code = SMF_EXIT_ERR_OTHER; 278*fcf3ce44SJohn Forte 279*fcf3ce44SJohn Forte if (alen >= sizeof (iscsi_child_smf_exit_code)) { 280*fcf3ce44SJohn Forte iscsi_child_smf_exit_code = *ptr; 281*fcf3ce44SJohn Forte } 282*fcf3ce44SJohn Forte (void) sem_post(&iscsi_child_sem); 283*fcf3ce44SJohn Forte (void) door_return(NULL, 0, NULL, 0); 284*fcf3ce44SJohn Forte } 285*fcf3ce44SJohn Forte 286*fcf3ce44SJohn Forte /* 287*fcf3ce44SJohn Forte * iscsi_kernel_door -- Kernel door entry point 288*fcf3ce44SJohn Forte * 289*fcf3ce44SJohn Forte * This function is executed when a driver calls door_ki_upcall(). 290*fcf3ce44SJohn Forte */ 291*fcf3ce44SJohn Forte /* ARGSUSED */ 292*fcf3ce44SJohn Forte static 293*fcf3ce44SJohn Forte void 294*fcf3ce44SJohn Forte iscsi_kernel_door( 295*fcf3ce44SJohn Forte void *cookie, 296*fcf3ce44SJohn Forte char *args, 297*fcf3ce44SJohn Forte size_t alen, 298*fcf3ce44SJohn Forte door_desc_t *ddp, 299*fcf3ce44SJohn Forte uint_t ndid 300*fcf3ce44SJohn Forte ) 301*fcf3ce44SJohn Forte { 302*fcf3ce44SJohn Forte iscsi_door_msg_hdr_t err_ind; 303*fcf3ce44SJohn Forte iscsi_door_req_t *req; 304*fcf3ce44SJohn Forte iscsi_door_cnf_t *cnf; 305*fcf3ce44SJohn Forte size_t cnf_len; 306*fcf3ce44SJohn Forte char *err_txt; 307*fcf3ce44SJohn Forte int err_code; 308*fcf3ce44SJohn Forte 309*fcf3ce44SJohn Forte /* Local variables pre-initialization */ 310*fcf3ce44SJohn Forte err_ind.signature = ISCSI_DOOR_REQ_SIGNATURE; 311*fcf3ce44SJohn Forte err_ind.version = ISCSI_DOOR_REQ_VERSION_1; 312*fcf3ce44SJohn Forte err_ind.opcode = ISCSI_DOOR_ERROR_IND; 313*fcf3ce44SJohn Forte 314*fcf3ce44SJohn Forte req = (iscsi_door_req_t *)args; 315*fcf3ce44SJohn Forte cnf = (iscsi_door_cnf_t *)&err_ind; 316*fcf3ce44SJohn Forte cnf_len = sizeof (err_ind); 317*fcf3ce44SJohn Forte 318*fcf3ce44SJohn Forte /* 319*fcf3ce44SJohn Forte * The validity of the request is checked before going any farther. 320*fcf3ce44SJohn Forte */ 321*fcf3ce44SJohn Forte if (req == NULL) { 322*fcf3ce44SJohn Forte /* 323*fcf3ce44SJohn Forte * A request has to be passed. 324*fcf3ce44SJohn Forte */ 325*fcf3ce44SJohn Forte err_ind.status = ISCSI_DOOR_STATUS_REQ_INVALID; 326*fcf3ce44SJohn Forte } else if (alen < sizeof (iscsi_door_msg_hdr_t)) { 327*fcf3ce44SJohn Forte /* 328*fcf3ce44SJohn Forte * The buffer containing the request must be at least as big 329*fcf3ce44SJohn Forte * as message header. 330*fcf3ce44SJohn Forte */ 331*fcf3ce44SJohn Forte err_ind.status = ISCSI_DOOR_STATUS_REQ_LENGTH; 332*fcf3ce44SJohn Forte } else if (req->hdr.signature != ISCSI_DOOR_REQ_SIGNATURE) { 333*fcf3ce44SJohn Forte /* 334*fcf3ce44SJohn Forte * The request must be correctly signed. 335*fcf3ce44SJohn Forte */ 336*fcf3ce44SJohn Forte err_ind.status = ISCSI_DOOR_STATUS_REQ_INVALID; 337*fcf3ce44SJohn Forte } else if (req->hdr.version != ISCSI_DOOR_REQ_VERSION_1) { 338*fcf3ce44SJohn Forte /* 339*fcf3ce44SJohn Forte * The version of the request must be supported by the server. 340*fcf3ce44SJohn Forte */ 341*fcf3ce44SJohn Forte err_ind.status = ISCSI_DOOR_STATUS_REQ_VERSION; 342*fcf3ce44SJohn Forte } else { 343*fcf3ce44SJohn Forte /* 344*fcf3ce44SJohn Forte * The request is treated according to the opcode. 345*fcf3ce44SJohn Forte */ 346*fcf3ce44SJohn Forte switch (req->hdr.opcode) { 347*fcf3ce44SJohn Forte 348*fcf3ce44SJohn Forte case ISCSI_DOOR_GETIPNODEBYNAME_REQ: 349*fcf3ce44SJohn Forte cnf = _getipnodebyname_req( 350*fcf3ce44SJohn Forte &req->ginbn_req, 351*fcf3ce44SJohn Forte alen, 352*fcf3ce44SJohn Forte &cnf_len); 353*fcf3ce44SJohn Forte break; 354*fcf3ce44SJohn Forte default: 355*fcf3ce44SJohn Forte err_ind.status = ISCSI_DOOR_STATUS_REQ_INVALID; 356*fcf3ce44SJohn Forte break; 357*fcf3ce44SJohn Forte } 358*fcf3ce44SJohn Forte } 359*fcf3ce44SJohn Forte err_code = door_return((char *)cnf, cnf_len, NULL, 0); 360*fcf3ce44SJohn Forte 361*fcf3ce44SJohn Forte switch (err_code) { 362*fcf3ce44SJohn Forte case E2BIG: 363*fcf3ce44SJohn Forte err_txt = "E2BIG"; 364*fcf3ce44SJohn Forte break; 365*fcf3ce44SJohn Forte case EFAULT: 366*fcf3ce44SJohn Forte err_txt = "EFAULT"; 367*fcf3ce44SJohn Forte break; 368*fcf3ce44SJohn Forte case EINVAL: 369*fcf3ce44SJohn Forte err_txt = "EINVAL"; 370*fcf3ce44SJohn Forte break; 371*fcf3ce44SJohn Forte case EMFILE: 372*fcf3ce44SJohn Forte err_txt = "EMFILE"; 373*fcf3ce44SJohn Forte break; 374*fcf3ce44SJohn Forte default: 375*fcf3ce44SJohn Forte err_txt = "?"; 376*fcf3ce44SJohn Forte break; 377*fcf3ce44SJohn Forte } 378*fcf3ce44SJohn Forte (void) fprintf(stderr, "door_return error(%s,%d)", err_txt, err_code); 379*fcf3ce44SJohn Forte syslog( 380*fcf3ce44SJohn Forte LOG_DAEMON | LOG_ERR, 381*fcf3ce44SJohn Forte gettext("!door_return error(%s,%d)"), 382*fcf3ce44SJohn Forte err_txt, 383*fcf3ce44SJohn Forte err_code); 384*fcf3ce44SJohn Forte } 385*fcf3ce44SJohn Forte 386*fcf3ce44SJohn Forte /* 387*fcf3ce44SJohn Forte * _getipnodebyname_req 388*fcf3ce44SJohn Forte * 389*fcf3ce44SJohn Forte * This function executes the request ISCSI_DOOR_GETIPNODEBYNAME_REQ. It 390*fcf3ce44SJohn Forte * calls getipnodebyname() but doesn't return all the information. The 391*fcf3ce44SJohn Forte * confirmation structure only contains one IP address of the list returned 392*fcf3ce44SJohn Forte * by getipnodebyname(). 393*fcf3ce44SJohn Forte */ 394*fcf3ce44SJohn Forte static 395*fcf3ce44SJohn Forte iscsi_door_cnf_t * 396*fcf3ce44SJohn Forte _getipnodebyname_req( 397*fcf3ce44SJohn Forte getipnodebyname_req_t *req, 398*fcf3ce44SJohn Forte int req_len, 399*fcf3ce44SJohn Forte size_t *pcnf_len 400*fcf3ce44SJohn Forte ) { 401*fcf3ce44SJohn Forte getipnodebyname_cnf_t *cnf = (getipnodebyname_cnf_t *)req; 402*fcf3ce44SJohn Forte size_t cnf_len; 403*fcf3ce44SJohn Forte struct hostent *hptr; 404*fcf3ce44SJohn Forte char *name; 405*fcf3ce44SJohn Forte 406*fcf3ce44SJohn Forte /* The opcode is changed immediately. */ 407*fcf3ce44SJohn Forte cnf->hdr.opcode = ISCSI_DOOR_GETIPNODEBYNAME_CNF; 408*fcf3ce44SJohn Forte 409*fcf3ce44SJohn Forte /* The size of the request is checked against the minimum required. */ 410*fcf3ce44SJohn Forte if (req_len < sizeof (getipnodebyname_cnf_t)) { 411*fcf3ce44SJohn Forte cnf->hdr.status = ISCSI_DOOR_STATUS_REQ_FORMAT; 412*fcf3ce44SJohn Forte *pcnf_len = req_len; 413*fcf3ce44SJohn Forte return ((iscsi_door_cnf_t *)cnf); 414*fcf3ce44SJohn Forte } 415*fcf3ce44SJohn Forte 416*fcf3ce44SJohn Forte name = (char *)req + req->name_offset; 417*fcf3ce44SJohn Forte 418*fcf3ce44SJohn Forte /* 419*fcf3ce44SJohn Forte * The pointer to the name has to stay inside the request but 420*fcf3ce44SJohn Forte * after the header. 421*fcf3ce44SJohn Forte */ 422*fcf3ce44SJohn Forte if ((name < ((char *)req + sizeof (getipnodebyname_req_t))) || 423*fcf3ce44SJohn Forte ((name + req->name_length) > ((char *)req + req_len))) { 424*fcf3ce44SJohn Forte cnf->hdr.status = ISCSI_DOOR_STATUS_REQ_FORMAT; 425*fcf3ce44SJohn Forte *pcnf_len = req_len; 426*fcf3ce44SJohn Forte return ((iscsi_door_cnf_t *)cnf); 427*fcf3ce44SJohn Forte } 428*fcf3ce44SJohn Forte 429*fcf3ce44SJohn Forte /* The library function is called. */ 430*fcf3ce44SJohn Forte hptr = getipnodebyname( 431*fcf3ce44SJohn Forte name, 432*fcf3ce44SJohn Forte (int)req->af, 433*fcf3ce44SJohn Forte (int)req->flags, 434*fcf3ce44SJohn Forte (int *)&cnf->error_num); 435*fcf3ce44SJohn Forte 436*fcf3ce44SJohn Forte if (hptr) { 437*fcf3ce44SJohn Forte /* 438*fcf3ce44SJohn Forte * The call was successful. Now starts the painful work of 439*fcf3ce44SJohn Forte * parsing the data. However, for version 1 we will only 440*fcf3ce44SJohn Forte * return the first address. 441*fcf3ce44SJohn Forte */ 442*fcf3ce44SJohn Forte cnf_len = sizeof (getipnodebyname_cnf_t); 443*fcf3ce44SJohn Forte cnf->h_size_needed = sizeof (getipnodebyname_cnf_t); 444*fcf3ce44SJohn Forte cnf->h_alias_list_length = 0; 445*fcf3ce44SJohn Forte cnf->h_alias_list_offset = 0; 446*fcf3ce44SJohn Forte cnf->h_name_len = 0; 447*fcf3ce44SJohn Forte cnf->h_name_offset = 0; 448*fcf3ce44SJohn Forte 449*fcf3ce44SJohn Forte cnf->h_addrlen = (uint32_t)hptr->h_length; 450*fcf3ce44SJohn Forte cnf->h_addrtype = (uint32_t)hptr->h_addrtype; 451*fcf3ce44SJohn Forte cnf->h_addr_list_offset = sizeof (getipnodebyname_cnf_t); 452*fcf3ce44SJohn Forte 453*fcf3ce44SJohn Forte if (*hptr->h_addr_list != NULL) { 454*fcf3ce44SJohn Forte (void) memcpy( 455*fcf3ce44SJohn Forte ((char *)cnf + sizeof (getipnodebyname_cnf_t)), 456*fcf3ce44SJohn Forte *hptr->h_addr_list, 457*fcf3ce44SJohn Forte hptr->h_length); 458*fcf3ce44SJohn Forte cnf->h_addr_list_length = 1; 459*fcf3ce44SJohn Forte cnf->h_size_needed += cnf->h_addrlen; 460*fcf3ce44SJohn Forte cnf_len += hptr->h_length; 461*fcf3ce44SJohn Forte } else { 462*fcf3ce44SJohn Forte cnf->h_addr_list_length = 0; 463*fcf3ce44SJohn Forte cnf->h_size_needed += hptr->h_length; 464*fcf3ce44SJohn Forte } 465*fcf3ce44SJohn Forte *pcnf_len = cnf_len; 466*fcf3ce44SJohn Forte cnf->hdr.status = ISCSI_DOOR_STATUS_SUCCESS; 467*fcf3ce44SJohn Forte freehostent(hptr); 468*fcf3ce44SJohn Forte } else { 469*fcf3ce44SJohn Forte cnf->hdr.status = ISCSI_DOOR_STATUS_SUCCESS; 470*fcf3ce44SJohn Forte cnf->h_addrlen = 0; 471*fcf3ce44SJohn Forte cnf->h_addrtype = 0; 472*fcf3ce44SJohn Forte cnf->h_addr_list_offset = sizeof (getipnodebyname_cnf_t); 473*fcf3ce44SJohn Forte cnf->h_addr_list_length = 0; 474*fcf3ce44SJohn Forte cnf->h_name_offset = sizeof (getipnodebyname_cnf_t); 475*fcf3ce44SJohn Forte cnf->h_name_len = 0; 476*fcf3ce44SJohn Forte cnf->h_alias_list_offset = sizeof (getipnodebyname_cnf_t); 477*fcf3ce44SJohn Forte cnf->h_alias_list_length = 0; 478*fcf3ce44SJohn Forte cnf->h_size_needed = sizeof (getipnodebyname_cnf_t); 479*fcf3ce44SJohn Forte *pcnf_len = sizeof (getipnodebyname_cnf_t); 480*fcf3ce44SJohn Forte } 481*fcf3ce44SJohn Forte return ((iscsi_door_cnf_t *)cnf); 482*fcf3ce44SJohn Forte } 483*fcf3ce44SJohn Forte 484*fcf3ce44SJohn Forte /* 485*fcf3ce44SJohn Forte * call_child_door -- This function calls the child door with the value 486*fcf3ce44SJohn Forte * provided by the caller. 487*fcf3ce44SJohn Forte * 488*fcf3ce44SJohn Forte */ 489*fcf3ce44SJohn Forte static 490*fcf3ce44SJohn Forte void 491*fcf3ce44SJohn Forte call_child_door( 492*fcf3ce44SJohn Forte int value 493*fcf3ce44SJohn Forte ) 494*fcf3ce44SJohn Forte { 495*fcf3ce44SJohn Forte door_arg_t door_arg; 496*fcf3ce44SJohn Forte 497*fcf3ce44SJohn Forte (void) memset(&door_arg, 0, sizeof (door_arg)); 498*fcf3ce44SJohn Forte door_arg.data_ptr = (char *)&value; 499*fcf3ce44SJohn Forte door_arg.data_size = sizeof (value); 500*fcf3ce44SJohn Forte (void) door_call(iscsi_child_door_handle, &door_arg); 501*fcf3ce44SJohn Forte } 502*fcf3ce44SJohn Forte 503*fcf3ce44SJohn Forte /* 504*fcf3ce44SJohn Forte * get_luns_count -- 505*fcf3ce44SJohn Forte */ 506*fcf3ce44SJohn Forte static 507*fcf3ce44SJohn Forte uint32_t 508*fcf3ce44SJohn Forte get_luns_count( 509*fcf3ce44SJohn Forte int did 510*fcf3ce44SJohn Forte ) 511*fcf3ce44SJohn Forte { 512*fcf3ce44SJohn Forte iscsi_lun_list_t *lun_list; 513*fcf3ce44SJohn Forte iscsi_lun_list_t *tmp; 514*fcf3ce44SJohn Forte size_t len; 515*fcf3ce44SJohn Forte uint32_t lun_count; 516*fcf3ce44SJohn Forte 517*fcf3ce44SJohn Forte lun_list = (iscsi_lun_list_t *)malloc(sizeof (*lun_list)); 518*fcf3ce44SJohn Forte 519*fcf3ce44SJohn Forte (void) memset(lun_list, 0, sizeof (*lun_list)); 520*fcf3ce44SJohn Forte lun_list->ll_vers = ISCSI_INTERFACE_VERSION; 521*fcf3ce44SJohn Forte lun_list->ll_in_cnt = 1; 522*fcf3ce44SJohn Forte lun_list->ll_all_tgts = B_TRUE; 523*fcf3ce44SJohn Forte 524*fcf3ce44SJohn Forte for (;;) { 525*fcf3ce44SJohn Forte 526*fcf3ce44SJohn Forte if (ioctl( 527*fcf3ce44SJohn Forte did, 528*fcf3ce44SJohn Forte ISCSI_LUN_OID_LIST_GET, 529*fcf3ce44SJohn Forte lun_list) == -1) { 530*fcf3ce44SJohn Forte free(lun_list); 531*fcf3ce44SJohn Forte /* The Ioctl didn't go well. */ 532*fcf3ce44SJohn Forte return (0); 533*fcf3ce44SJohn Forte } 534*fcf3ce44SJohn Forte if (lun_list->ll_in_cnt >= lun_list->ll_out_cnt) { 535*fcf3ce44SJohn Forte /* We got it all. */ 536*fcf3ce44SJohn Forte break; 537*fcf3ce44SJohn Forte } 538*fcf3ce44SJohn Forte /* 539*fcf3ce44SJohn Forte * We didn't get all the targets. Let's build a new Ioctl with 540*fcf3ce44SJohn Forte * a new size. 541*fcf3ce44SJohn Forte */ 542*fcf3ce44SJohn Forte tmp = lun_list; 543*fcf3ce44SJohn Forte len = tmp->ll_out_cnt * sizeof (tmp->ll_luns); 544*fcf3ce44SJohn Forte len += sizeof (*tmp) - sizeof (tmp->ll_luns); 545*fcf3ce44SJohn Forte lun_list = (iscsi_lun_list_t *)malloc(len); 546*fcf3ce44SJohn Forte if (lun_list == NULL) { 547*fcf3ce44SJohn Forte /* No resources. */ 548*fcf3ce44SJohn Forte free(tmp); 549*fcf3ce44SJohn Forte return (0); 550*fcf3ce44SJohn Forte } 551*fcf3ce44SJohn Forte (void) memset(lun_list, 0, len); 552*fcf3ce44SJohn Forte lun_list->ll_vers = ISCSI_INTERFACE_VERSION; 553*fcf3ce44SJohn Forte lun_list->ll_in_cnt = tmp->ll_out_cnt; 554*fcf3ce44SJohn Forte lun_list->ll_all_tgts = B_TRUE; 555*fcf3ce44SJohn Forte free(tmp); 556*fcf3ce44SJohn Forte } 557*fcf3ce44SJohn Forte lun_count = lun_list->ll_out_cnt; 558*fcf3ce44SJohn Forte free(lun_list); 559*fcf3ce44SJohn Forte return (lun_count); 560*fcf3ce44SJohn Forte } 561*fcf3ce44SJohn Forte 562*fcf3ce44SJohn Forte /* 563*fcf3ce44SJohn Forte * discovery_event_wait -- Waits for the discovery process to finish. 564*fcf3ce44SJohn Forte * 565*fcf3ce44SJohn Forte */ 566*fcf3ce44SJohn Forte static 567*fcf3ce44SJohn Forte boolean_t 568*fcf3ce44SJohn Forte discovery_event_wait( 569*fcf3ce44SJohn Forte int did 570*fcf3ce44SJohn Forte ) 571*fcf3ce44SJohn Forte { 572*fcf3ce44SJohn Forte boolean_t rc; 573*fcf3ce44SJohn Forte uint32_t lun_count; 574*fcf3ce44SJohn Forte uint32_t lun_timer; 575*fcf3ce44SJohn Forte uint32_t tmp; 576*fcf3ce44SJohn Forte iSCSIDiscoveryMethod_t discovery_flags; 577*fcf3ce44SJohn Forte iSCSIDiscoveryMethod_t discovery_all; 578*fcf3ce44SJohn Forte 579*fcf3ce44SJohn Forte rc = B_FALSE; 580*fcf3ce44SJohn Forte lun_count = 0; 581*fcf3ce44SJohn Forte lun_timer = 0; 582*fcf3ce44SJohn Forte discovery_flags = 0; 583*fcf3ce44SJohn Forte discovery_all = iSCSIDiscoveryMethodStatic | 584*fcf3ce44SJohn Forte iSCSIDiscoveryMethodSLP | 585*fcf3ce44SJohn Forte iSCSIDiscoveryMethodISNS | 586*fcf3ce44SJohn Forte iSCSIDiscoveryMethodSendTargets; 587*fcf3ce44SJohn Forte 588*fcf3ce44SJohn Forte for (;;) { 589*fcf3ce44SJohn Forte 590*fcf3ce44SJohn Forte /* The status discovery flags are read. */ 591*fcf3ce44SJohn Forte if (ioctl( 592*fcf3ce44SJohn Forte did, 593*fcf3ce44SJohn Forte ISCSI_DISCOVERY_EVENTS, 594*fcf3ce44SJohn Forte &discovery_flags) == -1) { 595*fcf3ce44SJohn Forte /* IO problem */ 596*fcf3ce44SJohn Forte break; 597*fcf3ce44SJohn Forte } 598*fcf3ce44SJohn Forte 599*fcf3ce44SJohn Forte if (discovery_flags == discovery_all) { 600*fcf3ce44SJohn Forte /* Discovery over */ 601*fcf3ce44SJohn Forte rc = B_TRUE; 602*fcf3ce44SJohn Forte break; 603*fcf3ce44SJohn Forte } 604*fcf3ce44SJohn Forte 605*fcf3ce44SJohn Forte if (lun_timer >= ISCSI_DISCOVERY_POLL_DELAY2) { 606*fcf3ce44SJohn Forte /* Let's check if the driver is making progress. */ 607*fcf3ce44SJohn Forte tmp = get_luns_count(did); 608*fcf3ce44SJohn Forte if (tmp <= lun_count) { 609*fcf3ce44SJohn Forte /* No progress */ 610*fcf3ce44SJohn Forte break; 611*fcf3ce44SJohn Forte } 612*fcf3ce44SJohn Forte lun_count = tmp; 613*fcf3ce44SJohn Forte lun_timer = 0; 614*fcf3ce44SJohn Forte } 615*fcf3ce44SJohn Forte (void) sleep(ISCSI_DISCOVERY_POLL_DELAY1); 616*fcf3ce44SJohn Forte lun_timer += ISCSI_DISCOVERY_POLL_DELAY1; 617*fcf3ce44SJohn Forte } 618*fcf3ce44SJohn Forte return (rc); 619*fcf3ce44SJohn Forte } 620