12654012fSReza Sabdar /* 2*674cb4b0SReza Sabdar * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 32654012fSReza Sabdar * Use is subject to license terms. 42654012fSReza Sabdar */ 52654012fSReza Sabdar 62654012fSReza Sabdar /* 72654012fSReza Sabdar * BSD 3 Clause License 82654012fSReza Sabdar * 92654012fSReza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association. 102654012fSReza Sabdar * 112654012fSReza Sabdar * Redistribution and use in source and binary forms, with or without 122654012fSReza Sabdar * modification, are permitted provided that the following conditions 132654012fSReza Sabdar * are met: 142654012fSReza Sabdar * - Redistributions of source code must retain the above copyright 152654012fSReza Sabdar * notice, this list of conditions and the following disclaimer. 162654012fSReza Sabdar * 172654012fSReza Sabdar * - Redistributions in binary form must reproduce the above copyright 182654012fSReza Sabdar * notice, this list of conditions and the following disclaimer in 192654012fSReza Sabdar * the documentation and/or other materials provided with the 202654012fSReza Sabdar * distribution. 212654012fSReza Sabdar * 222654012fSReza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA) 232654012fSReza Sabdar * nor the names of its contributors may be used to endorse or promote 242654012fSReza Sabdar * products derived from this software without specific prior written 252654012fSReza Sabdar * permission. 262654012fSReza Sabdar * 272654012fSReza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 282654012fSReza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 292654012fSReza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 302654012fSReza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 312654012fSReza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 322654012fSReza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 332654012fSReza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 342654012fSReza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 352654012fSReza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 362654012fSReza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 372654012fSReza Sabdar * POSSIBILITY OF SUCH DAMAGE. 382654012fSReza Sabdar */ 392654012fSReza Sabdar 402654012fSReza Sabdar /* This file contains all the door server code */ 412654012fSReza Sabdar 422654012fSReza Sabdar #include <door.h> 432654012fSReza Sabdar #include <alloca.h> 442654012fSReza Sabdar #include <errno.h> 452654012fSReza Sabdar #include <note.h> 462654012fSReza Sabdar #include <libintl.h> 472654012fSReza Sabdar #include <ndmpd_door.h> 482654012fSReza Sabdar #include "ndmpd.h" 492654012fSReza Sabdar 502654012fSReza Sabdar /* static variables */ 512654012fSReza Sabdar static int ndmp_door_fildes = -1; 522654012fSReza Sabdar static mutex_t ndmp_doorsrv_mutex; 532654012fSReza Sabdar 542654012fSReza Sabdar /* static routines */ 552654012fSReza Sabdar static void ndmp_door_server(void *cookie, char *ptr, size_t size, 562654012fSReza Sabdar door_desc_t *dp, uint_t n_desc); 572654012fSReza Sabdar 582654012fSReza Sabdar /* 592654012fSReza Sabdar * Statistics used in ndmpstat command 602654012fSReza Sabdar */ 612654012fSReza Sabdar ndmp_stat_t ndstat; 622654012fSReza Sabdar 632654012fSReza Sabdar int 642654012fSReza Sabdar ndmp_door_init(void) 652654012fSReza Sabdar { 662654012fSReza Sabdar int fd; 672654012fSReza Sabdar 682654012fSReza Sabdar (void) mutex_lock(&ndmp_doorsrv_mutex); 692654012fSReza Sabdar 702654012fSReza Sabdar if (ndmp_door_fildes != -1) { 712654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 722654012fSReza Sabdar "ndmp_door_init: ndmpd service is already running."); 732654012fSReza Sabdar (void) mutex_unlock(&ndmp_doorsrv_mutex); 742654012fSReza Sabdar return (0); 752654012fSReza Sabdar } 762654012fSReza Sabdar 772654012fSReza Sabdar if ((ndmp_door_fildes = door_create(ndmp_door_server, 782654012fSReza Sabdar NULL, DOOR_UNREF)) < 0) { 792654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Could not create door."); 802654012fSReza Sabdar (void) mutex_unlock(&ndmp_doorsrv_mutex); 812654012fSReza Sabdar return (-1); 822654012fSReza Sabdar } 832654012fSReza Sabdar 842654012fSReza Sabdar (void) unlink(NDMP_DOOR_SVC); 852654012fSReza Sabdar 862654012fSReza Sabdar if ((fd = creat(NDMP_DOOR_SVC, 0444)) < 0) { 872654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Can't create %s: %m.", 882654012fSReza Sabdar NDMP_DOOR_SVC); 892654012fSReza Sabdar (void) door_revoke(ndmp_door_fildes); 902654012fSReza Sabdar ndmp_door_fildes = -1; 912654012fSReza Sabdar (void) mutex_unlock(&ndmp_doorsrv_mutex); 922654012fSReza Sabdar return (-1); 932654012fSReza Sabdar } 942654012fSReza Sabdar 952654012fSReza Sabdar (void) close(fd); 962654012fSReza Sabdar (void) fdetach(NDMP_DOOR_SVC); 972654012fSReza Sabdar 982654012fSReza Sabdar if (fattach(ndmp_door_fildes, NDMP_DOOR_SVC) < 0) { 992654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ndmp_door_init: fattach failed %m"); 1002654012fSReza Sabdar (void) door_revoke(ndmp_door_fildes); 1012654012fSReza Sabdar ndmp_door_fildes = -1; 1022654012fSReza Sabdar (void) mutex_unlock(&ndmp_doorsrv_mutex); 1032654012fSReza Sabdar return (-1); 1042654012fSReza Sabdar } 1052654012fSReza Sabdar 1062654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Door server successfully started"); 1072654012fSReza Sabdar (void) mutex_unlock(&ndmp_doorsrv_mutex); 1082654012fSReza Sabdar return (0); 1092654012fSReza Sabdar } 1102654012fSReza Sabdar 1112654012fSReza Sabdar void 1122654012fSReza Sabdar ndmp_door_fini(void) 1132654012fSReza Sabdar { 1142654012fSReza Sabdar (void) mutex_lock(&ndmp_doorsrv_mutex); 1152654012fSReza Sabdar 1162654012fSReza Sabdar if (ndmp_door_fildes != -1) { 1172654012fSReza Sabdar (void) fdetach(NDMP_DOOR_SVC); 1182654012fSReza Sabdar (void) door_revoke(ndmp_door_fildes); 1192654012fSReza Sabdar ndmp_door_fildes = -1; 1202654012fSReza Sabdar } 1212654012fSReza Sabdar 1222654012fSReza Sabdar (void) mutex_unlock(&ndmp_doorsrv_mutex); 1232654012fSReza Sabdar } 1242654012fSReza Sabdar 1252654012fSReza Sabdar boolean_t 1262654012fSReza Sabdar ndmp_door_check(void) 1272654012fSReza Sabdar { 1282654012fSReza Sabdar door_info_t info; 1292654012fSReza Sabdar int door; 1302654012fSReza Sabdar 1312654012fSReza Sabdar if ((door = open(NDMP_DOOR_SVC, O_RDONLY)) < 0) 1322654012fSReza Sabdar return (0); 1332654012fSReza Sabdar 1342654012fSReza Sabdar if (door_info(door, &info) < 0) { 1352654012fSReza Sabdar (void) close(door); 1362654012fSReza Sabdar return (0); 1372654012fSReza Sabdar } 1382654012fSReza Sabdar 1392654012fSReza Sabdar if (info.di_target > 0) { 1402654012fSReza Sabdar NDMP_LOG(LOG_ERR, 1412654012fSReza Sabdar "Service already running: pid %ld", info.di_target); 1422654012fSReza Sabdar (void) close(door); 1432654012fSReza Sabdar return (1); 1442654012fSReza Sabdar } 1452654012fSReza Sabdar 1462654012fSReza Sabdar (void) close(door); 1472654012fSReza Sabdar return (0); 1482654012fSReza Sabdar } 1492654012fSReza Sabdar 1502654012fSReza Sabdar /* door server */ 1512654012fSReza Sabdar /*ARGSUSED*/ 1522654012fSReza Sabdar void 1532654012fSReza Sabdar ndmp_door_server(void *cookie, char *ptr, size_t size, 1542654012fSReza Sabdar door_desc_t *dp, uint_t n_desc) 1552654012fSReza Sabdar { 1562654012fSReza Sabdar NOTE(ARGUNUSED(cookie,dp,n_desc)) 1572654012fSReza Sabdar int req_type; 1582654012fSReza Sabdar char *buf; 1592654012fSReza Sabdar int buflen; 1602654012fSReza Sabdar unsigned int used; 1612654012fSReza Sabdar ndmp_door_ctx_t *dec_ctx; 1622654012fSReza Sabdar ndmp_door_ctx_t *enc_ctx; 1632654012fSReza Sabdar unsigned int dec_status; 1642654012fSReza Sabdar unsigned int enc_status; 1652654012fSReza Sabdar 1662654012fSReza Sabdar dec_ctx = ndmp_door_decode_start(ptr, size); 1672654012fSReza Sabdar if (dec_ctx == 0) 1682654012fSReza Sabdar return; 1692654012fSReza Sabdar 1702654012fSReza Sabdar req_type = ndmp_door_get_uint32(dec_ctx); 1712654012fSReza Sabdar buflen = NDMP_DOOR_SIZE; 1722654012fSReza Sabdar 1732654012fSReza Sabdar if ((buf = alloca(buflen)) == NULL) { 1742654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "Out of memory."); 1752654012fSReza Sabdar (void) ndmp_door_decode_finish(dec_ctx); 1762654012fSReza Sabdar return; 1772654012fSReza Sabdar } 1782654012fSReza Sabdar 1792654012fSReza Sabdar enc_ctx = ndmp_door_encode_start(buf, buflen); 1802654012fSReza Sabdar if (enc_ctx == 0) { 1812654012fSReza Sabdar (void) ndmp_door_decode_finish(dec_ctx); 1822654012fSReza Sabdar return; 1832654012fSReza Sabdar } 1842654012fSReza Sabdar 185*674cb4b0SReza Sabdar if (req_type != NDMP_GET_STAT) 1862654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, "ndmp_door_server: req_type=%d", req_type); 1872654012fSReza Sabdar 1882654012fSReza Sabdar switch (req_type) { 1892654012fSReza Sabdar case NDMP_GET_DOOR_STATUS: { 1902654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS); 1912654012fSReza Sabdar break; 1922654012fSReza Sabdar } 1932654012fSReza Sabdar case NDMP_DEVICES_GET_INFO: { 1942654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS); 1952654012fSReza Sabdar ndmpd_get_devs(enc_ctx); 1962654012fSReza Sabdar break; 1972654012fSReza Sabdar } 1982654012fSReza Sabdar case NDMP_SHOW: { 1992654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS); 2002654012fSReza Sabdar ndmp_connect_list_get(enc_ctx); 2012654012fSReza Sabdar break; 2022654012fSReza Sabdar } 2032654012fSReza Sabdar case NDMP_TERMINATE_SESSION_ID: { 2042654012fSReza Sabdar int status, id; 2052654012fSReza Sabdar id = ndmp_door_get_int32(dec_ctx); 2062654012fSReza Sabdar status = ndmpd_connect_kill_id(id); 2072654012fSReza Sabdar if (status == -1) /* session not found */ 2082654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, 2092654012fSReza Sabdar NDMP_DOOR_SRV_SUCCESS); 2102654012fSReza Sabdar else 2112654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, 2122654012fSReza Sabdar NDMP_DOOR_SRV_SUCCESS); 2132654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, status); 2142654012fSReza Sabdar break; 2152654012fSReza Sabdar } 2162654012fSReza Sabdar 2172654012fSReza Sabdar case NDMP_GET_STAT: 2182654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS); 2192654012fSReza Sabdar ndmp_door_put_uint32(enc_ctx, ndstat.ns_trun); 2202654012fSReza Sabdar ndmp_door_put_uint32(enc_ctx, ndstat.ns_twait); 2212654012fSReza Sabdar ndmp_door_put_uint32(enc_ctx, ndstat.ns_nbk); 2222654012fSReza Sabdar ndmp_door_put_uint32(enc_ctx, ndstat.ns_nrs); 2232654012fSReza Sabdar ndmp_door_put_uint32(enc_ctx, ndstat.ns_rfile); 2242654012fSReza Sabdar ndmp_door_put_uint32(enc_ctx, ndstat.ns_wfile); 2252654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, ndstat.ns_rdisk); 2262654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, ndstat.ns_wdisk); 2272654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, ndstat.ns_rtape); 2282654012fSReza Sabdar ndmp_door_put_uint64(enc_ctx, ndstat.ns_wtape); 2292654012fSReza Sabdar break; 2302654012fSReza Sabdar 2312654012fSReza Sabdar default: 2322654012fSReza Sabdar NDMP_LOG(LOG_DEBUG, 2332654012fSReza Sabdar "ndmp_door_server: Invalid request type 0x%x", req_type); 2342654012fSReza Sabdar goto decode_error; 2352654012fSReza Sabdar } 2362654012fSReza Sabdar 2372654012fSReza Sabdar if ((dec_status = ndmp_door_decode_finish(dec_ctx)) != 0) 2382654012fSReza Sabdar goto decode_error; 2392654012fSReza Sabdar 2402654012fSReza Sabdar if ((enc_status = ndmp_door_encode_finish(enc_ctx, &used)) != 0) 2412654012fSReza Sabdar goto encode_error; 2422654012fSReza Sabdar 2432654012fSReza Sabdar (void) door_return(buf, used, NULL, 0); 2442654012fSReza Sabdar 2452654012fSReza Sabdar return; 2462654012fSReza Sabdar 2472654012fSReza Sabdar decode_error: 2482654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_ERROR); 2492654012fSReza Sabdar ndmp_door_put_uint32(enc_ctx, dec_status); 2502654012fSReza Sabdar (void) ndmp_door_encode_finish(enc_ctx, &used); 2512654012fSReza Sabdar (void) door_return(buf, used, NULL, 0); 2522654012fSReza Sabdar return; 2532654012fSReza Sabdar 2542654012fSReza Sabdar encode_error: 2552654012fSReza Sabdar enc_ctx = ndmp_door_encode_start(buf, buflen); 2562654012fSReza Sabdar ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_ERROR); 2572654012fSReza Sabdar ndmp_door_put_uint32(enc_ctx, enc_status); 2582654012fSReza Sabdar (void) ndmp_door_encode_finish(enc_ctx, &used); 2592654012fSReza Sabdar (void) door_return(buf, used, NULL, 0); 2602654012fSReza Sabdar } 261