summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2017-02-24 14:47:58 +0100
committerLukas Slebodnik <lslebodn@redhat.com>2017-10-19 13:29:56 +0200
commit28f9c2051563fad6db26819c3d5188c8f946633e (patch)
tree2b236c1259dca3b26f5cbfd1b17d3fc62cf21e5e
parent1185cbce8d5dd04e539ca74d8f9564e5715a78aa (diff)
downloadsssd-28f9c2051563fad6db26819c3d5188c8f946633e.tar.gz
sssd-28f9c2051563fad6db26819c3d5188c8f946633e.tar.xz
sssd-28f9c2051563fad6db26819c3d5188c8f946633e.zip
sss_client: refactor internal timeout handling
This patch adds a timeout option to the internal client calls so that the timeout is not hard-coded anymore in the low level poll() calls but can be set by the caller with sss_nss_make_request_timeout(). Since the old timeout value is not changed by this patch there is no functional change expected. Related to https://pagure.io/SSSD/sssd/issue/2478 Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> Reviewed-by: Fabiano FidĂȘncio <fidencio@redhat.com>
-rw-r--r--src/sss_client/common.c106
-rw-r--r--src/sss_client/sss_cli.h6
2 files changed, 74 insertions, 38 deletions
diff --git a/src/sss_client/common.c b/src/sss_client/common.c
index b527c046e..e5e0cbf85 100644
--- a/src/sss_client/common.c
+++ b/src/sss_client/common.c
@@ -87,6 +87,7 @@ static void sss_cli_close_socket(void)
*/
static enum sss_status sss_cli_send_req(enum sss_cli_command cmd,
struct sss_cli_req_data *rd,
+ int timeout,
int *errnop)
{
uint32_t header[4];
@@ -110,7 +111,7 @@ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd,
do {
errno = 0;
- res = poll(&pfd, 1, SSS_CLI_SOCKET_TIMEOUT);
+ res = poll(&pfd, 1, timeout);
error = errno;
/* If error is EINTR here, we'll try again
@@ -188,6 +189,7 @@ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd,
*/
static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd,
+ int timeout,
uint8_t **_buf, int *_len,
int *errnop)
{
@@ -218,7 +220,7 @@ static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd,
do {
errno = 0;
- res = poll(&pfd, 1, SSS_CLI_SOCKET_TIMEOUT);
+ res = poll(&pfd, 1, timeout);
error = errno;
/* If error is EINTR here, we'll try again
@@ -344,6 +346,7 @@ failed:
static enum sss_status sss_cli_make_request_nochecks(
enum sss_cli_command cmd,
struct sss_cli_req_data *rd,
+ int timeout,
uint8_t **repbuf, size_t *replen,
int *errnop)
{
@@ -352,13 +355,13 @@ static enum sss_status sss_cli_make_request_nochecks(
int len = 0;
/* send data */
- ret = sss_cli_send_req(cmd, rd, errnop);
+ ret = sss_cli_send_req(cmd, rd, timeout, errnop);
if (ret != SSS_STATUS_SUCCESS) {
return ret;
}
/* data sent, now get reply */
- ret = sss_cli_recv_rep(cmd, &buf, &len, errnop);
+ ret = sss_cli_recv_rep(cmd, timeout, &buf, &len, errnop);
if (ret != SSS_STATUS_SUCCESS) {
return ret;
}
@@ -384,7 +387,7 @@ static enum sss_status sss_cli_make_request_nochecks(
* 0-3: 32bit unsigned version number
*/
-static bool sss_cli_check_version(const char *socket_name)
+static bool sss_cli_check_version(const char *socket_name, int timeout)
{
uint8_t *repbuf = NULL;
size_t replen;
@@ -414,7 +417,7 @@ static bool sss_cli_check_version(const char *socket_name)
req.len = sizeof(expected_version);
req.data = &expected_version;
- nret = sss_cli_make_request_nochecks(SSS_GET_VERSION, &req,
+ nret = sss_cli_make_request_nochecks(SSS_GET_VERSION, &req, timeout,
&repbuf, &replen, &errnop);
if (nret != SSS_STATUS_SUCCESS) {
return false;
@@ -524,7 +527,7 @@ static int make_safe_fd(int fd)
return new_fd;
}
-static int sss_cli_open_socket(int *errnop, const char *socket_name)
+static int sss_cli_open_socket(int *errnop, const char *socket_name, int timeout)
{
struct sockaddr_un nssaddr;
bool inprogress = true;
@@ -576,7 +579,7 @@ static int sss_cli_open_socket(int *errnop, const char *socket_name)
pfd.fd = sd;
pfd.events = POLLOUT;
- ret = poll(&pfd, 1, SSS_CLI_SOCKET_TIMEOUT - wait_time);
+ ret = poll(&pfd, 1, timeout - wait_time);
if (ret > 0) {
errnosize = sizeof(connect_errno);
@@ -590,7 +593,7 @@ static int sss_cli_open_socket(int *errnop, const char *socket_name)
wait_time = time(NULL) - start_time;
break;
case EAGAIN:
- if (wait_time < SSS_CLI_SOCKET_TIMEOUT) {
+ if (wait_time < timeout) {
sleep_time = rand() % 2 + 1;
sleep(sleep_time);
}
@@ -601,7 +604,7 @@ static int sss_cli_open_socket(int *errnop, const char *socket_name)
break;
}
- if (wait_time >= SSS_CLI_SOCKET_TIMEOUT) {
+ if (wait_time >= timeout) {
inprogress = false;
}
@@ -624,7 +627,9 @@ static int sss_cli_open_socket(int *errnop, const char *socket_name)
return sd;
}
-static enum sss_status sss_cli_check_socket(int *errnop, const char *socket_name)
+static enum sss_status sss_cli_check_socket(int *errnop,
+ const char *socket_name,
+ int timeout)
{
static pid_t mypid;
struct stat mysb;
@@ -655,7 +660,7 @@ static enum sss_status sss_cli_check_socket(int *errnop, const char *socket_name
do {
errno = 0;
- res = poll(&pfd, 1, SSS_CLI_SOCKET_TIMEOUT);
+ res = poll(&pfd, 1, timeout);
error = errno;
/* If error is EINTR here, we'll try again
@@ -690,14 +695,14 @@ static enum sss_status sss_cli_check_socket(int *errnop, const char *socket_name
sss_cli_close_socket();
}
- mysd = sss_cli_open_socket(errnop, socket_name);
+ mysd = sss_cli_open_socket(errnop, socket_name, timeout);
if (mysd == -1) {
return SSS_STATUS_UNAVAIL;
}
sss_cli_sd = mysd;
- if (sss_cli_check_version(socket_name)) {
+ if (sss_cli_check_version(socket_name, timeout)) {
return SSS_STATUS_SUCCESS;
}
@@ -708,10 +713,11 @@ static enum sss_status sss_cli_check_socket(int *errnop, const char *socket_name
/* this function will check command codes match and returned length is ok */
/* repbuf and replen report only the data section not the header */
-enum nss_status sss_nss_make_request(enum sss_cli_command cmd,
- struct sss_cli_req_data *rd,
- uint8_t **repbuf, size_t *replen,
- int *errnop)
+enum nss_status sss_nss_make_request_timeout(enum sss_cli_command cmd,
+ struct sss_cli_req_data *rd,
+ int timeout,
+ uint8_t **repbuf, size_t *replen,
+ int *errnop)
{
enum sss_status ret;
char *envval;
@@ -722,7 +728,7 @@ enum nss_status sss_nss_make_request(enum sss_cli_command cmd,
return NSS_STATUS_NOTFOUND;
}
- ret = sss_cli_check_socket(errnop, SSS_NSS_SOCKET_NAME);
+ ret = sss_cli_check_socket(errnop, SSS_NSS_SOCKET_NAME, timeout);
if (ret != SSS_STATUS_SUCCESS) {
#ifdef NONSTANDARD_SSS_NSS_BEHAVIOUR
*errnop = 0;
@@ -733,10 +739,11 @@ enum nss_status sss_nss_make_request(enum sss_cli_command cmd,
#endif
}
- ret = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop);
+ ret = sss_cli_make_request_nochecks(cmd, rd, timeout, repbuf, replen,
+ errnop);
if (ret == SSS_STATUS_UNAVAIL && *errnop == EPIPE) {
/* try reopen socket */
- ret = sss_cli_check_socket(errnop, SSS_NSS_SOCKET_NAME);
+ ret = sss_cli_check_socket(errnop, SSS_NSS_SOCKET_NAME, timeout);
if (ret != SSS_STATUS_SUCCESS) {
#ifdef NONSTANDARD_SSS_NSS_BEHAVIOUR
*errnop = 0;
@@ -748,7 +755,8 @@ enum nss_status sss_nss_make_request(enum sss_cli_command cmd,
}
/* and make request one more time */
- ret = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop);
+ ret = sss_cli_make_request_nochecks(cmd, rd, timeout, repbuf, replen,
+ errnop);
}
switch (ret) {
case SSS_STATUS_TRYAGAIN:
@@ -767,12 +775,22 @@ enum nss_status sss_nss_make_request(enum sss_cli_command cmd,
}
}
+enum nss_status sss_nss_make_request(enum sss_cli_command cmd,
+ struct sss_cli_req_data *rd,
+ uint8_t **repbuf, size_t *replen,
+ int *errnop)
+{
+ return sss_nss_make_request_timeout(cmd, rd, SSS_CLI_SOCKET_TIMEOUT,
+ repbuf, replen, errnop);
+}
+
int sss_pac_check_and_open(void)
{
enum sss_status ret;
int errnop;
- ret = sss_cli_check_socket(&errnop, SSS_PAC_SOCKET_NAME);
+ ret = sss_cli_check_socket(&errnop, SSS_PAC_SOCKET_NAME,
+ SSS_CLI_SOCKET_TIMEOUT);
if (ret != SSS_STATUS_SUCCESS) {
return EIO;
}
@@ -787,6 +805,7 @@ int sss_pac_make_request(enum sss_cli_command cmd,
{
enum sss_status ret;
char *envval;
+ int timeout = SSS_CLI_SOCKET_TIMEOUT;
/* avoid looping in the nss daemon */
envval = getenv("_SSS_LOOPS");
@@ -794,21 +813,23 @@ int sss_pac_make_request(enum sss_cli_command cmd,
return NSS_STATUS_NOTFOUND;
}
- ret = sss_cli_check_socket(errnop, SSS_PAC_SOCKET_NAME);
+ ret = sss_cli_check_socket(errnop, SSS_PAC_SOCKET_NAME, timeout);
if (ret != SSS_STATUS_SUCCESS) {
return NSS_STATUS_UNAVAIL;
}
- ret = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop);
+ ret = sss_cli_make_request_nochecks(cmd, rd, timeout, repbuf, replen,
+ errnop);
if (ret == SSS_STATUS_UNAVAIL && *errnop == EPIPE) {
/* try reopen socket */
- ret = sss_cli_check_socket(errnop, SSS_PAC_SOCKET_NAME);
+ ret = sss_cli_check_socket(errnop, SSS_PAC_SOCKET_NAME, timeout);
if (ret != SSS_STATUS_SUCCESS) {
return NSS_STATUS_UNAVAIL;
}
/* and make request one more time */
- ret = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop);
+ ret = sss_cli_make_request_nochecks(cmd, rd, timeout, repbuf, replen,
+ errnop);
}
switch (ret) {
case SSS_STATUS_TRYAGAIN:
@@ -872,6 +893,7 @@ int sss_pam_make_request(enum sss_cli_command cmd,
char *envval;
struct stat stat_buf;
const char *socket_name;
+ int timeout = SSS_CLI_SOCKET_TIMEOUT;
sss_pam_lock();
@@ -915,7 +937,7 @@ int sss_pam_make_request(enum sss_cli_command cmd,
}
}
- status = sss_cli_check_socket(errnop, socket_name);
+ status = sss_cli_check_socket(errnop, socket_name, timeout);
if (status != SSS_STATUS_SUCCESS) {
ret = PAM_SERVICE_ERR;
goto out;
@@ -929,17 +951,19 @@ int sss_pam_make_request(enum sss_cli_command cmd,
goto out;
}
- status = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop);
+ status = sss_cli_make_request_nochecks(cmd, rd, timeout, repbuf, replen,
+ errnop);
if (status == SSS_STATUS_UNAVAIL && *errnop == EPIPE) {
/* try reopen socket */
- status = sss_cli_check_socket(errnop, socket_name);
+ status = sss_cli_check_socket(errnop, socket_name, timeout);
if (status != SSS_STATUS_SUCCESS) {
ret = PAM_SERVICE_ERR;
goto out;
}
/* and make request one more time */
- status = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop);
+ status = sss_cli_make_request_nochecks(cmd, rd, timeout, repbuf, replen,
+ errnop);
}
if (status == SSS_STATUS_SUCCESS) {
@@ -968,27 +992,30 @@ void sss_pam_close_fd(void)
static enum sss_status
sss_cli_make_request_with_checks(enum sss_cli_command cmd,
struct sss_cli_req_data *rd,
+ int timeout,
uint8_t **repbuf, size_t *replen,
int *errnop,
const char *socket_name)
{
enum sss_status ret = SSS_STATUS_UNAVAIL;
- ret = sss_cli_check_socket(errnop, socket_name);
+ ret = sss_cli_check_socket(errnop, socket_name, timeout);
if (ret != SSS_STATUS_SUCCESS) {
return SSS_STATUS_UNAVAIL;
}
- ret = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop);
+ ret = sss_cli_make_request_nochecks(cmd, rd, timeout, repbuf, replen,
+ errnop);
if (ret == SSS_STATUS_UNAVAIL && *errnop == EPIPE) {
/* try reopen socket */
- ret = sss_cli_check_socket(errnop, socket_name);
+ ret = sss_cli_check_socket(errnop, socket_name, timeout);
if (ret != SSS_STATUS_SUCCESS) {
return SSS_STATUS_UNAVAIL;
}
/* and make request one more time */
- ret = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop);
+ ret = sss_cli_make_request_nochecks(cmd, rd, timeout, repbuf, replen,
+ errnop);
}
return ret;
@@ -999,7 +1026,8 @@ int sss_sudo_make_request(enum sss_cli_command cmd,
uint8_t **repbuf, size_t *replen,
int *errnop)
{
- return sss_cli_make_request_with_checks(cmd, rd, repbuf, replen, errnop,
+ return sss_cli_make_request_with_checks(cmd, rd, SSS_CLI_SOCKET_TIMEOUT,
+ repbuf, replen, errnop,
SSS_SUDO_SOCKET_NAME);
}
@@ -1008,7 +1036,8 @@ int sss_autofs_make_request(enum sss_cli_command cmd,
uint8_t **repbuf, size_t *replen,
int *errnop)
{
- return sss_cli_make_request_with_checks(cmd, rd, repbuf, replen, errnop,
+ return sss_cli_make_request_with_checks(cmd, rd, SSS_CLI_SOCKET_TIMEOUT,
+ repbuf, replen, errnop,
SSS_AUTOFS_SOCKET_NAME);
}
@@ -1017,7 +1046,8 @@ int sss_ssh_make_request(enum sss_cli_command cmd,
uint8_t **repbuf, size_t *replen,
int *errnop)
{
- return sss_cli_make_request_with_checks(cmd, rd, repbuf, replen, errnop,
+ return sss_cli_make_request_with_checks(cmd, rd, SSS_CLI_SOCKET_TIMEOUT,
+ repbuf, replen, errnop,
SSS_SSH_SOCKET_NAME);
}
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
index 0b97d492e..5329651a9 100644
--- a/src/sss_client/sss_cli.h
+++ b/src/sss_client/sss_cli.h
@@ -568,6 +568,12 @@ enum nss_status sss_nss_make_request(enum sss_cli_command cmd,
uint8_t **repbuf, size_t *replen,
int *errnop);
+enum nss_status sss_nss_make_request_timeout(enum sss_cli_command cmd,
+ struct sss_cli_req_data *rd,
+ int timeout,
+ uint8_t **repbuf, size_t *replen,
+ int *errnop);
+
int sss_pam_make_request(enum sss_cli_command cmd,
struct sss_cli_req_data *rd,
uint8_t **repbuf, size_t *replen,