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
ndmp_door_init(void)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
ndmp_door_fini(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
ndmp_door_check(void)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
ndmp_door_server(void * cookie,char * ptr,size_t size,door_desc_t * dp,uint_t n_desc)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