Beispiel #1
0
static int
ipmp_command(ipmp_handle_t handle, const void *req, uint_t reqsize)
{
	ipmp_state_t	*statep = (ipmp_state_t *)handle;
	mi_result_t	result;
	struct timeval	end;
	int		save_errno;
	int		retval;

	if (gettimeofday(&end, NULL) == -1)
		return (IPMP_FAILURE);
	end.tv_sec += IPMP_REQTIMEOUT;

	assert(statep->st_fd == -1);
	retval = ipmp_connect(&statep->st_fd);
	if (retval != IPMP_SUCCESS)
		return (retval);

	retval = ipmp_write(statep->st_fd, req, reqsize);
	if (retval != IPMP_SUCCESS)
		goto out;

	retval = ipmp_read(statep->st_fd, &result, sizeof (result), &end);
	if (retval != IPMP_SUCCESS)
		goto out;

	errno = result.me_sys_error;
	retval = result.me_mpathd_error;
out:
	save_errno = errno;
	(void) close(statep->st_fd);
	statep->st_fd = -1;
	errno = save_errno;
	return (retval);
}
Beispiel #2
0
/*
 * Using `statep', send a query request for `type' to in.mpathd, and if
 * necessary wait until at least `endtp' for a response.  Returns an IPMP
 * error code.  If successful, the caller may then read additional query
 * information through ipmp_readinfo(), and must eventually call
 * ipmp_querydone() to complete the query operation.  Only one query may be
 * outstanding on a given `statep' at a time.
 */
static int
ipmp_sendquery(ipmp_state_t *statep, ipmp_infotype_t type, const char *name,
    struct timeval *endtp)
{
	mi_query_t	query;
	mi_result_t	result;
	int		retval;

	query.miq_command = MI_QUERY;
	query.miq_inforeq = type;

	switch (type) {
	case IPMP_GROUPINFO:
		(void) strlcpy(query.miq_grname, name, LIFGRNAMSIZ);
		break;

	case IPMP_IFINFO:
		(void) strlcpy(query.miq_ifname, name, LIFNAMSIZ);
		break;

	case IPMP_GROUPLIST:
	case IPMP_SNAP:
		break;

	default:
		assert(0);
	}

	if (gettimeofday(endtp, NULL) == -1)
		return (IPMP_FAILURE);

	endtp->tv_sec += IPMP_REQTIMEOUT;

	assert(statep->st_fd == -1);
	retval = ipmp_connect(&statep->st_fd);
	if (retval != IPMP_SUCCESS)
		return (retval);

	retval = ipmp_write(statep->st_fd, &query, sizeof (query));
	if (retval != IPMP_SUCCESS)
		return (ipmp_querydone(statep, retval));

	retval = ipmp_read(statep->st_fd, &result, sizeof (result), endtp);
	if (retval != IPMP_SUCCESS)
		return (ipmp_querydone(statep, retval));

	if (result.me_mpathd_error != IPMP_SUCCESS)
		return (ipmp_querydone(statep, result.me_mpathd_error));

	return (IPMP_SUCCESS);
}
Beispiel #3
0
/*
 * Read the TLV triplet from descriptor `fd' and store its type, length and
 * value in `*typep', `*lenp', and `*valuep' respectively, before the current
 * time becomes `endtp'.  The buffer pointed to by `*valuep' will be
 * dynamically allocated.  Returns an IPMP error code.
 */
int
ipmp_readtlv(int fd, ipmp_infotype_t *typep, size_t *lenp, void **valuep,
    const struct timeval *endtp)
{
	int	retval;
	void	*value;

	retval = ipmp_read(fd, typep, sizeof (*typep), endtp);
	if (retval != IPMP_SUCCESS)
		return (retval);

	retval = ipmp_read(fd, lenp, sizeof (*lenp), endtp);
	if (retval != IPMP_SUCCESS)
		return (retval);

	value = malloc(*lenp);
	if (value == NULL) {
		/*
		 * Even though we cannot allocate space for the value, we
		 * still slurp it off so the input stream doesn't get left
		 * in a weird place.
		 */
		value = alloca(*lenp);
		(void) ipmp_read(fd, value, *lenp, endtp);
		return (IPMP_ENOMEM);
	}

	retval = ipmp_read(fd, value, *lenp, endtp);
	if (retval != IPMP_SUCCESS) {
		free(value);
		return (retval);
	}

	*valuep = value;
	return (IPMP_SUCCESS);
}