15325 bhyve upstream sync 2023 January
[illumos-gate.git] / usr / src / cmd / vntsd / vntsd.h
blob4da0435d42f23ec7b3ea708ddc1434a9f43e1a26
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * vntsd uses configuration information provided by vcc to export access
28 * to Ldom console access over regular TCP sockets. When it starts, it opens
29 * the vcc driver control port and obtains the list of ports that have been
30 * created by the vcc driver as well as TCP port number and group associated
31 * with each port.
32 * vntsd consists of multiple components as the follows:
34 * vntsd.c
35 * This module initializes vnts daemon, process user options such as instance
36 * number, ip address and etc., and provides main thread to poll any console
37 * port change.
39 * vntsdvcc.c
40 * This module provides vcc driver interface. It opens vcc driver control
41 * ports, read initial configuration, and provides interface to read, write and
42 * ioctl virtual console ports. This module creates a listen thread for each
43 * console group. It further dynamically adds and removes virtual consoles
44 * and groups following instructions of the vcc driver. This module
45 * is executed in the same thread as vntsd.c which is blocked on vcc control
46 * poll interface.
48 * listen.c
49 * This is a group listen thread. Each group's tcp-port has a listen thread
50 * associated with it. The thread is created when a console is associated with
51 * a new group and is removed when all consoles in the group are removed.
53 * console.c
54 * This is a console selection thread. The thread is created when a client
55 * connects to a group TCP port and exited when client disconnects. If there is
56 * only one console in the group, the client is connected to that console. If
57 * there are multiple consoles in the group, the client is asked to select a
58 * console. After determining which console to connect to, this thread
59 * a write thread if the cient is a writer and it self read in client input.
61 * read.c
62 * it reads input from a TCP client, processes
63 * special daemon and telent commands and write to vcc driver if the client
64 * is a writer. The client is a writer if the client is the first one connects
65 * to the console. Read thread print out an error message if a reader attempt
66 * to input to vcc. Read thread exits if console is deleted, client
67 * disconnects, or there is a fatal error.
69 * Write.c
70 * Write thread is creaed when first client connects to a console. It reads
71 * from vcc and writes to all clients that connect to the same console.
72 * Write thread exits when all clients disconnect from the console.
74 * cmd.c
75 * This is a supporting module for handling special daemon and telnet commands.
77 * common.c
78 * supporting modules shared by threads modules.
80 * queue.c
81 * This is a moudle supporting queue operations. Vntsd organizes its data
82 * in multiple queues <see data structure below>.
84 * vntsd.xml
85 * This is a manifest to support SMF interfaces.
87 * Data structures
88 * each group has a vntsd_group_t structure, which contains a queue of
89 * all console in that group.
90 * each console has a vntsd_cons_t structure, which contains a queue of
91 * all clients that connected to the console.
93 * +----------+ +----------+ +----------+
94 * | group |-->| group |-->| group |-->....
95 * +----------+ +----------+ +----------+
96 * |
97 * |<-----------------------------------------+
98 * |<------------------------+ |
99 * |<--------+ | |
100 * | | | |
101 * | +----------+ +----------+ +----------+
102 * +----->| console |---->| console |---->| lconsole |---> ....
103 * +----------+ +----------+ +----------+
104 * | |
105 * | | +----------+ +----------+
106 * | +---->| client |----->| client |----->......
107 * | +----------+ +----------+
108 * | | |
109 * |<------------+ |
110 * |<------------------------------+
112 * Locks
113 * Each vntsd has one lock to protect the group queue
114 * Each group has one lock to protect the console queue, the queue for
115 * clients without a console connection and status.
116 * Each console has one lock to protect client queue and status.
117 * Each client has one lock to protect the state of the client. The client
118 * states are:
120 * VCC_CLIENT_READER
121 * A client is connected to a console as either a writer or a reader.
122 * if this client is the first one connects the console, the client is
123 * a writer, otherwise the client is a reader. A writer' write thread
124 * reads from vcc and send output to all readers connected to the
125 * same console. a reader's write thread is blocked until a reader becomes
126 * a writer.
128 * When a client selected a console, the client becomes a reader if
129 * there is another client connected to the console before the client.
130 * A client will be a writer if
131 * 1. client is the first one connected to the console or
132 * 2. client has entered a ~w daemon command or
133 * 3. all clients connected to the console before the client have
134 * disconnected from the console.
136 * VCC_CLIENT_MOVE_CONS_FORWARD
137 * VCC_CLIENT_MOVE_CONS_BACKWOARD
138 * A client is disconnecting from one console and move to the next or
139 * previous console in the group queue.
140 * A client is in one of these state if
141 * 1. the client has entered the daemon command and
142 * 2. the vntsd is in process of switching the client from one
143 * console to another.
145 * VCC_CLIENT_DISABLE_DAEMON_CMD
146 * vntsd is in processing of a client's daemon command or the client is
147 * in selecting console.
148 * A client is in this state if
149 * 1. the client has not selected a console or
150 * 2. the vntsd is processing a client's daemon command.
152 * VCC_CLIENT_ACQUIRE_WRITER
153 * A reader forces to become a writer via vntsd special command.
154 * A client is in this state if
155 * 1. the client is a reader and
156 * 2. client has entered a daemon command to become a writer.
158 * VCC_CLIENT_CONS_DELETED
159 * The console that the client is connected to is being deleted and
160 * waiting for the client to disconnect.
161 * A client is in this state if
162 * 1. the console a client is connected to is being removed and
163 * 2. the vntsd is in process of disconnecting the client from the console.
167 #ifndef _VNTSD_H
168 #define _VNTSD_H
170 #ifdef __cplusplus
171 extern "C" {
172 #endif
174 #include <sys/shm.h>
175 #include <strings.h>
176 #include <assert.h>
177 #include <sys/wait.h>
178 #include <sys/stat.h>
179 #include <fcntl.h>
180 #include <stropts.h>
181 #include <errno.h>
182 #include <sys/param.h>
183 #include "../../uts/sun4v/sys/vcc.h"
185 #define DEBUG
187 /* vntsd limits */
188 #define VNTSD_MAX_BUF_SIZE 128
189 #define VNTSD_LINE_LEN 100
190 #define VNTSD_MAX_SOCKETS 5
191 #define VNTSD_EOL_LEN 2
193 /* secons before re-send signal for cv_wait */
194 #define VNTSD_CV_WAIT_DELTIME 10
196 #define VCC_PATH_PREFIX \
197 "/devices/virtual-devices@100/channel-devices@200/"
198 #define VCC_DEVICE_PATH "/devices%s"
199 #define VCC_DEVICE_CTL_PATH VCC_PATH_PREFIX "%s:ctl"
201 /* common messages */
202 #define VNTSD_NO_WRITE_ACCESS_MSG "You do not have write access"
204 /* vntsd options */
205 #define VNTSD_OPT_DAEMON_OFF 0x1
206 #define VNTSD_OPT_AUTH_CHECK 0x2 /* Enable auth checking */
209 * group states
210 * When a console is removed or vntsd is exiting, main thread
211 * notifies listen, read and write thread to exit.
212 * After those threads exit, main thread clears up group structurre.
214 * VNTSD_GROUP_SIG_WAIT
215 * The main thread is waiting for listen thread to exit.
216 * VNTSD_GROUP_CLEAN_CONS
217 * There are console(s) in the group that are being removed.
218 * This is a transition state where the corresponding vcc port has been
219 * removed, but vntsd has not done its clean up yet.
220 * VNTSD_GROUP_IN_CLEANUP
221 * vntsd main thread has started cleaning up the group.
224 #define VNTSD_GROUP_SIG_WAIT 0x1
225 #define VNTSD_GROUP_CLEAN_CONS 0x2
226 #define VNTSD_GROUP_IN_CLEANUP 0x4
233 * console states
234 * There are two states when a console is removed
235 * VNTSD_CONS_DELETED
236 * the console is being deleted
237 * VNTSD_CONS_SIG_WAIT
238 * console is waiting for all clients to exit.
241 #define VNTSD_CONS_DELETED 0x1 /* deleted */
242 #define VNTSD_CONS_SIG_WAIT 0x2 /* waiting for signal */
245 #define VNTSD_CLIENT_IO_ERR 0x1 /* reader */
246 #define VNTSD_CLIENT_DISABLE_DAEMON_CMD 0x2 /* disable daemon cmd */
247 #define VNTSD_CLIENT_TIMEOUT 0x4 /* timeout */
248 #define VNTSD_CLIENT_CONS_DELETED 0x8 /* console deleted */
250 /* generic que structure */
251 typedef struct vntsd_que {
252 void *handle; /* element in queue */
253 struct vntsd_que *nextp; /* next queue element */
254 struct vntsd_que *prevp; /* previous queue element */
255 } vntsd_que_t;
257 struct vntsd_cons;
258 struct vntsd_group;
259 struct vntsd;
261 /* client structure */
262 typedef struct vntsd_client {
263 mutex_t lock; /* protect the client */
264 uint_t status; /* client's state */
266 int sockfd; /* connection socket */
267 thread_t cons_tid; /* console thread */
269 struct vntsd_cons *cons; /* back link to console configuration */
271 char prev_char; /* previous char read by this client */
273 } vntsd_client_t;
275 /* console structure */
276 typedef struct vntsd_cons {
277 mutex_t lock; /* protect console port */
278 cond_t cvp; /* sync between threads */
280 vntsd_que_t *clientpq; /* client que */
281 uint_t status; /* client's state */
282 int vcc_fd; /* vcc console port */
283 thread_t wr_tid; /* write thread */
285 uint_t cons_no; /* console port number */
286 char domain_name[MAXPATHLEN]; /* domain name */
287 char dev_name[MAXPATHLEN];
289 struct vntsd_group *group; /* back link to group */
290 } vntsd_cons_t;
292 /* group structure */
293 typedef struct vntsd_group {
294 mutex_t lock; /* protect group */
295 cond_t cvp; /* sync remove group */
297 uint_t status; /* group status */
298 char group_name[MAXPATHLEN];
299 uint64_t tcp_port; /* telnet port */
301 thread_t listen_tid; /* listen thread */
302 int sockfd; /* listen socket */
304 vntsd_que_t *conspq; /* console queue */
305 uint_t num_cons; /* num console */
307 /* clients have no console connection */
308 vntsd_que_t *no_cons_clientpq;
309 struct vntsd *vntsd;
311 } vntsd_group_t;
313 /* daemon structure */
314 typedef struct vntsd {
316 mutex_t lock; /* protect vntsd */
317 mutex_t tmo_lock; /* protect tmo queue */
319 int instance; /* vcc instance */
320 struct in_addr ip_addr; /* ip address to listen */
321 uint64_t options; /* daemon options */
322 int timeout; /* connection timeout */
324 char *devinst; /* device name */
325 int ctrl_fd; /* vcc ctrl port */
327 vntsd_que_t *grouppq; /* group queue */
328 uint_t num_grps; /* num groups */
330 vntsd_que_t *tmoq; /* timeout queue */
331 thread_t tid; /* main thread id */
333 } vntsd_t;
335 /* handle for creating thread */
336 typedef struct vntsd_thr_arg {
337 void *handle;
338 void *arg;
339 } vntsd_thr_arg_t;
341 /* timeout structure */
342 typedef struct vntsd_timeout {
343 thread_t tid; /* thread tid */
344 uint_t minutes; /* idle minutes */
345 vntsd_client_t *clientp; /* client */
346 } vntsd_timeout_t;
348 /* vntsd status and error definitions */
349 typedef enum {
351 /* status */
352 VNTSD_SUCCESS = 0, /* success */
353 VNTSD_STATUS_CONTINUE, /* continue to execute */
354 VNTSD_STATUS_EXIT_SIG, /* exit siginal */
355 VNTSD_STATUS_SIG, /* known signal */
356 VNTSD_STATUS_NO_HOST_NAME, /* no host name set */
357 VNTSD_STATUS_CLIENT_QUIT, /* client disconnected from group */
358 VNTSD_STATUS_RESELECT_CONS, /* client re-selecting console */
359 VNTSD_STATUS_VCC_IO_ERR, /* a vcc io error occurs */
360 VNTSD_STATUS_MOV_CONS_FORWARD, /* down arrow */
361 VNTSD_STATUS_MOV_CONS_BACKWARD, /* up arrow */
362 VNTSD_STATUS_ACQUIRE_WRITER, /* force become the writer */
363 VNTSD_STATUS_INTR, /* thread receive a signal */
364 VNTSD_STATUS_DISCONN_CONS, /* disconnect a client from cons */
365 VNTSD_STATUS_NO_CONS, /* disconnect a client from cons */
366 VNTSD_STATUS_AUTH_ENABLED, /* auth enabled; can't process '-p' */
368 /* resource errors */
369 VNTSD_ERR_NO_MEM, /* memory allocation error */
370 VNTSD_ERR_NO_DRV, /* cannot open vcc port */
372 /* vcc errors */
373 VNTSD_ERR_VCC_CTRL_DATA, /* vcc ctrl data error */
374 VNTSD_ERR_VCC_POLL, /* error poll vcc driver */
375 VNTSD_ERR_VCC_IOCTL, /* vcc ioctl call error */
376 VNTSD_ERR_VCC_GRP_NAME, /* group name differs from database */
377 VNTSD_ERR_ADD_CONS_FAILED, /* addition of a console failed */
379 /* create thread errors */
380 VNTSD_ERR_CREATE_LISTEN_THR, /* listen thread creation failed */
381 VNTSD_ERR_CREATE_CONS_THR, /* create console thread err */
382 VNTSD_ERR_CREATE_WR_THR, /* listen thread creation failed */
384 /* listen thread errors */
385 VNTSD_ERR_LISTEN_SOCKET, /* can not create tcp socket */
386 VNTSD_ERR_LISTEN_OPTS, /* can not set socket opt */
387 VNTSD_ERR_LISTEN_BIND, /* can not bind socket */
388 VNTSD_STATUS_ACCEPT_ERR, /* accept error */
390 /* tcp client read and write errors */
391 VNTSD_ERR_WRITE_CLIENT, /* writing tcp client err */
393 /* tcp client timeout */
394 VNTSD_ERR_CLIENT_TIMEOUT, /* client has no activity for timeout */
396 /* signal errors */
397 VNTSD_ERR_SIG, /* unknown signal */
399 /* user input error */
400 VNTSD_ERR_INVALID_INPUT, /* client typed in */
402 /* internal errors */
403 VNTSD_ERR_EL_NOT_FOUND, /* element not found */
404 VNTSD_ERR_UNKNOWN_CMD /* unknown error/cmd */
406 } vntsd_status_t;
408 /* function prototype defines */
409 typedef int (*compare_func_t)(void *el, void *data);
410 typedef int (*el_func_t)(void *el);
411 typedef void (*clean_func_t)(void *el);
412 typedef void (*sig_handler_t)(int sig);
413 typedef void *(*thr_func_t)(void *);
417 /* function prototype */
418 void vntsd_log(vntsd_status_t err, char *msg);
419 struct in_addr vntsd_ip_addr(void);
421 void vntsd_get_config(vntsd_t *vntsdp);
422 void vntsd_daemon_wakeup(vntsd_t *vntsdp);
423 int vntsd_open_vcc(char *domain_name, uint_t cons_no);
424 void vntsd_delete_cons(vntsd_t *vntsdp);
425 void vntsd_clean_group(vntsd_group_t *groupp);
428 void *vntsd_listen_thread(vntsd_group_t *groupp);
429 void *vntsd_console_thread(vntsd_thr_arg_t *argp);
430 int vntsd_read(vntsd_client_t *clientp);
431 void *vntsd_write_thread(vntsd_cons_t *consp);
433 boolean_t vntsd_cons_by_consno(vntsd_cons_t *consp, int *cons_id);
435 int vntsd_que_append(vntsd_que_t **que_hd, void *handle);
436 int vntsd_que_rm(vntsd_que_t **que_hd, void *handle);
437 void *vntsd_que_find(vntsd_que_t *que_hd, compare_func_t
438 compare_func, void *data);
439 void *vntsd_que_walk(vntsd_que_t *que_hd, el_func_t el_func);
441 int vntsd_que_insert_after(vntsd_que_t *que, void *handle,
442 void *next);
443 void *vntsd_que_pos(vntsd_que_t *que_hd, void *handle, int pos);
444 void vntsd_free_que(vntsd_que_t **q, clean_func_t clean_func);
446 int vntsd_read_char(vntsd_client_t *clientp, char *c);
447 int vntsd_read_line(vntsd_client_t *clientp, char *buf, int *size);
448 int vntsd_read_data(vntsd_client_t *clientp, char *c);
449 int vntsd_get_yes_no(vntsd_client_t *clientp, char *msg,
450 int *yes_no);
451 int vntsd_ctrl_cmd(vntsd_client_t *clientp, char c);
452 int vntsd_process_daemon_cmd(vntsd_client_t *clientp, char c);
453 int vntsd_telnet_cmd(vntsd_client_t *clientp, char c);
455 int vntsd_set_telnet_options(int fd);
456 int vntsd_write_client(vntsd_client_t *client, char *buffer,
457 size_t sz);
458 int vntsd_write_fd(int fd, void *buffer, size_t sz);
459 int vntsd_write_line(vntsd_client_t *clientp, char *line);
460 int vntsd_write_lines(vntsd_client_t *clientp, char *lines);
461 extern char vntsd_eol[];
463 void vntsd_clean_group(vntsd_group_t *portp);
464 void vntsd_free_client(vntsd_client_t *clientp);
465 int vntsd_attach_timer(vntsd_timeout_t *tmop);
466 int vntsd_detach_timer(vntsd_timeout_t *tmop);
467 void vntsd_reset_timer(thread_t tid);
468 void vntsd_init_esctable_msgs(void);
469 int vntsd_vcc_ioctl(int ioctl_code, uint_t portno, void *buf);
470 int vntsd_vcc_err(vntsd_cons_t *consp);
471 int vntsd_cons_chk_intr(vntsd_client_t *clientp);
472 boolean_t vntsd_vcc_cons_alive(vntsd_cons_t *consp);
473 boolean_t vntsd_notify_client_cons_del(vntsd_client_t *clientp);
474 int vntsd_chk_group_total_cons(vntsd_group_t *groupp);
475 boolean_t vntsd_mark_deleted_cons(vntsd_cons_t *consp);
476 boolean_t auth_check_fd(int sock_fd, char *group_name);
478 #ifdef DEBUG
480 extern int vntsddbg;
482 #define D1 if (vntsddbg & 0x01) (void) fprintf
483 #define D2 if (vntsddbg & 0x02) (void) fprintf
484 #define D3 if (vntsddbg & 0x04) (void) fprintf
485 #define DERR if (vntsddbg & 0x08) (void) fprintf
487 #else /* not DEBUG */
489 #define D1
490 #define D2
491 #define D3
492 #define DERR
494 #endif /* not DEBUG */
496 #ifdef __cplusplus
498 #endif
500 #endif /* _VNTSD_H */