Implement mount_getexports_timeout

master
peak3d 2020-06-04 16:42:48 +02:00
parent 3fbec953e6
commit 74ac9b5e11
2 changed files with 41 additions and 2 deletions

View File

@ -1904,6 +1904,16 @@ EXTERN int mount_getexports_async(struct rpc_context *rpc, const char *server,
*/
EXTERN struct exportnode *mount_getexports(const char *server);
/*
* Sync getexports_timeout(<server>, <timeout>)
* Function returns
* NULL : something failed
* exports export : a linked list of exported directories
*
* returned data must be freed by calling mount_free_export_list(exportnode);
*/
EXTERN struct exportnode *mount_getexports_timeout(const char *server, int timeout);
EXTERN void mount_free_export_list(struct exportnode *exports);

View File

@ -114,9 +114,27 @@ wait_for_reply(struct rpc_context *rpc, struct sync_cb_data *cb_data)
struct pollfd pfd;
int revents;
int ret;
uint64_t timeout;
assert(rpc->magic == RPC_CONTEXT_MAGIC);
if (rpc->timeout > 0) {
timeout = rpc_current_time() + rpc->timeout;
#ifndef HAVE_CLOCK_GETTIME
/* If we do not have GETTIME we fallback to time() which
* has 1s granularity for its timestamps.
* We thus need to bump the timeout by 1000ms
* so that we break if timeout is within 1.0 - 2.0 seconds.
* Otherwise setting a 1s timeout would trigger within
* 0.001 - 1.0s.
*/
timeout += 1000;
#endif
}
else {
timeout = 0;
}
while (!cb_data->is_finished) {
pfd.fd = rpc_get_fd(rpc);
@ -142,6 +160,11 @@ wait_for_reply(struct rpc_context *rpc, struct sync_cb_data *cb_data)
rpc_set_error(rpc, "Socket closed");
break;
}
if (timeout > 0 && rpc_current_time() > timeout) {
rpc_set_error(rpc, "Timeout reached");
break;
}
}
}
@ -1858,7 +1881,7 @@ mount_getexports_cb(struct rpc_context *mount_context, int status, void *data,
}
struct exportnode *
mount_getexports(const char *server)
mount_getexports_timeout(const char *server, int timeout)
{
struct sync_cb_data cb_data;
struct rpc_context *rpc;
@ -1868,7 +1891,7 @@ mount_getexports(const char *server)
cb_data.return_data = NULL;
rpc = rpc_init_context();
rpc_set_timeout(rpc, 2000);
rpc_set_timeout(rpc, timeout);
if (mount_getexports_async(rpc, server, mount_getexports_cb,
&cb_data) != 0) {
rpc_destroy_context(rpc);
@ -1881,6 +1904,12 @@ mount_getexports(const char *server)
return cb_data.return_data;
}
struct exportnode *
mount_getexports(const char *server)
{
mount_getexports_timeout(server, -1);
}
void
mount_free_export_list(struct exportnode *exp)
{