Beispiel #1
0
/* daemon wake up */
void
vntsd_daemon_wakeup(vntsd_t *vntsdp)
{

	vcc_response_t	inq_data;

	/* reason to wake up  */
	if (vntsd_vcc_ioctl(VCC_INQUIRY, 0, (void *)&inq_data) !=
	    VNTSD_SUCCESS) {
		vntsd_log(VNTSD_ERR_VCC_IOCTL, "vntsd_daemon_wakeup()");
		return;
	}

	D1(stderr, "t@%d vntsd_daemon_wakup:msg %d port %x\n", thr_self(),
	    inq_data.reason, inq_data.cons_no);

	switch (inq_data.reason) {

	case VCC_CONS_ADDED:
		do_add_cons(vntsdp, inq_data.cons_no);
		break;

	default:
		DERR(stderr, "t@%d daemon_wakeup:ioctl_unknown %d\n",
		    thr_self(), inq_data.reason);
		vntsd_log(VNTSD_ERR_UNKNOWN_CMD, "from vcc\n");
		break;
	}
}
Beispiel #2
0
/* create listen thread */
static boolean_t
create_listen_thread(vntsd_group_t *groupp)
{

	char err_msg[VNTSD_LINE_LEN];
	int rv;

	assert(groupp);

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

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

	if ((rv = thr_create(NULL, 0, (thr_func_t)vntsd_listen_thread,
			    (void *)groupp, THR_DETACHED, &groupp->listen_tid))
	    != 0) {
		(void) (void) snprintf(err_msg, sizeof (err_msg),
		    "Can not create listen thread for"
		    "group %s tcp %llx\n", groupp->group_name,
		    groupp->tcp_port);
		vntsd_log(VNTSD_ERR_CREATE_LISTEN_THR, err_msg);

		/* clean up group queue */
		vntsd_free_que(&groupp->conspq, (clean_func_t)free_cons);
		groupp->listen_tid = (thread_t)-1;
	}

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

	return (rv != 0);
}
Beispiel #3
0
/* allocate and initialize group */
static vntsd_group_t *
alloc_group(vntsd_t *vntsdp, char *group_name, uint64_t tcp_port)
{
	vntsd_group_t *groupp;

	/* allocate group */
	groupp = (vntsd_group_t *)malloc(sizeof (vntsd_group_t));
	if (groupp == NULL) {
		vntsd_log(VNTSD_ERR_NO_MEM, "alloc_group");
		return (NULL);
	}

	/* initialize group */
	bzero(groupp, sizeof (vntsd_group_t));

	(void) mutex_init(&groupp->lock, USYNC_THREAD|LOCK_ERRORCHECK, NULL);
	(void) cond_init(&groupp->cvp, USYNC_THREAD, NULL);

	if (group_name != NULL) {
		(void) memcpy(groupp->group_name, group_name, MAXPATHLEN);
	}

	groupp->tcp_port = tcp_port;
	groupp->listen_tid = (thread_t)-1;
	groupp->sockfd = (thread_t)-1;
	groupp->vntsd = vntsdp;

	D1(stderr, "t@%d alloc_group@%lld:%s\n", thr_self(), groupp->tcp_port,
	    groupp->group_name);

	return (groupp);
}
Beispiel #4
0
/* allocate and initialize console structure */
static vntsd_cons_t *
alloc_cons(vntsd_group_t *groupp, vcc_console_t *consolep)
{
	vntsd_cons_t *consp;
	int	rv;

	/* allocate console */
	consp = (vntsd_cons_t *)malloc(sizeof (vntsd_cons_t));
	if (consp == NULL) {
		vntsd_log(VNTSD_ERR_NO_MEM, "alloc_cons");
		return (NULL);
	}

	/* intialize console */
	bzero(consp, sizeof (vntsd_cons_t));

	(void) mutex_init(&consp->lock, USYNC_THREAD|LOCK_ERRORCHECK, NULL);
	(void) cond_init(&consp->cvp, USYNC_THREAD, NULL);

	consp->cons_no = consolep->cons_no;
	(void) strlcpy(consp->domain_name, consolep->domain_name, MAXPATHLEN);
	(void) strlcpy(consp->dev_name, consolep->dev_name, MAXPATHLEN);
	consp->wr_tid = (thread_t)-1;
	consp->vcc_fd = (thread_t)-1;

	/* join the group */
	(void) mutex_lock(&groupp->lock);

	if ((rv = vntsd_que_append(&groupp->conspq, consp)) !=
	    VNTSD_SUCCESS) {
		(void) mutex_unlock(&groupp->lock);
		vntsd_log(rv, "alloc_cons");
		free_cons(consp);
		return (NULL);
	}
	groupp->num_cons++;
	consp->group = groupp;

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

	D1(stderr, "t@%d alloc_cons@%d %s %s\n", thr_self(),
	    consp->cons_no, consp->domain_name, consp->dev_name);

	return (consp);
}
Beispiel #5
0
/* add a console */
static void
do_add_cons(vntsd_t *vntsdp, int cons_no)
{
	vcc_console_t	console;
	vntsd_group_t	*groupp;
	int		rv;
	char		err_msg[VNTSD_LINE_LEN];


	(void) snprintf(err_msg, sizeof (err_msg),
	    "do_add_cons():Can not add console=%d", cons_no);

	/* get console configuration from vcc */

	if ((rv = vntsd_vcc_ioctl(VCC_CONS_INFO, cons_no, (void *)&console))
	    != VNTSD_SUCCESS) {
		vntsd_log(rv, err_msg);
		return;
	}

	/* clean up the console if console was deleted and added again */
	delete_cons_before_add(vntsdp, console.tcp_port, console.cons_no);

	/* initialize console */

	if ((rv = alloc_cons_with_group(vntsdp, &console, &groupp)) !=
	    VNTSD_SUCCESS) {
		/* no memory to add this new console */
		vntsd_log(rv, err_msg);
		return;
	}

	if (groupp != NULL) {
		/* new group */
		/* create listen thread for this console */
		if (create_listen_thread(groupp)) {
			vntsd_log(VNTSD_ERR_CREATE_LISTEN_THR, err_msg);
			(void) cond_destroy(&groupp->cvp);
			(void) mutex_destroy(&groupp->lock);
			free(groupp);
		}

	}
}
Beispiel #6
0
/* initial console configuration */
void
vntsd_get_config(vntsd_t *vntsdp)
{

	int		i;
	int		num_cons;
	vcc_console_t	*consp;
	vntsd_group_t	*groupp;

	/* num of consoles */
	num_cons = 0;

	if (vntsd_vcc_ioctl(VCC_NUM_CONSOLE, 0, (void *)&num_cons) !=
	    VNTSD_SUCCESS) {
		vntsd_log(VNTSD_ERR_VCC_IOCTL, "VCC_NUM_CONSOLE failed\n");
		return;
	}

	D3(stderr, "get_config:num_cons=%d", num_cons);

	if (num_cons == 0) {
		return;
	}

	/* allocate memory for all consoles */
	consp = malloc(num_cons*sizeof (vcc_console_t));

	if (consp == NULL) {
		vntsd_log(VNTSD_ERR_NO_MEM, "for console table.");
		return;
	}

	/* get console table */
	if (vntsd_vcc_ioctl(VCC_CONS_TBL, 0, (void *)consp) != VNTSD_SUCCESS) {
		vntsd_log(VNTSD_ERR_VCC_IOCTL, " VCC_CONS_TBL "
		    "for console table\n");
		return;
	}

	/* intialize groups and consoles  */
	for (i = 0; i < num_cons; i++) {
		if (alloc_cons_with_group(vntsdp, &consp[i], &groupp)
		    != VNTSD_SUCCESS) {
			vntsd_log(VNTSD_ERR_ADD_CONS_FAILED, "get_config");
		}
	}

	/* create listen thread for each group */
	(void) mutex_lock(&vntsdp->lock);

	for (; ; ) {
		groupp = vntsd_que_walk(vntsdp->grouppq,
		    (el_func_t)create_listen_thread);
		if (groupp == NULL) {
			break;
		}
		vntsd_log(VNTSD_ERR_CREATE_LISTEN_THR, "get config()");
	}

	(void) mutex_unlock(&vntsdp->lock);
}
Beispiel #7
0
/*
 * Initialize a console, if console is associated with with a
 * new group, intialize the group.
 */
static int
alloc_cons_with_group(vntsd_t *vntsdp, vcc_console_t *consp,
    vntsd_group_t **new_groupp)
{
	vntsd_group_t	*groupp = NULL;
	int		rv;

	*new_groupp = NULL;

	/* match group by tcp port */


	(void) mutex_lock(&vntsdp->lock);
	groupp = vntsd_que_find(vntsdp->grouppq,
	    (compare_func_t)grp_by_tcp, (void *)&(consp->tcp_port));
	(void) mutex_unlock(&vntsdp->lock);

	if (groupp != NULL) {
		/* group with same tcp port found */

		if (strcmp(groupp->group_name, consp->group_name)) {
			/* conflict group name */
			vntsd_log(VNTSD_ERR_VCC_GRP_NAME,
			    "group name is different from existing group");
			return (VNTSD_ERR_VCC_CTRL_DATA);
		}

	} else {
		/* new group */
		groupp = alloc_group(vntsdp, consp->group_name,
		    consp->tcp_port);
		if (groupp == NULL) {
			return (VNTSD_ERR_NO_MEM);
		}

		assert(groupp->conspq == NULL);
		/* queue group to vntsdp */
		(void) mutex_lock(&vntsdp->lock);
		rv = vntsd_que_append(&vntsdp->grouppq, groupp);
		(void) mutex_unlock(&vntsdp->lock);

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

		*new_groupp = groupp;
	}

	/* intialize console */
	if (alloc_cons(groupp, consp) == NULL) {
		/* no memory */
		if (new_groupp != NULL) {
			/* clean up new group */
			(void) cond_destroy(&groupp->cvp);
			(void) mutex_destroy(&groupp->lock);
			free(groupp);
		}

		return (VNTSD_ERR_NO_MEM);
	}

	return (VNTSD_SUCCESS);

}
Beispiel #8
0
/*
 * check the state of listen thread. exit if there is an fatal error
 * or the group is removed. Main thread will call free_group
 * to close group socket and free group structure.
 */
static void
listen_chk_status(vntsd_group_t *groupp, int status)
{
	char	    err_msg[VNTSD_LINE_LEN];


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

	(void) snprintf(err_msg, sizeof (err_msg),
	    "Group:%s TCP port %lld status %x",
	    groupp->group_name, groupp->tcp_port, groupp->status);


	switch (status) {

	case VNTSD_SUCCESS:
		return;


	case VNTSD_STATUS_ACCEPT_ERR:
		return;

	case VNTSD_STATUS_INTR:
		assert(groupp->status & VNTSD_GROUP_SIG_WAIT);
		/*FALLTHRU*/
	case VNTSD_STATUS_NO_CONS:
	default:
		/* fatal error or no console in the group, remove the group. */

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

		if (groupp->status & VNTSD_GROUP_SIG_WAIT) {
			/*
			 * group is already being deleted, notify main
			 * thread and exit.
			 */
			groupp->status &= ~VNTSD_GROUP_SIG_WAIT;
			(void) cond_signal(&groupp->cvp);
			(void) mutex_unlock(&groupp->lock);
			thr_exit(0);
		}

		/*
		 * if there still is console(s) in the group,
		 * the console(s) could not be connected any more because of
		 * a fatal error. Therefore, mark the console and notify
		 * main thread to delete console and group.
		 */
		(void) vntsd_que_walk(groupp->conspq,
		    (el_func_t)vntsd_mark_deleted_cons);
		groupp->status |= VNTSD_GROUP_CLEAN_CONS;

		/* signal main thread to delete the group */
		(void) thr_kill(groupp->vntsd->tid, SIGUSR1);
		(void) mutex_unlock(&groupp->lock);

		/* log error */
		if (status != VNTSD_STATUS_NO_CONS)
			vntsd_log(status, err_msg);
		thr_exit(0);
	}
}