10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7888Sandrew.rutz@sun.com * Common Development and Distribution License (the "License"). 6*7888Sandrew.rutz@sun.com * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*7888Sandrew.rutz@sun.com * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate /* 270Sstevel@tonic-gate * l_misc.c : 280Sstevel@tonic-gate * This file contains the miscelleneous routines for libsm.so 290Sstevel@tonic-gate */ 300Sstevel@tonic-gate 310Sstevel@tonic-gate #include <sys/types.h> 320Sstevel@tonic-gate #include <sys/stat.h> 330Sstevel@tonic-gate #include <sys/utsname.h> 340Sstevel@tonic-gate #include <fcntl.h> 350Sstevel@tonic-gate #include <sys/dkio.h> 360Sstevel@tonic-gate #include <sys/vtoc.h> 370Sstevel@tonic-gate #include <sys/dktp/fdisk.h> 380Sstevel@tonic-gate #include <dirent.h> 390Sstevel@tonic-gate #include <dlfcn.h> 400Sstevel@tonic-gate #include <stdlib.h> 410Sstevel@tonic-gate #include <sys/stat.h> 420Sstevel@tonic-gate #include <strings.h> 430Sstevel@tonic-gate #include "l_defines.h" 440Sstevel@tonic-gate #include <rpc/rpc.h> 450Sstevel@tonic-gate #include "smed.h" 460Sstevel@tonic-gate #include <sys/smedia.h> 470Sstevel@tonic-gate #include "../inc/rmedia.h" 480Sstevel@tonic-gate #include <smserver.h> 490Sstevel@tonic-gate #include <sys/mman.h> 500Sstevel@tonic-gate #include <utmpx.h> 510Sstevel@tonic-gate #include <limits.h> 520Sstevel@tonic-gate 530Sstevel@tonic-gate #ifdef _LP64 540Sstevel@tonic-gate #ifdef __sparc 550Sstevel@tonic-gate #define PATHNAME "/usr/lib/smedia/sparcv9" 560Sstevel@tonic-gate #else 570Sstevel@tonic-gate #define PATHNAME "/usr/lib/smedia/amd64" 580Sstevel@tonic-gate #endif 590Sstevel@tonic-gate #else 600Sstevel@tonic-gate #define PATHNAME "/usr/lib/smedia" 610Sstevel@tonic-gate #endif 620Sstevel@tonic-gate 630Sstevel@tonic-gate #define PERROR(string) my_perror(gettext(string)) 640Sstevel@tonic-gate #define RUN_LIBSMEDIA_SERVER " /usr/lib/smedia/rpc.smserverd &\n" 650Sstevel@tonic-gate 660Sstevel@tonic-gate static void 670Sstevel@tonic-gate my_perror(char *err_string) 680Sstevel@tonic-gate { 690Sstevel@tonic-gate 700Sstevel@tonic-gate int error_no; 710Sstevel@tonic-gate if (errno == 0) 720Sstevel@tonic-gate return; 730Sstevel@tonic-gate 740Sstevel@tonic-gate error_no = errno; 750Sstevel@tonic-gate (void) fprintf(stderr, gettext(err_string)); 760Sstevel@tonic-gate (void) fprintf(stderr, gettext(" : ")); 770Sstevel@tonic-gate errno = error_no; 780Sstevel@tonic-gate perror(""); 790Sstevel@tonic-gate } 800Sstevel@tonic-gate 810Sstevel@tonic-gate static int 820Sstevel@tonic-gate is_server_running(rmedia_handle_t *handle) 830Sstevel@tonic-gate { 840Sstevel@tonic-gate door_arg_t door_args; 850Sstevel@tonic-gate smedia_reqping_t reqping; 860Sstevel@tonic-gate smedia_retping_t *retping; 870Sstevel@tonic-gate int ret_val; 880Sstevel@tonic-gate int door_fd; 890Sstevel@tonic-gate CLIENT *clnt; 900Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)]; 910Sstevel@tonic-gate smserver_info *server_info; 920Sstevel@tonic-gate 930Sstevel@tonic-gate /* 940Sstevel@tonic-gate * We will assume that we are running at level 2 or greater 950Sstevel@tonic-gate * and attempt to contact the server using RPC mecahnisms. 960Sstevel@tonic-gate * If that fails then we will attempt to contact the server 970Sstevel@tonic-gate * using non-rpc mechanism. This will enable the libsmedia 980Sstevel@tonic-gate * to be used in SINGLE user mode when inetd is not running. 990Sstevel@tonic-gate * We expect the server to have been started manually by user. 100*7888Sandrew.rutz@sun.com * 101*7888Sandrew.rutz@sun.com * Note that "localhost" is used (vs hostname (eg, "uname -n")), 102*7888Sandrew.rutz@sun.com * as this minimizes interference with common IPSec rules. 1030Sstevel@tonic-gate */ 1040Sstevel@tonic-gate 105*7888Sandrew.rutz@sun.com clnt = clnt_create("localhost", SMSERVERPROG, SMSERVERVERS, 106*7888Sandrew.rutz@sun.com "circuit_v"); 1070Sstevel@tonic-gate if (clnt == (CLIENT *)NULL) { 1080Sstevel@tonic-gate /* 1090Sstevel@tonic-gate * The failure could be that we are running at level 1 1100Sstevel@tonic-gate */ 1110Sstevel@tonic-gate door_fd = open(smedia_service, O_RDONLY, 0644); 1120Sstevel@tonic-gate if (door_fd < 0) { 1130Sstevel@tonic-gate DPRINTF1("Error in opening %s\n", 114*7888Sandrew.rutz@sun.com smedia_service); 1150Sstevel@tonic-gate return (0); 1160Sstevel@tonic-gate } 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate DPRINTF1("rbuf address=%p\n", rbuf); 1190Sstevel@tonic-gate reqping.cnum = SMEDIA_CNUM_PING; 1200Sstevel@tonic-gate door_args.data_ptr = (char *)&reqping; 1210Sstevel@tonic-gate door_args.data_size = sizeof (smedia_services_t); 1220Sstevel@tonic-gate door_args.desc_ptr = NULL; 1230Sstevel@tonic-gate door_args.desc_num = 0; 1240Sstevel@tonic-gate door_args.rbuf = rbuf; 1250Sstevel@tonic-gate door_args.rsize = sizeof (rbuf); 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate ret_val = door_call(door_fd, &door_args); 1280Sstevel@tonic-gate (void) close(door_fd); 1290Sstevel@tonic-gate if (ret_val < 0) { 1300Sstevel@tonic-gate return (0); 1310Sstevel@tonic-gate } 1320Sstevel@tonic-gate DPRINTF3("rsize = %d data_size = %d data_ptr = %p \n", 133*7888Sandrew.rutz@sun.com door_args.rsize, door_args.data_size, 134*7888Sandrew.rutz@sun.com door_args.data_ptr); 1350Sstevel@tonic-gate retping = (smedia_retping_t *)( 136*7888Sandrew.rutz@sun.com (void *)door_args.data_ptr); 1370Sstevel@tonic-gate if (retping->cnum != SMEDIA_CNUM_PING) { 138*7888Sandrew.rutz@sun.com DPRINTF1("*** door call failed *** cnum " 139*7888Sandrew.rutz@sun.com "returned = 0x%x\n", retping->cnum); 1400Sstevel@tonic-gate return (0); 1410Sstevel@tonic-gate } 1420Sstevel@tonic-gate return (1); 1430Sstevel@tonic-gate } 1440Sstevel@tonic-gate server_info = smserverproc_get_serverinfo_1(NULL, clnt); 1450Sstevel@tonic-gate if (server_info == NULL) { 1460Sstevel@tonic-gate if (clnt) 1470Sstevel@tonic-gate clnt_destroy(clnt); 1480Sstevel@tonic-gate return (0); 1490Sstevel@tonic-gate } 1500Sstevel@tonic-gate if (server_info->status != 0) { 1510Sstevel@tonic-gate if (clnt) 1520Sstevel@tonic-gate clnt_destroy(clnt); 153*7888Sandrew.rutz@sun.com DPRINTF1("get server_info call failed. " 154*7888Sandrew.rutz@sun.com "status = %d\n", server_info->status); 1550Sstevel@tonic-gate return (0); 1560Sstevel@tonic-gate } 1570Sstevel@tonic-gate if (server_info->vernum != SMSERVERVERS) { 1580Sstevel@tonic-gate if (clnt) 1590Sstevel@tonic-gate clnt_destroy(clnt); 160*7888Sandrew.rutz@sun.com DPRINTF2("version expected = %d version " 161*7888Sandrew.rutz@sun.com "returned = %d\n", SMSERVERVERS, 162*7888Sandrew.rutz@sun.com server_info->vernum); 1630Sstevel@tonic-gate return (0); 1640Sstevel@tonic-gate } 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate door_fd = open(smedia_service, O_RDONLY, 0644); 1670Sstevel@tonic-gate if (door_fd < 0) { 1680Sstevel@tonic-gate DPRINTF1("Error in opening %s\n", smedia_service); 1690Sstevel@tonic-gate return (0); 1700Sstevel@tonic-gate } 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate DPRINTF1("rbuf address=%p\n", rbuf); 1730Sstevel@tonic-gate reqping.cnum = SMEDIA_CNUM_PING; 1740Sstevel@tonic-gate door_args.data_ptr = (char *)&reqping; 1750Sstevel@tonic-gate door_args.data_size = sizeof (smedia_services_t); 1760Sstevel@tonic-gate door_args.desc_ptr = NULL; 1770Sstevel@tonic-gate door_args.desc_num = 0; 1780Sstevel@tonic-gate door_args.rbuf = rbuf; 1790Sstevel@tonic-gate door_args.rsize = sizeof (rbuf); 1800Sstevel@tonic-gate 1810Sstevel@tonic-gate ret_val = door_call(door_fd, &door_args); 1820Sstevel@tonic-gate (void) close(door_fd); 1830Sstevel@tonic-gate if (ret_val < 0) { 1840Sstevel@tonic-gate return (0); 1850Sstevel@tonic-gate } 1860Sstevel@tonic-gate DPRINTF3("rsize = %d data_size = %d data_ptr = %p \n", 187*7888Sandrew.rutz@sun.com door_args.rsize, door_args.data_size, 188*7888Sandrew.rutz@sun.com door_args.data_ptr); 1890Sstevel@tonic-gate retping = (smedia_retping_t *)((void *)door_args.data_ptr); 1900Sstevel@tonic-gate if (retping->cnum != SMEDIA_CNUM_PING) { 191*7888Sandrew.rutz@sun.com DPRINTF1("*** door call failed *** cnum returned " 192*7888Sandrew.rutz@sun.com "= 0x%x\n", retping->cnum); 1930Sstevel@tonic-gate return (0); 1940Sstevel@tonic-gate } 1950Sstevel@tonic-gate handle->sm_clnt = clnt; 1960Sstevel@tonic-gate return (1); 1970Sstevel@tonic-gate } 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate static void * 2000Sstevel@tonic-gate get_dev_library_handle(int32_t fd) 2010Sstevel@tonic-gate { 2020Sstevel@tonic-gate void *handle; 2030Sstevel@tonic-gate void *old_handle = NULL; 2040Sstevel@tonic-gate struct dk_cinfo dkinfo; 2050Sstevel@tonic-gate DIR *dirp; 2060Sstevel@tonic-gate struct dirent *dp; 2070Sstevel@tonic-gate char *pathname; 2080Sstevel@tonic-gate int32_t (*d_fcn_ptr)(ushort_t, ushort_t); 2090Sstevel@tonic-gate int32_t (*v_fcn_ptr)(void); 2100Sstevel@tonic-gate int32_t ret_val; 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) { 2130Sstevel@tonic-gate PERROR("DKIOCINFO failed"); 2140Sstevel@tonic-gate return (NULL); 2150Sstevel@tonic-gate } 2160Sstevel@tonic-gate DPRINTF1("dki_ctype = 0x%x\n", dkinfo.dki_ctype); 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate if ((pathname = malloc(PATH_MAX)) == NULL) { 2190Sstevel@tonic-gate PERROR("malloc failed"); 2200Sstevel@tonic-gate return (NULL); 2210Sstevel@tonic-gate } 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate dirp = opendir(PATHNAME); 2240Sstevel@tonic-gate if (dirp == NULL) { 2250Sstevel@tonic-gate (void) fprintf(stderr, gettext("Couldnot open %s\n"), PATHNAME); 2260Sstevel@tonic-gate free(pathname); 2270Sstevel@tonic-gate return (NULL); 2280Sstevel@tonic-gate } 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate while ((dp = readdir(dirp)) != NULL) { 2310Sstevel@tonic-gate if (strncmp("sm_", dp->d_name, 3) != 0) { 2320Sstevel@tonic-gate DPRINTF1("not a library %s\n", dp->d_name); 2330Sstevel@tonic-gate continue; 2340Sstevel@tonic-gate } 2350Sstevel@tonic-gate if (snprintf(pathname, PATH_MAX, "%s/%s", 2360Sstevel@tonic-gate PATHNAME, dp->d_name) >= PATH_MAX) { 2370Sstevel@tonic-gate continue; 2380Sstevel@tonic-gate } 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate handle = dlopen(pathname, RTLD_LAZY); 2410Sstevel@tonic-gate if (handle == NULL) { 2420Sstevel@tonic-gate PERROR("Error opening library file"); 2430Sstevel@tonic-gate continue; 2440Sstevel@tonic-gate } 2450Sstevel@tonic-gate d_fcn_ptr = (int32_t (*)(ushort_t, ushort_t))dlsym(handle, 246*7888Sandrew.rutz@sun.com "_m_device_type"); 2470Sstevel@tonic-gate if (d_fcn_ptr == NULL) { 2480Sstevel@tonic-gate DPRINTF("Could not find _m_device_type\n"); 2490Sstevel@tonic-gate (void) dlclose(handle); 2500Sstevel@tonic-gate continue; 2510Sstevel@tonic-gate } 2520Sstevel@tonic-gate ret_val = (*d_fcn_ptr)(dkinfo.dki_ctype, 0); 2530Sstevel@tonic-gate if (ret_val == 0) { 2540Sstevel@tonic-gate DPRINTF1("NAME %s\n", dp->d_name); 2550Sstevel@tonic-gate v_fcn_ptr = (int32_t (*)(void))dlsym(handle, 256*7888Sandrew.rutz@sun.com "_m_version_no"); 2570Sstevel@tonic-gate if (v_fcn_ptr == NULL) { 2580Sstevel@tonic-gate DPRINTF("Could not find _m_version_no\n"); 2590Sstevel@tonic-gate (void) dlclose(handle); 2600Sstevel@tonic-gate continue; 2610Sstevel@tonic-gate } 2620Sstevel@tonic-gate ret_val = (*v_fcn_ptr)(); 2630Sstevel@tonic-gate if ((ret_val >= 0) && 2640Sstevel@tonic-gate (ret_val >= SM_PLUGIN_VERSION)) { 2650Sstevel@tonic-gate if (old_handle != NULL) 2660Sstevel@tonic-gate (void) dlclose(old_handle); 2670Sstevel@tonic-gate old_handle = handle; 2680Sstevel@tonic-gate continue; 2690Sstevel@tonic-gate } else { 2700Sstevel@tonic-gate (void) dlclose(handle); 2710Sstevel@tonic-gate } 2720Sstevel@tonic-gate } else { 2730Sstevel@tonic-gate (void) dlclose(handle); 2740Sstevel@tonic-gate } 2750Sstevel@tonic-gate } 2760Sstevel@tonic-gate free(pathname); 2770Sstevel@tonic-gate (void) closedir(dirp); 2780Sstevel@tonic-gate return (old_handle); 2790Sstevel@tonic-gate } 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate int32_t 2820Sstevel@tonic-gate call_function(rmedia_handle_t *handle, void *ip, char *func_name) 2830Sstevel@tonic-gate { 2840Sstevel@tonic-gate 2850Sstevel@tonic-gate int32_t ret_val; 2860Sstevel@tonic-gate int32_t (*fcn_ptr)(rmedia_handle_t *handle, void *ip); 2870Sstevel@tonic-gate void *lib_handle; 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate if (handle == NULL) { 2900Sstevel@tonic-gate DPRINTF("Handle is NULL\n"); 2910Sstevel@tonic-gate errno = EINVAL; 2920Sstevel@tonic-gate return (-1); 2930Sstevel@tonic-gate } 2940Sstevel@tonic-gate lib_handle = handle->sm_lib_handle; 2950Sstevel@tonic-gate if (handle->sm_signature != LIBSMEDIA_SIGNATURE) { 2960Sstevel@tonic-gate DPRINTF2("call_function:signature expected=0x%x, found=0x%x\n", 297*7888Sandrew.rutz@sun.com LIBSMEDIA_SIGNATURE, handle->sm_signature); 2980Sstevel@tonic-gate errno = EINVAL; 2990Sstevel@tonic-gate return (-1); 3000Sstevel@tonic-gate } 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate fcn_ptr = (int32_t (*)(rmedia_handle_t *, void*)) 303*7888Sandrew.rutz@sun.com dlsym(lib_handle, func_name); 3040Sstevel@tonic-gate if (fcn_ptr == NULL) { 3050Sstevel@tonic-gate DPRINTF1("Could not find %s\n", func_name); 3060Sstevel@tonic-gate errno = ENOTSUP; 3070Sstevel@tonic-gate return (-1); 3080Sstevel@tonic-gate } 3090Sstevel@tonic-gate ret_val = (*fcn_ptr)(handle, ip); 3100Sstevel@tonic-gate return (ret_val); 3110Sstevel@tonic-gate } 3120Sstevel@tonic-gate 3130Sstevel@tonic-gate int32_t 3140Sstevel@tonic-gate release_handle(rmedia_handle_t *handle) 3150Sstevel@tonic-gate { 3160Sstevel@tonic-gate if (handle == NULL) { 3170Sstevel@tonic-gate DPRINTF("Handle is NULL\n"); 3180Sstevel@tonic-gate errno = EINVAL; 3190Sstevel@tonic-gate return (-1); 3200Sstevel@tonic-gate } 3210Sstevel@tonic-gate if ((handle->sm_dkinfo.dki_ctype == DKC_SCSI_CCS) || 322*7888Sandrew.rutz@sun.com (handle->sm_dkinfo.dki_ctype == DKC_MD21) || 323*7888Sandrew.rutz@sun.com (handle->sm_dkinfo.dki_ctype == DKC_CDROM)) { 3240Sstevel@tonic-gate (void) close(handle->sm_door); 3250Sstevel@tonic-gate (void) close(handle->sm_death_door); 3260Sstevel@tonic-gate if (handle->sm_buf != NULL) 3270Sstevel@tonic-gate (void) munmap(handle->sm_buf, handle->sm_bufsize); 3280Sstevel@tonic-gate if (handle->sm_clnt != NULL) 3290Sstevel@tonic-gate clnt_destroy(handle->sm_clnt); 3300Sstevel@tonic-gate } 3310Sstevel@tonic-gate (void) close(handle->sm_buffd); 3320Sstevel@tonic-gate handle->sm_signature = 0; 3330Sstevel@tonic-gate (void) dlclose(handle->sm_lib_handle); 3340Sstevel@tonic-gate free(handle); 3350Sstevel@tonic-gate return (0); 3360Sstevel@tonic-gate } 3370Sstevel@tonic-gate 3380Sstevel@tonic-gate smedia_handle_t 3390Sstevel@tonic-gate get_handle_from_fd(int32_t fd) 3400Sstevel@tonic-gate { 3410Sstevel@tonic-gate rmedia_handle_t *handle; 3420Sstevel@tonic-gate void *lib_handle; 3430Sstevel@tonic-gate int door_fd, door_server; 3440Sstevel@tonic-gate int ret_val; 3450Sstevel@tonic-gate door_arg_t door_args; 3460Sstevel@tonic-gate smedia_reqopen_t reqopen; 3470Sstevel@tonic-gate smedia_reterror_t *reterror; 3480Sstevel@tonic-gate door_desc_t ddesc[2]; 3490Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)]; 3500Sstevel@tonic-gate struct stat stat; 3510Sstevel@tonic-gate 3520Sstevel@tonic-gate DPRINTF("smedia_get_handle called\n"); 3530Sstevel@tonic-gate handle = (rmedia_handle_t *)malloc(sizeof (rmedia_handle_t)); 3540Sstevel@tonic-gate if (handle == NULL) { 3550Sstevel@tonic-gate DPRINTF("Could not allocate memory for handle\n"); 3560Sstevel@tonic-gate return (NULL); 3570Sstevel@tonic-gate } 3580Sstevel@tonic-gate (void) memset((void *) handle, 0, sizeof (rmedia_handle_t)); 3590Sstevel@tonic-gate handle->sm_fd = -1; 3600Sstevel@tonic-gate handle->sm_door = -1; 3610Sstevel@tonic-gate handle->sm_death_door = -1; 3620Sstevel@tonic-gate handle->sm_buffd = -1; 3630Sstevel@tonic-gate handle->sm_buf = NULL; 3640Sstevel@tonic-gate handle->sm_bufsize = 0; 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate if (ioctl(fd, DKIOCINFO, &handle->sm_dkinfo) == -1) { 3670Sstevel@tonic-gate free(handle); 3680Sstevel@tonic-gate PERROR("DKIOCINFO failed"); 3690Sstevel@tonic-gate return (NULL); 3700Sstevel@tonic-gate } 3710Sstevel@tonic-gate lib_handle = get_dev_library_handle(fd); 3720Sstevel@tonic-gate if (lib_handle == NULL) { 3730Sstevel@tonic-gate free(handle); 3740Sstevel@tonic-gate DPRINTF("lib_Handle is NULL\n"); 3750Sstevel@tonic-gate errno = ENOTSUP; 3760Sstevel@tonic-gate return (NULL); 3770Sstevel@tonic-gate } 3780Sstevel@tonic-gate DPRINTF("Handle initialised successfully.\n"); 3790Sstevel@tonic-gate /* Initialise the handle elements */ 3800Sstevel@tonic-gate handle->sm_lib_handle = lib_handle; 3810Sstevel@tonic-gate handle->sm_signature = LIBSMEDIA_SIGNATURE; 3820Sstevel@tonic-gate DPRINTF2("fd=%d signature=0x%x\n", handle->sm_fd, handle->sm_signature); 3830Sstevel@tonic-gate 3840Sstevel@tonic-gate if ((handle->sm_dkinfo.dki_ctype == DKC_SCSI_CCS) || 385*7888Sandrew.rutz@sun.com (handle->sm_dkinfo.dki_ctype == DKC_MD21) || 386*7888Sandrew.rutz@sun.com (handle->sm_dkinfo.dki_ctype == DKC_CDROM)) { 3870Sstevel@tonic-gate 3880Sstevel@tonic-gate ret_val = is_server_running(handle); 3890Sstevel@tonic-gate if (ret_val == 0) { 3900Sstevel@tonic-gate (void) dlclose(handle->sm_lib_handle); 3910Sstevel@tonic-gate free(handle); 3920Sstevel@tonic-gate return (NULL); 3930Sstevel@tonic-gate } 3940Sstevel@tonic-gate door_fd = open(smedia_service, O_RDONLY, 0644); 3950Sstevel@tonic-gate if (door_fd < 0) { 3960Sstevel@tonic-gate (void) dlclose(handle->sm_lib_handle); 3970Sstevel@tonic-gate free(handle); 3980Sstevel@tonic-gate if (handle->sm_clnt) 3990Sstevel@tonic-gate clnt_destroy(handle->sm_clnt); 4000Sstevel@tonic-gate DPRINTF1("Error in opening %s\n", smedia_service); 4010Sstevel@tonic-gate PERROR(smedia_service); 4020Sstevel@tonic-gate return (NULL); 4030Sstevel@tonic-gate } 4040Sstevel@tonic-gate 4050Sstevel@tonic-gate DPRINTF1("rbuf address=%p\n", rbuf); 4060Sstevel@tonic-gate ddesc[0].d_data.d_desc.d_descriptor = fd; 4070Sstevel@tonic-gate ddesc[0].d_attributes = DOOR_DESCRIPTOR; 4080Sstevel@tonic-gate reqopen.cnum = SMEDIA_CNUM_OPEN_FD; 4090Sstevel@tonic-gate door_args.data_ptr = (char *)&reqopen; 4100Sstevel@tonic-gate door_args.data_size = sizeof (smedia_services_t); 4110Sstevel@tonic-gate door_args.desc_ptr = &ddesc[0]; 4120Sstevel@tonic-gate door_args.desc_num = 1; 4130Sstevel@tonic-gate door_args.rbuf = rbuf; 4140Sstevel@tonic-gate door_args.rsize = sizeof (rbuf); 4150Sstevel@tonic-gate 4160Sstevel@tonic-gate ret_val = door_call(door_fd, &door_args); 4170Sstevel@tonic-gate (void) close(door_fd); 4180Sstevel@tonic-gate if (ret_val < 0) { 4190Sstevel@tonic-gate (void) dlclose(handle->sm_lib_handle); 4200Sstevel@tonic-gate free(handle); 4210Sstevel@tonic-gate if (handle->sm_clnt) 4220Sstevel@tonic-gate clnt_destroy(handle->sm_clnt); 4230Sstevel@tonic-gate PERROR("door_call"); 4240Sstevel@tonic-gate return (NULL); 4250Sstevel@tonic-gate } 4260Sstevel@tonic-gate DPRINTF3("rsize = %d data_size = %d data_ptr = %p \n", 427*7888Sandrew.rutz@sun.com door_args.rsize, door_args.data_size, 428*7888Sandrew.rutz@sun.com door_args.data_ptr); 4290Sstevel@tonic-gate reterror = (smedia_reterror_t *)((void *)door_args.data_ptr); 4300Sstevel@tonic-gate if (reterror->cnum != SMEDIA_CNUM_OPEN_FD) { 4310Sstevel@tonic-gate (void) dlclose(handle->sm_lib_handle); 4320Sstevel@tonic-gate free(handle); 4330Sstevel@tonic-gate if (handle->sm_clnt) 4340Sstevel@tonic-gate clnt_destroy(handle->sm_clnt); 4350Sstevel@tonic-gate DPRINTF1( 4360Sstevel@tonic-gate "*** door call failed *** cnum returned = 0x%x\n", reterror->cnum); 4370Sstevel@tonic-gate errno = reterror->errnum; 4380Sstevel@tonic-gate return (NULL); 4390Sstevel@tonic-gate } 4400Sstevel@tonic-gate /* 4410Sstevel@tonic-gate * 2 door descriptors are returned after the above door call. 4420Sstevel@tonic-gate * The first door descriptor is the one that will be used 4430Sstevel@tonic-gate * in subsequent smedia calls. A dedicated thread is 4440Sstevel@tonic-gate * associated with this door to handle client calls. 4450Sstevel@tonic-gate * The second door descriptor is needed to signal unexpected 4460Sstevel@tonic-gate * death of the client to the server. This will help the server 4470Sstevel@tonic-gate * to do the necessary cleanup. 4480Sstevel@tonic-gate */ 4490Sstevel@tonic-gate if (door_args.desc_num != 2) { 4500Sstevel@tonic-gate (void) dlclose(handle->sm_lib_handle); 4510Sstevel@tonic-gate free(handle); 4520Sstevel@tonic-gate if (handle->sm_clnt) 4530Sstevel@tonic-gate clnt_destroy(handle->sm_clnt); 454*7888Sandrew.rutz@sun.com DPRINTF("Num of door descriptors returned by " 455*7888Sandrew.rutz@sun.com "server is not 2"); 4560Sstevel@tonic-gate if (door_args.desc_num) 457*7888Sandrew.rutz@sun.com (void) close(door_args.desc_ptr->\ 458*7888Sandrew.rutz@sun.com d_data.d_desc.d_descriptor); 4590Sstevel@tonic-gate return (NULL); 4600Sstevel@tonic-gate } 4610Sstevel@tonic-gate door_server = door_args.desc_ptr->d_data.d_desc.d_descriptor; 4620Sstevel@tonic-gate /* Check if the descriptor returned is S_IFDOOR */ 4630Sstevel@tonic-gate if (fstat(door_server, &stat) < 0) { 4640Sstevel@tonic-gate PERROR("fstat"); 4650Sstevel@tonic-gate (void) dlclose(handle->sm_lib_handle); 4660Sstevel@tonic-gate free(handle); 4670Sstevel@tonic-gate if (handle->sm_clnt) 4680Sstevel@tonic-gate clnt_destroy(handle->sm_clnt); 4690Sstevel@tonic-gate return (NULL); 4700Sstevel@tonic-gate } 471871Scasper if (!S_ISDOOR(stat.st_mode)) { 4720Sstevel@tonic-gate DPRINTF( 4730Sstevel@tonic-gate "Descriptor returned by door_call is not of type DOOR\n"); 4740Sstevel@tonic-gate (void) dlclose(handle->sm_lib_handle); 4750Sstevel@tonic-gate free(handle); 4760Sstevel@tonic-gate if (handle->sm_clnt) 4770Sstevel@tonic-gate clnt_destroy(handle->sm_clnt); 4780Sstevel@tonic-gate return (NULL); 4790Sstevel@tonic-gate } 4800Sstevel@tonic-gate handle->sm_door = door_server; 4810Sstevel@tonic-gate handle->sm_fd = fd; 4820Sstevel@tonic-gate door_args.desc_ptr++; 4830Sstevel@tonic-gate handle->sm_death_door = 484*7888Sandrew.rutz@sun.com door_args.desc_ptr->d_data.d_desc.d_descriptor; 4850Sstevel@tonic-gate DPRINTF("door call succeeded.\n"); 4860Sstevel@tonic-gate return ((smedia_handle_t)handle); 4870Sstevel@tonic-gate 4880Sstevel@tonic-gate } else { 4890Sstevel@tonic-gate handle->sm_fd = fd; 4900Sstevel@tonic-gate return ((smedia_handle_t)handle); 4910Sstevel@tonic-gate } 4920Sstevel@tonic-gate 4930Sstevel@tonic-gate } 494