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