Пример #1
0
/* delete a console */
void
vntsd_delete_cons(vntsd_t *vntsdp)
{
	vntsd_group_t *groupp;
	vntsd_cons_t *consp;

	for (; ; ) {
		/* get the group contains deleted console */
		(void) mutex_lock(&vntsdp->lock);
		groupp = vntsd_que_walk(vntsdp->grouppq,
		    (el_func_t)find_clean_cons_group);
		if (groupp == NULL) {
			/* no more group has console deleted */
			(void) mutex_unlock(&vntsdp->lock);
			return;
		}
		groupp->status &= ~VNTSD_GROUP_CLEAN_CONS;
		(void) mutex_unlock(&vntsdp->lock);

		for (; ; ) {
			/* get the console to be deleted */
			(void) mutex_lock(&groupp->lock);
			assert(groupp->conspq);
			consp = vntsd_que_walk(groupp->conspq,
			    (el_func_t)find_clean_cons);
			if (consp == NULL) {
				/* no more cons to delete */
				(void) mutex_unlock(&groupp->lock);
				break;
			}

			/* remove console from the group */
			(void) vntsd_que_rm(&groupp->conspq, consp);
			groupp->num_cons--;
			(void) mutex_unlock(&groupp->lock);

			/* clean up the console */
			cleanup_cons(consp);

			/* delete group? */
			if (groupp->num_cons == 0) {
				/* no more console delete it */
				assert(groupp->vntsd);

				(void) mutex_lock(&groupp->vntsd->lock);
				(void) vntsd_que_rm(&groupp->vntsd->grouppq,
						    groupp);
				(void) mutex_unlock(&groupp->vntsd->lock);

				/* clean up the group */
				vntsd_clean_group(groupp);
				break;
			}
		}
	}
}
Пример #2
0
/*
 * acquire_writer() the client is going to be writer.
 * insert the client to the head of the console client queue.
 */
static int
acquire_writer(vntsd_client_t *clientp)
{
	vntsd_cons_t	    *consp;
	vntsd_client_t	    *writerp;
	int		    rv;

	D1(stderr, "t@%d:acuire_writer :client@%d\n", thr_self(),
	    clientp->sockfd);

	assert(clientp != NULL);
	consp = clientp->cons;

	assert(consp);

	(void) mutex_lock(&consp->lock);

	assert(consp->clientpq != NULL);
	if (consp->clientpq->handle == clientp) {
		/* clientp is a writer already */
		(void) mutex_unlock(&consp->lock);
		return (VNTSD_SUCCESS);
	}

	/* current writer */
	writerp = (vntsd_client_t *)(consp->clientpq->handle);

	(void) mutex_lock(&writerp->lock);

	rv = vntsd_que_rm(&(consp->clientpq), clientp);
	assert(rv == VNTSD_SUCCESS);

	(void) mutex_lock(&clientp->lock);

	/* move client to be first in the console queue */
	consp->clientpq->handle = clientp;

	/* move previous writer to be the second in the queue */
	rv =  vntsd_que_insert_after(consp->clientpq, clientp, writerp);

	(void) mutex_unlock(&consp->lock);
	(void) mutex_unlock(&writerp->lock);
	(void) mutex_unlock(&clientp->lock);

	if (rv != VNTSD_SUCCESS) {
		return (rv);
	}

	/* write warning message to the writer */

	if ((rv = vntsd_write_line(writerp,
	    gettext("Warning: Console connection forced into read-only mode")))
	    != VNTSD_SUCCESS) {
		return (rv);
	}

	return (VNTSD_SUCCESS);
}
Пример #3
0
/* clean up a group */
void
vntsd_clean_group(vntsd_group_t *groupp)
{

	timestruc_t	to;

	D1(stderr, "t@%d clean_group() group=%s tcp=%lld\n", thr_self(),
	    groupp->group_name, groupp->tcp_port);

	(void) mutex_lock(&groupp->lock);

	/* prevent from reentry */
	if (groupp->status & VNTSD_GROUP_CLEANUP) {
		(void) mutex_unlock(&groupp->lock);
		return;
	}
	groupp->status |= VNTSD_GROUP_CLEANUP;
	vntsd_free_que(&groupp->conspq, (clean_func_t)cleanup_cons);
	(void) mutex_unlock(&groupp->lock);

	/* walk through no cons client queue */
	while (groupp->no_cons_clientpq != NULL) {
		groupp->status |= VNTSD_GROUP_SIG_WAIT;
		(void) vntsd_que_walk(groupp->no_cons_clientpq,
		    (el_func_t)vntsd_notify_client_cons_del);
		to.tv_sec = VNTSD_CV_WAIT_DELTIME;
		to.tv_nsec = 0;
		(void) cond_reltimedwait(&groupp->cvp, &groupp->lock, &to);
	}

	if (groupp->listen_tid == thr_self()) {
		/* listen thread is exiting */
		(void) mutex_lock(&(groupp->vntsd->lock));
		(void) vntsd_que_rm(&groupp->vntsd->grouppq, groupp);
		(void) mutex_unlock(&groupp->vntsd->lock);

		(void) cond_destroy(&groupp->cvp);
		(void) mutex_unlock(&groupp->lock);
		(void) mutex_destroy(&groupp->lock);
		free(groupp);
		return;
	}

	/* signal listen thread to exit  */
	groupp->status |= VNTSD_GROUP_SIG_WAIT;

	while (groupp->status & VNTSD_GROUP_SIG_WAIT) {
		(void) thr_kill(groupp->listen_tid, SIGUSR1);
		to.tv_sec = VNTSD_CV_WAIT_DELTIME;
		to.tv_nsec = 0;
		/* wait listen thread to exit  */
		(void) cond_reltimedwait(&groupp->cvp, &groupp->lock, &to);
	}

	(void) mutex_unlock(&groupp->lock);
	(void) thr_join(groupp->listen_tid, NULL, NULL);
	/* free group */
	(void) cond_destroy(&groupp->cvp);
	(void) mutex_destroy(&groupp->lock);
	free(groupp);
}
Пример #4
0
/* ceate console selection thread */
static int
create_console_thread(vntsd_group_t *groupp, int sockfd)
{
	vntsd_client_t	    *clientp;
	vntsd_thr_arg_t	    *thr_arg;
	int		    rv;


	assert(groupp);
	D1(stderr, "t@%d create_console_thread@%lld:client@%d\n", thr_self(),
	    groupp->tcp_port, sockfd);

	/* allocate a new client */
	clientp = (vntsd_client_t *)malloc(sizeof (vntsd_client_t));
	if (clientp  == NULL) {
		return (VNTSD_ERR_NO_MEM);
	}

	/* initialize the client */
	bzero(clientp, sizeof (vntsd_client_t));

	clientp->sockfd = sockfd;
	clientp->cons_tid = (thread_t)-1;

	(void) mutex_init(&clientp->lock, USYNC_THREAD|LOCK_ERRORCHECK, NULL);

	/* append client to group */
	(void) mutex_lock(&groupp->lock);

	/* check if the group is [being] removed */
	if (groupp->status & VNTSD_GROUP_IN_CLEANUP) {
		(void) mutex_unlock(&groupp->lock);
		vntsd_free_client(clientp);
		return (VNTSD_STATUS_NO_CONS);
	}


	if ((rv = vntsd_que_append(&groupp->no_cons_clientpq, clientp))
	    != VNTSD_SUCCESS) {
		(void) mutex_unlock(&groupp->lock);
		vntsd_free_client(clientp);
		return (rv);
	}

	(void) mutex_unlock(&groupp->lock);

	/*
	 * allocate thr_arg from heap for console thread so
	 * that thr_arg is still valid after this function exits.
	 * console thread will free thr_arg.
	 */

	thr_arg = (vntsd_thr_arg_t *)malloc(sizeof (vntsd_thr_arg_t));
	if (thr_arg  == NULL) {
		vntsd_free_client(clientp);
		return (VNTSD_ERR_NO_MEM);
	}
	thr_arg->handle = groupp;
	thr_arg->arg = clientp;

	(void) mutex_lock(&clientp->lock);


	/* create console selection thread */
	if (thr_create(NULL, 0, (thr_func_t)vntsd_console_thread,
	    thr_arg, THR_DETACHED, &clientp->cons_tid)) {

		free(thr_arg);
		(void) mutex_unlock(&clientp->lock);
		(void) mutex_lock(&groupp->lock);
		(void) vntsd_que_rm(&groupp->no_cons_clientpq, clientp);
		(void) mutex_unlock(&groupp->lock);
		vntsd_free_client(clientp);

		return (VNTSD_ERR_CREATE_CONS_THR);
	}

	(void) mutex_unlock(&clientp->lock);

	return (VNTSD_SUCCESS);
}