19 * the documentation and/or other materials provided with the
20 * distribution.
21 *
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
25 * permission.
26 *
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.
38 */
39
40 /* This file contains all the door server code */
41
42 #include <door.h>
43 #include <alloca.h>
44 #include <errno.h>
45 #include <note.h>
46 #include <libintl.h>
47 #include <ndmpd_door.h>
48 #include "ndmpd.h"
49
50 /* static variables */
51 static int ndmp_door_fildes = -1;
52 static mutex_t ndmp_doorsrv_mutex;
53
54 /* static routines */
55 static void ndmp_door_server(void *cookie, char *ptr, size_t size,
56 door_desc_t *dp, uint_t n_desc);
57
58 /*
59 * Statistics used in ndmpstat command
60 */
61 ndmp_stat_t ndstat;
62
63 int
64 ndmp_door_init(void)
65 {
66 int fd;
67
68 (void) mutex_lock(&ndmp_doorsrv_mutex);
69
70 if (ndmp_door_fildes != -1) {
71 NDMP_LOG(LOG_DEBUG,
72 "ndmp_door_init: ndmpd service is already running.");
73 (void) mutex_unlock(&ndmp_doorsrv_mutex);
74 return (0);
75 }
76
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);
81 return (-1);
82 }
83
84 (void) unlink(NDMP_DOOR_SVC);
85
86 if ((fd = creat(NDMP_DOOR_SVC, 0444)) < 0) {
87 NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Can't create %s: %m.",
88 NDMP_DOOR_SVC);
89 (void) door_revoke(ndmp_door_fildes);
90 ndmp_door_fildes = -1;
91 (void) mutex_unlock(&ndmp_doorsrv_mutex);
92 return (-1);
93 }
94
95 (void) close(fd);
96 (void) fdetach(NDMP_DOOR_SVC);
97
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);
103 return (-1);
104 }
105
106 NDMP_LOG(LOG_DEBUG, "ndmp_door_init: Door server successfully started");
107 (void) mutex_unlock(&ndmp_doorsrv_mutex);
108 return (0);
109 }
110
111 void
112 ndmp_door_fini(void)
113 {
114 (void) mutex_lock(&ndmp_doorsrv_mutex);
115
116 if (ndmp_door_fildes != -1) {
117 (void) fdetach(NDMP_DOOR_SVC);
118 (void) door_revoke(ndmp_door_fildes);
119 ndmp_door_fildes = -1;
120 }
121
122 (void) mutex_unlock(&ndmp_doorsrv_mutex);
123 }
124
125 boolean_t
126 ndmp_door_check(void)
127 {
128 door_info_t info;
129 int door;
130
131 if ((door = open(NDMP_DOOR_SVC, O_RDONLY)) < 0)
132 return (0);
133
134 if (door_info(door, &info) < 0) {
135 (void) close(door);
136 return (0);
137 }
138
139 if (info.di_target > 0) {
140 NDMP_LOG(LOG_ERR,
141 "Service already running: pid %ld", info.di_target);
142 (void) close(door);
143 return (1);
144 }
145
146 (void) close(door);
147 return (0);
148 }
149
150 /* door server */
151 /*ARGSUSED*/
152 void
153 ndmp_door_server(void *cookie, char *ptr, size_t size,
154 door_desc_t *dp, uint_t n_desc)
155 {
156 NOTE(ARGUNUSED(cookie,dp,n_desc))
157 int req_type;
158 char *buf;
159 int buflen;
160 unsigned int used;
161 ndmp_door_ctx_t *dec_ctx;
162 ndmp_door_ctx_t *enc_ctx;
163 unsigned int dec_status;
164 unsigned int enc_status;
165
166 dec_ctx = ndmp_door_decode_start(ptr, size);
167 if (dec_ctx == 0)
168 return;
169
170 req_type = ndmp_door_get_uint32(dec_ctx);
171 buflen = NDMP_DOOR_SIZE;
172
173 if ((buf = alloca(buflen)) == NULL) {
174 NDMP_LOG(LOG_DEBUG, "Out of memory.");
175 (void) ndmp_door_decode_finish(dec_ctx);
176 return;
177 }
178
179 enc_ctx = ndmp_door_encode_start(buf, buflen);
180 if (enc_ctx == 0) {
181 (void) ndmp_door_decode_finish(dec_ctx);
182 return;
183 }
184
185 if (req_type != NDMP_GET_STAT)
186 NDMP_LOG(LOG_DEBUG, "ndmp_door_server: req_type=%d", req_type);
187
188 switch (req_type) {
189 case NDMP_GET_DOOR_STATUS: {
190 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
191 break;
192 }
193 case NDMP_DEVICES_GET_INFO: {
194 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
195 ndmpd_get_devs(enc_ctx);
196 break;
197 }
198 case NDMP_SHOW: {
199 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
200 ndmp_connect_list_get(enc_ctx);
201 break;
202 }
203 case NDMP_TERMINATE_SESSION_ID: {
204 int status, id;
205 id = ndmp_door_get_int32(dec_ctx);
206 status = ndmpd_connect_kill_id(id);
212 NDMP_DOOR_SRV_SUCCESS);
213 ndmp_door_put_int32(enc_ctx, status);
214 break;
215 }
216
217 case NDMP_GET_STAT:
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);
229 break;
230
231 default:
232 NDMP_LOG(LOG_DEBUG,
233 "ndmp_door_server: Invalid request type 0x%x", req_type);
234 goto decode_error;
235 }
236
237 if ((dec_status = ndmp_door_decode_finish(dec_ctx)) != 0)
238 goto decode_error;
239
240 if ((enc_status = ndmp_door_encode_finish(enc_ctx, &used)) != 0)
241 goto encode_error;
242
243 (void) door_return(buf, used, NULL, 0);
244
245 return;
246
247 decode_error:
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);
252 return;
|
19 * the documentation and/or other materials provided with the
20 * distribution.
21 *
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
25 * permission.
26 *
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.
38 */
39 /* Copyright 2017 Nexenta Systems, Inc. All rights reserved. */
40
41 /* This file contains all the door server code */
42
43 #include <syslog.h>
44 #include <door.h>
45 #include <alloca.h>
46 #include <errno.h>
47 #include <note.h>
48 #include <libintl.h>
49 #include <ndmpd_door.h>
50 #include "ndmpd.h"
51
52 /* static variables */
53 static int ndmp_door_fildes = -1;
54 static mutex_t ndmp_doorsrv_mutex;
55
56 /* static routines */
57 static void ndmp_door_server(void *cookie, char *ptr, size_t size,
58 door_desc_t *dp, uint_t n_desc);
59
60 /*
61 * Statistics used in ndmpstat command
62 */
63 ndmp_stat_t ndstat;
64
65 int
66 ndmp_door_init(void)
67 {
68 int fd;
69
70 (void) mutex_lock(&ndmp_doorsrv_mutex);
71
72 if (ndmp_door_fildes != -1) {
73 syslog(LOG_ERR,
74 "ndmp_door_init: ndmpd service is already running.");
75 (void) mutex_unlock(&ndmp_doorsrv_mutex);
76 return (0);
77 }
78
79 if ((ndmp_door_fildes = door_create(ndmp_door_server,
80 NULL, DOOR_UNREF)) < 0) {
81 syslog(LOG_ERR, "ndmp_door_init: Could not create door.");
82 (void) mutex_unlock(&ndmp_doorsrv_mutex);
83 return (-1);
84 }
85
86 (void) unlink(NDMP_DOOR_SVC);
87
88 if ((fd = creat(NDMP_DOOR_SVC, 0444)) < 0) {
89 syslog(LOG_ERR, "ndmp_door_init: Can't create %s: %m.",
90 NDMP_DOOR_SVC);
91 (void) door_revoke(ndmp_door_fildes);
92 ndmp_door_fildes = -1;
93 (void) mutex_unlock(&ndmp_doorsrv_mutex);
94 return (-1);
95 }
96
97 (void) close(fd);
98 (void) fdetach(NDMP_DOOR_SVC);
99
100 if (fattach(ndmp_door_fildes, NDMP_DOOR_SVC) < 0) {
101 syslog(LOG_ERR, "ndmp_door_init: fattach failed %m");
102 (void) door_revoke(ndmp_door_fildes);
103 ndmp_door_fildes = -1;
104 (void) mutex_unlock(&ndmp_doorsrv_mutex);
105 return (-1);
106 }
107
108 syslog(LOG_DEBUG, "ndmp_door_init: Door server successfully started");
109 (void) mutex_unlock(&ndmp_doorsrv_mutex);
110 return (0);
111 }
112
113 void
114 ndmp_door_fini(void)
115 {
116 (void) mutex_lock(&ndmp_doorsrv_mutex);
117
118 if (ndmp_door_fildes != -1) {
119 (void) fdetach(NDMP_DOOR_SVC);
120 (void) door_revoke(ndmp_door_fildes);
121 ndmp_door_fildes = -1;
122 }
123
124 (void) mutex_unlock(&ndmp_doorsrv_mutex);
125 }
126
127 boolean_t
128 ndmp_door_check(void)
129 {
130 door_info_t info;
131 int door;
132
133 if ((door = open(NDMP_DOOR_SVC, O_RDONLY)) < 0)
134 return (0);
135
136 if (door_info(door, &info) < 0) {
137 (void) close(door);
138 return (0);
139 }
140
141 if (info.di_target > 0) {
142 syslog(LOG_ERR,
143 "Service already running: pid %ld", info.di_target);
144 (void) close(door);
145 return (1);
146 }
147
148 (void) close(door);
149 return (0);
150 }
151
152 /* door server */
153 /*ARGSUSED*/
154 void
155 ndmp_door_server(void *cookie, char *ptr, size_t size,
156 door_desc_t *dp, uint_t n_desc)
157 {
158 NOTE(ARGUNUSED(cookie,dp,n_desc))
159 int req_type;
160 char *buf;
161 int buflen;
162 unsigned int used;
163 ndmp_door_ctx_t *dec_ctx;
164 ndmp_door_ctx_t *enc_ctx;
165 unsigned int dec_status = EINVAL;
166 unsigned int enc_status = EINVAL;
167
168 dec_ctx = ndmp_door_decode_start(ptr, size);
169 if (dec_ctx == 0)
170 return;
171
172 req_type = ndmp_door_get_uint32(dec_ctx);
173 buflen = NDMP_DOOR_SIZE;
174
175 if ((buf = alloca(buflen)) == NULL) {
176 syslog(LOG_ERR, "Out of memory.");
177 (void) ndmp_door_decode_finish(dec_ctx);
178 return;
179 }
180
181 enc_ctx = ndmp_door_encode_start(buf, buflen);
182 if (enc_ctx == 0) {
183 (void) ndmp_door_decode_finish(dec_ctx);
184 return;
185 }
186
187 if (req_type != NDMP_GET_STAT)
188 syslog(LOG_DEBUG, "ndmp_door_server: req_type=%d", req_type);
189
190 switch (req_type) {
191 case NDMP_GET_DOOR_STATUS: {
192 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
193 break;
194 }
195 case NDMP_DEVICES_GET_INFO: {
196 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
197 ndmpd_get_devs(enc_ctx);
198 break;
199 }
200 case NDMP_SHOW: {
201 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
202 ndmp_connect_list_get(enc_ctx);
203 break;
204 }
205 case NDMP_TERMINATE_SESSION_ID: {
206 int status, id;
207 id = ndmp_door_get_int32(dec_ctx);
208 status = ndmpd_connect_kill_id(id);
214 NDMP_DOOR_SRV_SUCCESS);
215 ndmp_door_put_int32(enc_ctx, status);
216 break;
217 }
218
219 case NDMP_GET_STAT:
220 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_SUCCESS);
221 ndmp_door_put_uint32(enc_ctx, ndstat.ns_trun);
222 ndmp_door_put_uint32(enc_ctx, ndstat.ns_twait);
223 ndmp_door_put_uint32(enc_ctx, ndstat.ns_nbk);
224 ndmp_door_put_uint32(enc_ctx, ndstat.ns_nrs);
225 ndmp_door_put_uint32(enc_ctx, ndstat.ns_rfile);
226 ndmp_door_put_uint32(enc_ctx, ndstat.ns_wfile);
227 ndmp_door_put_uint64(enc_ctx, ndstat.ns_rdisk);
228 ndmp_door_put_uint64(enc_ctx, ndstat.ns_wdisk);
229 ndmp_door_put_uint64(enc_ctx, ndstat.ns_rtape);
230 ndmp_door_put_uint64(enc_ctx, ndstat.ns_wtape);
231 break;
232
233 default:
234 syslog(LOG_ERR,
235 "ndmp_door_server: Invalid request type 0x%x", req_type);
236 goto decode_error;
237 }
238
239 if ((dec_status = ndmp_door_decode_finish(dec_ctx)) != 0)
240 goto decode_error;
241
242 if ((enc_status = ndmp_door_encode_finish(enc_ctx, &used)) != 0)
243 goto encode_error;
244
245 (void) door_return(buf, used, NULL, 0);
246
247 return;
248
249 decode_error:
250 ndmp_door_put_int32(enc_ctx, NDMP_DOOR_SRV_ERROR);
251 ndmp_door_put_uint32(enc_ctx, dec_status);
252 (void) ndmp_door_encode_finish(enc_ctx, &used);
253 (void) door_return(buf, used, NULL, 0);
254 return;
|