Add nfsport/mountport arguments
Add two arguments to set which port to use for MOUNT (only used in NFSv3) as well as for the NFS protocols. When set to non-zero libnfs will connect directly to that port and bypass the use of portmapper completely. Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>libnfs-4.0.0-vitalif
parent
54405d994e
commit
b54fc96e00
4
README
4
README
|
@ -69,6 +69,10 @@ Arguments supported by libnfs are :
|
|||
version=<3|4> : NFS Version. Default is 3.
|
||||
This is just a placeholder for now. NFSv4 support is not
|
||||
yet functional.
|
||||
nfsport=<port> : Use this port for NFS instead of using the portmapper.
|
||||
mountport=<port> : Use this port for the MOUNT protocol instead of
|
||||
using portmapper. This argument is ignored for NFSv4
|
||||
as it does not use the MOUNT protocol.
|
||||
|
||||
Auto_traverse_mounts
|
||||
====================
|
||||
|
|
|
@ -287,7 +287,9 @@ struct nfs_context {
|
|||
int auto_traverse_mounts;
|
||||
struct nested_mounts *nested_mounts;
|
||||
|
||||
int version;
|
||||
int version;
|
||||
int nfsport;
|
||||
int mountport;
|
||||
|
||||
/* NFSv4 specific fields */
|
||||
verifier4 verifier;
|
||||
|
|
|
@ -218,6 +218,30 @@ EXTERN int rpc_connect_program_async(struct rpc_context *rpc,
|
|||
int program, int version,
|
||||
rpc_cb cb, void *private_data);
|
||||
|
||||
/*
|
||||
* Async function to connect to a specific RPC program/version.
|
||||
* This connects directly to the specified port without using portmapper.
|
||||
*
|
||||
* Function returns
|
||||
* 0 : The connection was initiated. The callback will be invoked once the
|
||||
* connection establish finishes.
|
||||
* <0 : An error occured when trying to set up the connection.
|
||||
* The callback will not be invoked.
|
||||
*
|
||||
* When the callback is invoked, status indicates the result:
|
||||
* RPC_STATUS_SUCCESS : The tcp connection was successfully established.
|
||||
* data is NULL.
|
||||
* RPC_STATUS_ERROR : The connection failed to establish.
|
||||
* data is the error string.
|
||||
* RPC_STATUS_CANCEL : The connection attempt was aborted before it could
|
||||
* complete.
|
||||
* : data is NULL.
|
||||
*/
|
||||
EXTERN int rpc_connect_port_async(struct rpc_context *rpc, const char *server,
|
||||
int port,
|
||||
int program, int version,
|
||||
rpc_cb cb, void *private_data);
|
||||
|
||||
/*
|
||||
* When disconnecting a connection all commands in flight will be
|
||||
* called with a callback status RPC_STATUS_ERROR. Data will be the
|
||||
|
|
|
@ -206,6 +206,10 @@ EXTERN void nfs_destroy_context(struct nfs_context *nfs);
|
|||
* to the application.
|
||||
* version=<3|4> : NFS version. Default is 3.
|
||||
* Version 4 is not yet functional. Do not use.
|
||||
* nfsport=<port> : Use this port for NFS instead of using the portmapper.
|
||||
* mountport=<port> : Use this port for the MOUNT protocol instead of
|
||||
* using portmapper. This argument is ignored for NFSv4
|
||||
* as it does not use the MOUNT protocol.
|
||||
*/
|
||||
/*
|
||||
* Parse a complete NFS URL including, server, path and
|
||||
|
|
|
@ -116,6 +116,8 @@ nfs4_set_client_name
|
|||
nfs4_set_verifier
|
||||
win32_poll
|
||||
rpc_connect_async
|
||||
rpc_connect_port_async
|
||||
rpc_connect_program_async
|
||||
rpc_destroy_context
|
||||
rpc_disconnect
|
||||
rpc_get_error
|
||||
|
|
57
lib/libnfs.c
57
lib/libnfs.c
|
@ -274,6 +274,10 @@ nfs_set_context_args(struct nfs_context *nfs, const char *arg, const char *val)
|
|||
atoi(val));
|
||||
return -1;
|
||||
}
|
||||
} else if (!strcmp(arg, "nfsport")) {
|
||||
nfs->nfsport = atoi(val);
|
||||
} else if (!strcmp(arg, "mountport")) {
|
||||
nfs->mountport = atoi(val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -540,6 +544,9 @@ void free_rpc_cb_data(struct rpc_cb_data *data)
|
|||
free(data);
|
||||
}
|
||||
|
||||
static int
|
||||
rpc_connect_port_internal(struct rpc_context *rpc, int port, struct rpc_cb_data *data);
|
||||
|
||||
static void
|
||||
rpc_connect_program_5_cb(struct rpc_context *rpc, int status,
|
||||
void *command_data, void *private_data)
|
||||
|
@ -636,12 +643,12 @@ rpc_connect_program_3_cb(struct rpc_context *rpc, int status,
|
|||
}
|
||||
|
||||
rpc_disconnect(rpc, "normal disconnect");
|
||||
if (rpc_connect_async(rpc, data->server, rpc_port,
|
||||
rpc_connect_program_4_cb, data) != 0) {
|
||||
data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data);
|
||||
if (rpc_connect_port_internal(rpc, rpc_port, data)) {
|
||||
data->cb(rpc, RPC_STATUS_ERROR, command_data,
|
||||
data->private_data);
|
||||
free_rpc_cb_data(data);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -724,6 +731,46 @@ rpc_connect_program_1_cb(struct rpc_context *rpc, int status,
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
rpc_connect_port_internal(struct rpc_context *rpc, int port, struct rpc_cb_data *data)
|
||||
{
|
||||
if (rpc_connect_async(rpc, data->server, port,
|
||||
rpc_connect_program_4_cb, data) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rpc_connect_port_async(struct rpc_context *rpc, const char *server,
|
||||
int port,
|
||||
int program, int version,
|
||||
rpc_cb cb, void *private_data)
|
||||
{
|
||||
struct rpc_cb_data *data;
|
||||
|
||||
data = malloc(sizeof(struct rpc_cb_data));
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memset(data, 0, sizeof(struct rpc_cb_data));
|
||||
data->server = strdup(server);
|
||||
data->program = program;
|
||||
data->version = version;
|
||||
|
||||
data->cb = cb;
|
||||
data->private_data = private_data;
|
||||
|
||||
if (rpc_connect_port_internal(rpc, port, data)) {
|
||||
rpc_set_error(rpc, "Failed to start connection. %s",
|
||||
rpc_get_error(rpc));
|
||||
free_rpc_cb_data(data);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rpc_connect_program_async(struct rpc_context *rpc, const char *server,
|
||||
int program, int version,
|
||||
|
|
54
lib/nfs_v3.c
54
lib/nfs_v3.c
|
@ -854,6 +854,21 @@ finished:
|
|||
return;
|
||||
}
|
||||
|
||||
if (nfs->nfsport) {
|
||||
if (rpc_connect_port_async(nfs->rpc, nfs->server, nfs->nfsport,
|
||||
NFS_PROGRAM, NFS_V3,
|
||||
nfs3_mount_5_cb, data) != 0) {
|
||||
nfs_set_error(nfs, "%s: %s", __FUNCTION__,
|
||||
nfs_get_error(nfs));
|
||||
data->cb(-ENOMEM, nfs, nfs_get_error(nfs),
|
||||
data->private_data);
|
||||
free(md_cb);
|
||||
free_nfs_cb_data(data);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (rpc_connect_program_async(nfs->rpc, nfs->server, NFS_PROGRAM,
|
||||
NFS_V3, nfs3_mount_5_cb, data) != 0) {
|
||||
nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs));
|
||||
|
@ -961,6 +976,20 @@ nfs3_mount_3_cb(struct rpc_context *rpc, int status, void *command_data,
|
|||
*/
|
||||
rpc_disconnect(rpc, "normal disconnect");
|
||||
|
||||
if (nfs->nfsport) {
|
||||
if (rpc_connect_port_async(nfs->rpc, nfs->server, nfs->nfsport,
|
||||
NFS_PROGRAM, NFS_V3,
|
||||
nfs3_mount_5_cb, data) != 0) {
|
||||
nfs_set_error(nfs, "%s: %s", __FUNCTION__,
|
||||
nfs_get_error(nfs));
|
||||
data->cb(-ENOMEM, nfs, nfs_get_error(nfs),
|
||||
data->private_data);
|
||||
free_nfs_cb_data(data);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (rpc_connect_program_async(nfs->rpc, nfs->server, NFS_PROGRAM,
|
||||
NFS_V3, nfs3_mount_5_cb, data) != 0) {
|
||||
nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs));
|
||||
|
@ -1024,6 +1053,19 @@ nfs3_mount_2_cb(struct rpc_context *rpc, int status, void *command_data,
|
|||
}
|
||||
|
||||
rpc_disconnect(rpc, "normal disconnect");
|
||||
if (nfs->nfsport) {
|
||||
if (rpc_connect_port_async(nfs->rpc, nfs->server, nfs->nfsport,
|
||||
NFS_PROGRAM, NFS_V3,
|
||||
nfs3_mount_5_cb, data) != 0) {
|
||||
nfs_set_error(nfs, "%s: %s", __FUNCTION__,
|
||||
nfs_get_error(nfs));
|
||||
data->cb(-ENOMEM, nfs, nfs_get_error(nfs),
|
||||
data->private_data);
|
||||
free_nfs_cb_data(data);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (rpc_connect_program_async(nfs->rpc, nfs->server, NFS_PROGRAM,
|
||||
NFS_V3, nfs3_mount_5_cb, data) != 0) {
|
||||
|
@ -1086,6 +1128,18 @@ nfs3_mount_async(struct nfs_context *nfs, const char *server,
|
|||
data->cb = cb;
|
||||
data->private_data = private_data;
|
||||
|
||||
if (nfs->mountport) {
|
||||
if (rpc_connect_port_async(nfs->rpc, server, nfs->mountport,
|
||||
MOUNT_PROGRAM, MOUNT_V3,
|
||||
nfs3_mount_1_cb, data) != 0) {
|
||||
nfs_set_error(nfs, "Failed to start connection. %s",
|
||||
nfs_get_error(nfs));
|
||||
free_nfs_cb_data(data);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rpc_connect_program_async(nfs->rpc, server,
|
||||
MOUNT_PROGRAM, MOUNT_V3,
|
||||
nfs3_mount_1_cb, data) != 0) {
|
||||
|
|
12
lib/nfs_v4.c
12
lib/nfs_v4.c
|
@ -1612,6 +1612,18 @@ nfs4_mount_async(struct nfs_context *nfs, const char *server,
|
|||
data->private_data = private_data;
|
||||
data->path = strdup(new_export);
|
||||
|
||||
if (nfs->nfsport) {
|
||||
if (rpc_connect_port_async(nfs->rpc, server, nfs->nfsport,
|
||||
NFS4_PROGRAM, NFS_V4,
|
||||
nfs4_mount_1_cb, data) != 0) {
|
||||
nfs_set_error(nfs, "Failed to start connection. %s",
|
||||
nfs_get_error(nfs));
|
||||
free_nfs4_cb_data(data);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rpc_connect_program_async(nfs->rpc, server,
|
||||
NFS4_PROGRAM, NFS_V4,
|
||||
nfs4_mount_1_cb, data) != 0) {
|
||||
|
|
Loading…
Reference in New Issue