2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
9 * Copyright (c) 2007, The Storage Networking Industry Association.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * - Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * - Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
22 * - Neither the name of The Storage Networking Industry Association (SNIA)
23 * nor the names of its contributors may be used to endorse or promote
24 * products derived from this software without specific prior written
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
40 /* This file contains all the door server code */
47 #include <ndmpd_door.h>
50 /* static variables */
51 static int ndmp_door_fildes
= -1;
52 static mutex_t ndmp_doorsrv_mutex
;
55 static void ndmp_door_server(void *cookie
, char *ptr
, size_t size
,
56 door_desc_t
*dp
, uint_t n_desc
);
59 * Statistics used in ndmpstat command
68 (void) mutex_lock(&ndmp_doorsrv_mutex
);
70 if (ndmp_door_fildes
!= -1) {
72 "ndmp_door_init: ndmpd service is already running.");
73 (void) mutex_unlock(&ndmp_doorsrv_mutex
);
77 if ((ndmp_door_fildes
= door_create(ndmp_door_server
,
78 NULL
, DOOR_UNREF
)) < 0) {
79 NDMP_LOG(LOG_DEBUG
, "ndmp_door_init: Could not create door.");
80 (void) mutex_unlock(&ndmp_doorsrv_mutex
);
84 (void) unlink(NDMP_DOOR_SVC
);
86 if ((fd
= creat(NDMP_DOOR_SVC
, 0444)) < 0) {
87 NDMP_LOG(LOG_DEBUG
, "ndmp_door_init: Can't create %s: %m.",
89 (void) door_revoke(ndmp_door_fildes
);
90 ndmp_door_fildes
= -1;
91 (void) mutex_unlock(&ndmp_doorsrv_mutex
);
96 (void) fdetach(NDMP_DOOR_SVC
);
98 if (fattach(ndmp_door_fildes
, NDMP_DOOR_SVC
) < 0) {
99 NDMP_LOG(LOG_DEBUG
, "ndmp_door_init: fattach failed %m");
100 (void) door_revoke(ndmp_door_fildes
);
101 ndmp_door_fildes
= -1;
102 (void) mutex_unlock(&ndmp_doorsrv_mutex
);
106 NDMP_LOG(LOG_DEBUG
, "ndmp_door_init: Door server successfully started");
107 (void) mutex_unlock(&ndmp_doorsrv_mutex
);
114 (void) mutex_lock(&ndmp_doorsrv_mutex
);
116 if (ndmp_door_fildes
!= -1) {
117 (void) fdetach(NDMP_DOOR_SVC
);
118 (void) door_revoke(ndmp_door_fildes
);
119 ndmp_door_fildes
= -1;
122 (void) mutex_unlock(&ndmp_doorsrv_mutex
);
126 ndmp_door_check(void)
131 if ((door
= open(NDMP_DOOR_SVC
, O_RDONLY
)) < 0)
134 if (door_info(door
, &info
) < 0) {
139 if (info
.di_target
> 0) {
141 "Service already running: pid %ld", info
.di_target
);
153 ndmp_door_server(void *cookie
, char *ptr
, size_t size
,
154 door_desc_t
*dp
, uint_t n_desc
)
156 NOTE(ARGUNUSED(cookie
,dp
,n_desc
))
161 ndmp_door_ctx_t
*dec_ctx
;
162 ndmp_door_ctx_t
*enc_ctx
;
163 unsigned int dec_status
;
164 unsigned int enc_status
;
166 dec_ctx
= ndmp_door_decode_start(ptr
, size
);
170 req_type
= ndmp_door_get_uint32(dec_ctx
);
171 buflen
= NDMP_DOOR_SIZE
;
173 if ((buf
= alloca(buflen
)) == NULL
) {
174 NDMP_LOG(LOG_DEBUG
, "Out of memory.");
175 (void) ndmp_door_decode_finish(dec_ctx
);
179 enc_ctx
= ndmp_door_encode_start(buf
, buflen
);
181 (void) ndmp_door_decode_finish(dec_ctx
);
185 if (req_type
!= NDMP_GET_STAT
)
186 NDMP_LOG(LOG_DEBUG
, "ndmp_door_server: req_type=%d", req_type
);
189 case NDMP_GET_DOOR_STATUS
: {
190 ndmp_door_put_int32(enc_ctx
, NDMP_DOOR_SRV_SUCCESS
);
193 case NDMP_DEVICES_GET_INFO
: {
194 ndmp_door_put_int32(enc_ctx
, NDMP_DOOR_SRV_SUCCESS
);
195 ndmpd_get_devs(enc_ctx
);
199 ndmp_door_put_int32(enc_ctx
, NDMP_DOOR_SRV_SUCCESS
);
200 ndmp_connect_list_get(enc_ctx
);
203 case NDMP_TERMINATE_SESSION_ID
: {
205 id
= ndmp_door_get_int32(dec_ctx
);
206 status
= ndmpd_connect_kill_id(id
);
207 if (status
== -1) /* session not found */
208 ndmp_door_put_int32(enc_ctx
,
209 NDMP_DOOR_SRV_SUCCESS
);
211 ndmp_door_put_int32(enc_ctx
,
212 NDMP_DOOR_SRV_SUCCESS
);
213 ndmp_door_put_int32(enc_ctx
, status
);
218 ndmp_door_put_int32(enc_ctx
, NDMP_DOOR_SRV_SUCCESS
);
219 ndmp_door_put_uint32(enc_ctx
, ndstat
.ns_trun
);
220 ndmp_door_put_uint32(enc_ctx
, ndstat
.ns_twait
);
221 ndmp_door_put_uint32(enc_ctx
, ndstat
.ns_nbk
);
222 ndmp_door_put_uint32(enc_ctx
, ndstat
.ns_nrs
);
223 ndmp_door_put_uint32(enc_ctx
, ndstat
.ns_rfile
);
224 ndmp_door_put_uint32(enc_ctx
, ndstat
.ns_wfile
);
225 ndmp_door_put_uint64(enc_ctx
, ndstat
.ns_rdisk
);
226 ndmp_door_put_uint64(enc_ctx
, ndstat
.ns_wdisk
);
227 ndmp_door_put_uint64(enc_ctx
, ndstat
.ns_rtape
);
228 ndmp_door_put_uint64(enc_ctx
, ndstat
.ns_wtape
);
233 "ndmp_door_server: Invalid request type 0x%x", req_type
);
237 if ((dec_status
= ndmp_door_decode_finish(dec_ctx
)) != 0)
240 if ((enc_status
= ndmp_door_encode_finish(enc_ctx
, &used
)) != 0)
243 (void) door_return(buf
, used
, NULL
, 0);
248 ndmp_door_put_int32(enc_ctx
, NDMP_DOOR_SRV_ERROR
);
249 ndmp_door_put_uint32(enc_ctx
, dec_status
);
250 (void) ndmp_door_encode_finish(enc_ctx
, &used
);
251 (void) door_return(buf
, used
, NULL
, 0);
255 enc_ctx
= ndmp_door_encode_start(buf
, buflen
);
256 ndmp_door_put_int32(enc_ctx
, NDMP_DOOR_SRV_ERROR
);
257 ndmp_door_put_uint32(enc_ctx
, enc_status
);
258 (void) ndmp_door_encode_finish(enc_ctx
, &used
);
259 (void) door_return(buf
, used
, NULL
, 0);