Ejemplo n.º 1
0
/*
 * If a clnt_call gets an RPC error, force the message out here with details.
 * This would be nice to send to commd_debug(), but we can't call rpc.mdcommd
 * code from libmeta.
 */
static void
mdmn_handle_RPC_error(CLIENT *clnt, char *ident, md_mn_nodeid_t nid)
{
	/*
	 * This is sized for a max message which would look like this:
	 * "mdmn_wakeup_initiator: rpc.mdcommd node 4294967295"
	 */
	char errstr[51];
	struct rpc_err e;

	CLNT_GETERR((CLIENT *) clnt, &e);
	if (meta_rpc_err_mask() & (1 << e.re_status)) {
		if (nid == 0) {
			(void) snprintf(errstr, sizeof (errstr),
			    "%s: %s node (local)", ident, COMMD_PROGNAME);
		} else {
			(void) snprintf(errstr, sizeof (errstr),
			    "%s: %s node %d", ident, COMMD_PROGNAME, nid);
		}
		syslog(LOG_WARNING, "mdmn_handle_RPC_error: %s",
		    clnt_sperror(clnt, errstr));
	}
}
Ejemplo n.º 2
0
/*
 * Print reply error info
 */
char *
clnt_sperror (CLIENT * rpch, const char *msg)
{
  char chrbuf[1024];
  struct rpc_err e;
  char *err;
  char *str = _buf ();
  char *strstart = str;
  int len;

  if (str == NULL)
    return NULL;
  CLNT_GETERR (rpch, &e);

  len = sprintf (str, "%s: ", msg);
  str += len;

  (void) strcpy(str, clnt_sperrno(e.re_status));
  str += strlen(str);

  switch (e.re_status)
    {
    case RPC_SUCCESS:
    case RPC_CANTENCODEARGS:
    case RPC_CANTDECODERES:
    case RPC_TIMEDOUT:
    case RPC_PROGUNAVAIL:
    case RPC_PROCUNAVAIL:
    case RPC_CANTDECODEARGS:
    case RPC_SYSTEMERROR:
    case RPC_UNKNOWNHOST:
    case RPC_UNKNOWNPROTO:
    case RPC_PMAPFAILURE:
    case RPC_PROGNOTREGISTERED:
    case RPC_FAILED:
      break;

    case RPC_CANTSEND:
    case RPC_CANTRECV:
      strerror_r (e.re_errno, chrbuf, sizeof chrbuf);
      len = sprintf (str, "; errno = %s", chrbuf);
      str += len;
      break;

    case RPC_VERSMISMATCH:
      len= sprintf (str, _("; low version = %lu, high version = %lu"),
		    e.re_vers.low, e.re_vers.high);
      str += len;
      break;

    case RPC_AUTHERROR:
      err = auth_errmsg (e.re_why);
      (void) strcpy(str, _("; why = "));
      str += strlen(str);

      if (err != NULL)
	{
	  (void) strcpy(str, err);
	  str += strlen(str);
	}
      else
	{
	  len = sprintf (str, _("(unknown authentication error - %d)"),
			 (int) e.re_why);
	  str += len;
	}
      break;

    case RPC_PROGVERSMISMATCH:
      len = sprintf (str, _("; low version = %lu, high version = %lu"),
		     e.re_vers.low, e.re_vers.high);
      str += len;
      break;

    default:			/* unknown */
      len = sprintf (str, "; s1 = %lu, s2 = %lu", e.re_lb.s1, e.re_lb.s2);
      str += len;
      break;
    }
  *str = '\n';
  *++str = '\0';
  return (strstart);
}
Ejemplo n.º 3
0
/*
 * Print reply error info
 */
char *
clnt_sperror(
	CLIENT *rpch,
	const char *s)
{
	struct rpc_err e;
	char *err;
	char *str = _buf();
	char *strstart = str;

	if (str == 0)
		return (0);
	CLNT_GETERR(rpch, &e);

	(void) sprintf(str, "%s: %s", s, clnt_sperrno(e.re_status));
	str += strlen(str);

	switch (e.re_status) {
	case RPC_SUCCESS:
	case RPC_CANTENCODEARGS:
	case RPC_CANTDECODERES:
	case RPC_TIMEDOUT:
	case RPC_PROGUNAVAIL:
	case RPC_PROCUNAVAIL:
	case RPC_CANTDECODEARGS:
	case RPC_SYSTEMERROR:
	case RPC_UNKNOWNHOST:
	case RPC_UNKNOWNPROTO:
	case RPC_PMAPFAILURE:
	case RPC_PROGNOTREGISTERED:
	case RPC_FAILED:
		break;

	case RPC_CANTSEND:
	case RPC_CANTRECV:
		(void) snprintf(str, CLNT_PERROR_BUFLEN - (str - strstart),
			"; errno = %s\n", strerror(e.re_errno));
		break;

	case RPC_VERSMISMATCH:
		(void) sprintf(str,
			"; low version = %lu, high version = %lu\n",
			(u_long)e.re_vers.low, (u_long)e.re_vers.high);
		break;

	case RPC_AUTHERROR:
		err = auth_errmsg(e.re_why);
		(void) sprintf(str,"; why = ");
		str += strlen(str);
		if (err != NULL) {
			(void) sprintf(str, "%s\n",err);
		} else {
			(void) sprintf(str,
				"(unknown authentication error - %d)\n",
				(int) e.re_why);
		}
		break;

	case RPC_PROGVERSMISMATCH:
		(void) sprintf(str,
			"; low version = %lu, high version = %lu\n",
			(u_long)e.re_vers.low, (u_long)e.re_vers.high);
		break;

	default:	/* unknown */
		(void) sprintf(str,
			"; s1 = %lu, s2 = %lu\n",
			(long)e.re_lb.s1, (long)e.re_lb.s2);
		break;
	}
	strstart[CLNT_PERROR_BUFLEN-2] = '\n';
	strstart[CLNT_PERROR_BUFLEN-1] = '\0';
	return(strstart) ;
}
Ejemplo n.º 4
0
/*
 * Return string reply error info. For use after clnt_call().
 * It allocates the  buffer of size MAXPATHLEN and assumes
 * caller's responsibility to free the memory after use.
 */
char *
clnt_sperror(const CLIENT *cl, const char *s)
{
	struct rpc_err e;
#ifdef notyet
	char *err;
#endif
	char *str;
	char *strstart;

	str = kmem_alloc(MAXPATHLEN, KM_SLEEP);
	strstart = str;

	CLNT_GETERR((CLIENT *) cl, &e);

	(void) sprintf(str, "%s: ", s);
	str += strlen(str);

	(void) strcpy(str, clnt_sperrno(e.re_status));
	str += strlen(str);

	switch (e.re_status) {
	case RPC_SUCCESS:
	case RPC_CANTENCODEARGS:
	case RPC_CANTDECODERES:
	case RPC_TIMEDOUT:
	case RPC_PROGUNAVAIL:
	case RPC_PROCUNAVAIL:
	case RPC_CANTDECODEARGS:
	case RPC_SYSTEMERROR:
	case RPC_UNKNOWNHOST:
	case RPC_UNKNOWNPROTO:
	case RPC_UNKNOWNADDR:
	case RPC_NOBROADCAST:
	case RPC_RPCBFAILURE:
	case RPC_PROGNOTREGISTERED:
	case RPC_FAILED:
	case RPC_INPROGRESS:
		break;

#ifdef notyet
	case RPC_N2AXLATEFAILURE:
		(void) sprintf(str, "; %s", netdir_sperror());
		break;
#endif

	case RPC_TLIERROR:
#ifdef notyet
		(void) sprintf(str, "; %s", t_errlist[e.re_terrno]);
#else
		(void) sprintf(str, "; %d", e.re_terrno);
#endif
		str += strlen(str);
		if (e.re_errno) {
#ifdef notyet
			(void) sprintf(str, "; %s", strerror(e.re_errno));
#else
			(void) sprintf(str, "; %d", e.re_errno);
#endif
		}
		break;

	case RPC_CANTSEND:
	case RPC_CANTRECV:
		if (e.re_errno) {
#ifdef notyet
			(void) sprintf(str, "; errno = %s",
			    strerror(e.re_errno));
#else
			(void) sprintf(str, "; errno = %d", e.re_errno);
#endif
			str += strlen(str);
		}
		if (e.re_terrno) {
#ifdef notyet
			(void) sprintf(str, "; %s", t_errlist[e.re_terrno]);
#else
			(void) sprintf(str, "; %d", e.re_terrno);
#endif
		}
		break;

	case RPC_VERSMISMATCH:
		(void) sprintf(str,
		    "; low version = %" PRIu32 ", high version = %" PRIu32,
		    e.re_vers.low, e.re_vers.high);
		break;

#ifdef notyet
	case RPC_AUTHERROR:
		err = auth_errmsg(e.re_why);
		(void) sprintf(str, "; why = ");
		str += strlen(str);
		if (err != NULL) {
			(void) sprintf(str, "%s", err);
		} else {
			(void) sprintf(str,
			    "(unknown authentication error - %d)",
			    (int)e.re_why);
		}
		break;
#endif

	case RPC_PROGVERSMISMATCH:
		(void) sprintf(str,
		    "; low version = %" PRIu32 ", high version = %" PRIu32,
		    e.re_vers.low, e.re_vers.high);
		break;

	default:	/* unknown */
		(void) sprintf(str, "; s1 = %" PRIu32 ", s2 = %" PRIu32,
		    e.re_lb.s1, e.re_lb.s2);
		break;
	}
	return (strstart);
}
Ejemplo n.º 5
0
static enum clnt_stat
clnt_reconnect_call(
	CLIENT		*cl,		/* client handle */
	struct rpc_callextra *ext,	/* call metadata */
	rpcproc_t	proc,		/* procedure number */
	struct mbuf	*args,		/* pointer to args */
	struct mbuf	**resultsp,	/* pointer to results */
	struct timeval	utimeout)
{
	struct rc_data *rc = (struct rc_data *)cl->cl_private;
	CLIENT *client;
	enum clnt_stat stat;
	int tries, error;

	tries = 0;
	do {
		mtx_lock(&rc->rc_lock);
		if (rc->rc_closed) {
			mtx_unlock(&rc->rc_lock);
			return (RPC_CANTSEND);
		}

		if (!rc->rc_client) {
			mtx_unlock(&rc->rc_lock);
			stat = clnt_reconnect_connect(cl);
			if (stat == RPC_SYSTEMERROR) {
				error = tsleep(&fake_wchan,
				    rc->rc_intr ? PCATCH | PBDRY : 0, "rpccon",
				    hz);
				if (error == EINTR || error == ERESTART)
					return (RPC_INTR);
				tries++;
				if (tries >= rc->rc_retries)
					return (stat);
				continue;
			}
			if (stat != RPC_SUCCESS)
				return (stat);
			mtx_lock(&rc->rc_lock);
		}

		if (!rc->rc_client) {
			mtx_unlock(&rc->rc_lock);
			stat = RPC_FAILED;
			continue;
		}
		CLNT_ACQUIRE(rc->rc_client);
		client = rc->rc_client;
		mtx_unlock(&rc->rc_lock);
		stat = CLNT_CALL_MBUF(client, ext, proc, args,
		    resultsp, utimeout);

		if (stat != RPC_SUCCESS) {
			if (!ext)
				CLNT_GETERR(client, &rc->rc_err);
		}

		if (stat == RPC_TIMEDOUT) {
			/*
			 * Check for async send misfeature for NLM
			 * protocol.
			 */
			if ((rc->rc_timeout.tv_sec == 0
				&& rc->rc_timeout.tv_usec == 0)
			    || (rc->rc_timeout.tv_sec == -1
				&& utimeout.tv_sec == 0
				&& utimeout.tv_usec == 0)) {
				CLNT_RELEASE(client);
				break;
			}
		}

		if (stat == RPC_TIMEDOUT || stat == RPC_CANTSEND
		    || stat == RPC_CANTRECV) {
			tries++;
			if (tries >= rc->rc_retries) {
				CLNT_RELEASE(client);
				break;
			}

			if (ext && ext->rc_feedback)
				ext->rc_feedback(FEEDBACK_RECONNECT, proc,
				    ext->rc_feedback_arg);

			mtx_lock(&rc->rc_lock);
			/*
			 * Make sure that someone else hasn't already
			 * reconnected by checking if rc_client has changed.
			 * If not, we are done with the client and must
			 * do CLNT_RELEASE(client) twice to dispose of it,
			 * because there is both an initial refcnt and one
			 * acquired by CLNT_ACQUIRE() above.
			 */
			if (rc->rc_client == client) {
				rc->rc_client = NULL;
				mtx_unlock(&rc->rc_lock);
				CLNT_RELEASE(client);
			} else {
				mtx_unlock(&rc->rc_lock);
			}
			CLNT_RELEASE(client);
		} else {
			CLNT_RELEASE(client);
			break;
		}
	} while (stat != RPC_SUCCESS);

	KASSERT(stat != RPC_SUCCESS || *resultsp,
	    ("RPC_SUCCESS without reply"));

	return (stat);
}
Ejemplo n.º 6
0
/*
 * Print reply error info
 */
char *
clnt_sperror(CLIENT *rpch, const char *s)
{
	struct rpc_err e;
	char *err;
	char *str;
	char *strstart;
	size_t len, i;

	if (rpch == NULL || s == NULL)
		return (0);

	str = _buf();		/* side effect: sets CLNT_PERROR_BUFLEN */
	if (str == 0)
		return (0);
	len = CLNT_PERROR_BUFLEN;
	strstart = str;
	CLNT_GETERR(rpch, &e);

	if (snprintf(str, len, "%s: ", s) > 0) {
		i = strlen(str);
		str += i;
		len -= i;
	}

	(void)strncpy(str, clnt_sperrno(e.re_status), len - 1);
	i = strlen(str);
	str += i;
	len -= i;

	switch (e.re_status) {
	case RPC_SUCCESS:
	case RPC_CANTENCODEARGS:
	case RPC_CANTDECODERES:
	case RPC_TIMEDOUT:
	case RPC_PROGUNAVAIL:
	case RPC_PROCUNAVAIL:
	case RPC_CANTDECODEARGS:
	case RPC_SYSTEMERROR:
	case RPC_UNKNOWNHOST:
	case RPC_UNKNOWNPROTO:
	case RPC_PMAPFAILURE:
	case RPC_PROGNOTREGISTERED:
	case RPC_FAILED:
		break;

	case RPC_CANTSEND:
	case RPC_CANTRECV:
		snprintf(str, len, "; errno = %s", strerror(e.re_errno));
		i = strlen(str);
		if (i > 0) {
			str += i;
			len -= i;
		}
		break;

	case RPC_VERSMISMATCH:
		snprintf(str, len, "; low version = %u, high version = %u",
			 e.re_vers.low, e.re_vers.high);
		i = strlen(str);
		if (i > 0) {
			str += i;
			len -= i;
		}
		break;

	case RPC_AUTHERROR:
		err = auth_errmsg(e.re_why);
		snprintf(str, len, "; why = ");
		i = strlen(str);
		if (i > 0) {
			str += i;
			len -= i;
		}
		if (err != NULL) {
			snprintf(str, len, "%s", err);
		} else {
			snprintf(str, len,
				 "(unknown authentication error - %d)",
				 (int)e.re_why);
		}
		i = strlen(str);
		if (i > 0) {
			str += i;
			len -= i;
		}
		break;

	case RPC_PROGVERSMISMATCH:
		snprintf(str, len, "; low version = %u, high version = %u",
			 e.re_vers.low, e.re_vers.high);
		i = strlen(str);
		if (i > 0) {
			str += i;
			len -= i;
		}
		break;

	default:		/* unknown */
		snprintf(str, len, "; s1 = %u, s2 = %u", e.re_lb.s1,
			 e.re_lb.s2);
		i = strlen(str);
		if (i > 0) {
			str += i;
			len -= i;
		}
		break;
	}
	strstart[CLNT_PERROR_BUFLEN - 1] = '\0';
	return (strstart);
}
Ejemplo n.º 7
0
/*
 * Print reply error info
 */
char *
clnt_sperror(CLIENT *rpch, char *s)
{
	struct rpc_err e;
	void clnt_perrno();
	char *err;
	char *bufstart = get_buf();
	char *str = bufstart;
	char *strstart = str;
	char *strend;

	if (str == 0)
		return (0);
	strend = str + BUFSIZ;
	CLNT_GETERR(rpch, &e);

	strncpy (str, s, BUFSIZ - 1);
	str[BUFSIZ - 1] = 0;
	strncat (str, ": ", BUFSIZ - 1 - strlen (bufstart));
	str += strlen(str);
	strncat (str, clnt_sperrno(e.re_status), BUFSIZ - 1 - strlen (bufstart));
	strstart[BUFSIZ - 1] = '\0';
	str += strlen(str);

	switch (e.re_status) {
	case RPC_SUCCESS:
	case RPC_CANTENCODEARGS:
	case RPC_CANTDECODERES:
	case RPC_TIMEDOUT:
	case RPC_PROGUNAVAIL:
	case RPC_PROCUNAVAIL:
	case RPC_CANTDECODEARGS:
	case RPC_SYSTEMERROR:
	case RPC_UNKNOWNHOST:
	case RPC_UNKNOWNPROTO:
	case RPC_PMAPFAILURE:
	case RPC_PROGNOTREGISTERED:
	case RPC_FAILED:
		break;

	case RPC_CANTSEND:
	case RPC_CANTRECV:
		/* 10 for the string */
		if (str - bufstart + 10 + strlen(strerror(e.re_errno)) < BUFSIZ)
		    (void) snprintf(str, strend-str, "; errno = %s",
				    strerror(e.re_errno));
		str += strlen(str);
		break;

	case RPC_VERSMISMATCH:
		/* 33 for the string, 22 for the numbers */
		if(str - bufstart + 33 + 22 < BUFSIZ)
		    (void) snprintf(str, strend-str,
				    "; low version = %lu, high version = %lu",
				    (u_long) e.re_vers.low,
				    (u_long) e.re_vers.high);
		str += strlen(str);
		break;

	case RPC_AUTHERROR:
		err = auth_errmsg(e.re_why);
		/* 8 for the string */
		if(str - bufstart + 8 < BUFSIZ)
		    (void) snprintf(str, strend-str, "; why = ");
		str += strlen(str);
		if (err != NULL) {
			if(str - bufstart + strlen(err) < BUFSIZ)
			    (void) snprintf(str, strend-str, "%s",err);
		} else {
		    /* 33 for the string, 11 for the number */
		    if(str - bufstart + 33 + 11 < BUFSIZ)
			(void) snprintf(str, strend-str,
					"(unknown authentication error - %d)",
					(int) e.re_why);
		}
		str += strlen(str);
		break;

	case RPC_PROGVERSMISMATCH:
		/* 33 for the string, 22 for the numbers */
		if(str - bufstart + 33 + 22 < BUFSIZ)
		    (void) snprintf(str, strend-str,
				    "; low version = %lu, high version = %lu",
				    (u_long) e.re_vers.low,
				    (u_long) e.re_vers.high);
		str += strlen(str);
		break;

	default:	/* unknown */
		/* 14 for the string, 22 for the numbers */
		if(str - bufstart + 14 + 22 < BUFSIZ)
		    (void) snprintf(str, strend-str,
				    "; s1 = %lu, s2 = %lu",
				    (u_long) e.re_lb.s1,
				    (u_long) e.re_lb.s2);
		str += strlen(str);
		break;
	}
	if (str - bufstart + 1 < BUFSIZ)
	    (void) snprintf(str, strend-str, "\n");
	return(strstart) ;
}
Ejemplo n.º 8
0
/*
 * Print reply error info
 */
char *
clnt_sperror(CLIENT *rpch, char *s)
{
	char *err, *str = buf;
	struct rpc_err e;
	int ret, len = CLNT_PERROR_BUFLEN;

	CLNT_GETERR(rpch, &e);

	ret = snprintf(str, len, "%s: %s", s, clnt_sperrno(e.re_status));
	if (ret == -1)
		ret = 0;
	else if (ret >= len)
		goto truncated;
	str += ret;
	len -= ret;

	switch (e.re_status) {
	case RPC_SUCCESS:
	case RPC_CANTENCODEARGS:
	case RPC_CANTDECODERES:
	case RPC_TIMEDOUT:
	case RPC_PROGUNAVAIL:
	case RPC_PROCUNAVAIL:
	case RPC_CANTDECODEARGS:
	case RPC_SYSTEMERROR:
	case RPC_UNKNOWNHOST:
	case RPC_UNKNOWNPROTO:
	case RPC_PMAPFAILURE:
	case RPC_PROGNOTREGISTERED:
	case RPC_FAILED:
		break;

	case RPC_CANTSEND:
	case RPC_CANTRECV:
		ret = snprintf(str, len, "; errno = %s", strerror(e.re_errno));
		if (ret == -1 || ret >= len)
			goto truncated;
		break;

	case RPC_VERSMISMATCH:
		ret = snprintf(str, len,
		    "; low version = %u, high version = %u",
		    e.re_vers.low, e.re_vers.high);
		if (ret == -1 || ret >= len)
			goto truncated;
		break;

	case RPC_AUTHERROR:
		ret = snprintf(str, len, "; why = ");
		if (ret == -1)
			ret = 0;
		else if (ret >= len)
			goto truncated;
		str += ret;
		len -= ret;
		err = auth_errmsg(e.re_why);
		if (err != NULL) {
			ret = snprintf(str, len, "%s", err);
			if (ret == -1 || ret >= len)
				goto truncated;
		} else {
			ret = snprintf(str, len,
			    "(unknown authentication error - %d)",
			    (int) e.re_why);
			if (ret == -1 || ret >= len)
				goto truncated;
		}
		break;

	case RPC_PROGVERSMISMATCH:
		ret = snprintf(str, len,
		    "; low version = %u, high version = %u",
		    e.re_vers.low, e.re_vers.high);
		if (ret == -1 || ret >= len)
			goto truncated;
		break;

	default:	/* unknown */
		ret = snprintf(str, len, "; s1 = %u, s2 = %u",
		    e.re_lb.s1, e.re_lb.s2);
		if (ret == -1 || ret >= len)
			goto truncated;
		break;
	}
	if (strlcat(buf, "\n", CLNT_PERROR_BUFLEN) >= CLNT_PERROR_BUFLEN)
		goto truncated;
	return (buf);

truncated:
	snprintf(buf + CLNT_PERROR_BUFLEN - 5, 5, "...\n");
	return (buf);
}