vntsdvcc.c revision 3af08d828975d7e2581b6829e0eecff14d87a483
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * CDDL HEADER START
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * The contents of this file are subject to the terms of the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Common Development and Distribution License (the "License").
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * You may not use this file except in compliance with the License.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * See the License for the specific language governing permissions
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * and limitations under the License.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * When distributing Covered Code, include this CDDL HEADER in each
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * If applicable, add the following below this CDDL HEADER, with the
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * fields enclosed by brackets "[]" replaced with your own identifying
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * information: Portions Copyright [yyyy] [name of copyright owner]
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * CDDL HEADER END
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Use is subject to license terms.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo#pragma ident "%Z%%M% %I% %E% SMI"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Configuration and setup interface to vcc driver.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * At intialization time, vntsd opens vcc ctrl port and read initial
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * configuratioa. It manages console groups, creates the listen thread,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * dynamically adds and removes virtual console within a group.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* signal all clients that console has been deleted */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* free console structure */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * all clients connected to a console must disconnect before
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * removing a console.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1(stderr, "t@%d vntsd_disconn_clients@%d\n", thr_self(),
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* wait for all clients disconnect from the console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* signal client to disconnect the console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* wait for clients to disconnect */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) cond_reltimedwait(&consp->cvp, &consp->lock, &to);
3af08d828975d7e2581b6829e0eecff14d87a483lm /* reduce console count in the group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* search for a group whose console is being deleted */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* search for a console that is being deleted */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* delete a console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (; ; ) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* get the group contains deleted console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* no more group has console deleted */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (; ; ) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* get the console to be deleted */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* no more cons to delete */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* remove console from the group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* clean up the console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* delete group? */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* no more console delete it */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* clean up the group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* clean up a group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1(stderr, "t@%d clean_group() group=%s tcp=%lld\n", thr_self(),
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* prevent from reentry */
7636cb21f250f0485ca6052ffadc80ace93e6358lm /* signal that the listen thread is exiting */
3af08d828975d7e2581b6829e0eecff14d87a483lm vntsd_free_que(&groupp->conspq, (clean_func_t)cleanup_cons);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* walk through no cons client queue */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) cond_reltimedwait(&groupp->cvp, &groupp->lock, &to);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* listen thread is exiting */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* signal listen thread to exit */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* wait listen thread to exit */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) cond_reltimedwait(&groupp->cvp, &groupp->lock, &to);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* free group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* allocate and initialize console structure */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoalloc_cons(vntsd_group_t *groupp, vcc_console_t *consolep)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* allocate console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo consp = (vntsd_cons_t *)malloc(sizeof (vntsd_cons_t));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* intialize console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) mutex_init(&consp->lock, USYNC_THREAD|LOCK_ERRORCHECK, NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) strlcpy(consp->domain_name, consolep->domain_name, MAXPATHLEN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) strlcpy(consp->dev_name, consolep->dev_name, MAXPATHLEN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* join the group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = vntsd_que_append(&groupp->conspq, consp)) !=
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* compare tcp with group->tcp */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* allocate and initialize group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoalloc_group(vntsd_t *vntsdp, char *group_name, uint64_t tcp_port)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* allocate group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo groupp = (vntsd_group_t *)malloc(sizeof (vntsd_group_t));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* initialize group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) mutex_init(&groupp->lock, USYNC_THREAD|LOCK_ERRORCHECK, NULL);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void) memcpy(groupp->group_name, group_name, MAXPATHLEN);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1(stderr, "t@%d alloc_group@%lld:%s\n", thr_self(), groupp->tcp_port,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * Initialize a console, if console is associated with with a
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo * new group, intialize the group.
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppoalloc_cons_with_group(vntsd_t *vntsdp, vcc_console_t *consp,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* match group by tcp port */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (compare_func_t)grp_by_tcp, (void *)&(consp->tcp_port));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* group with same tcp port found */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* conflict group name */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "group name is different from existing group");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* new group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* queue group to vntsdp */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* intialize console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* no memory */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* clean up new group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* create listen thread */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1(stderr, "t@%d create_listen:%lld\n", thr_self(), groupp->tcp_port);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = thr_create(NULL, 0, (thr_func_t)vntsd_listen_thread,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "Can not create listen thread for"
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* clean up group queue */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vntsd_free_que(&groupp->conspq, (clean_func_t)free_cons);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo return (rv != 0);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* delete a console if the console exists in the vntsd */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppodelete_cons_before_add(vntsd_t *vntsdp, uint64_t tcp_port, uint_t cons_no)
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* group exists? */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo groupp = vntsd_que_find(vntsdp->grouppq, (compare_func_t)grp_by_tcp,
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo (void *)&(tcp_port));
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* no such group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* group exists, if console exists? */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* no such console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* console exists - delete console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* add a console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* get console configuration from vcc */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = vntsd_vcc_ioctl(VCC_CONS_INFO, cons_no, (void *)&console))
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* clean up the console if console was deleted and added again */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo delete_cons_before_add(vntsdp, console.tcp_port, console.cons_no);
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* initialize console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if ((rv = alloc_cons_with_group(vntsdp, &console, &groupp)) !=
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* no memory to add this new console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* new group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* create listen thread for this console */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* daemon wake up */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* reason to wake up */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vntsd_vcc_ioctl(VCC_INQUIRY, 0, (void *)&inq_data) !=
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vntsd_log(VNTSD_ERR_VCC_IOCTL, "vntsd_daemon_wakeup()");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo D1(stderr, "t@%d vntsd_daemon_wakup:msg %d port %x\n", thr_self(),
7636cb21f250f0485ca6052ffadc80ace93e6358lm /* an added port was deleted before vntsd can process it */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo/* initial console configuration */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* num of consoles */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vntsd_vcc_ioctl(VCC_NUM_CONSOLE, 0, (void *)&num_cons) !=
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo vntsd_log(VNTSD_ERR_VCC_IOCTL, "VCC_NUM_CONSOLE failed\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* allocate memory for all consoles */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* get console table */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo if (vntsd_vcc_ioctl(VCC_CONS_TBL, 0, (void *)consp) != VNTSD_SUCCESS) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo "for console table\n");
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* intialize groups and consoles */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (i = 0; i < num_cons; i++) {
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo /* create listen thread for each group */
1ae0874509b6811fdde1dfd46f0d93fd09867a3fheppo for (; ; ) {