nfsclient: Return an error status in nfsInit()

Avoid assert() and use proper cleanup if nfsInit() fails to allocate a
resource.
This commit is contained in:
Sebastian Huber
2013-01-09 17:22:51 +01:00
parent d8134178de
commit f33a84b555
2 changed files with 84 additions and 50 deletions

View File

@@ -135,8 +135,11 @@ rpcUdpCleanup(void);
* *
* Supply zero values to have the * Supply zero values to have the
* driver chose reasonable defaults. * driver chose reasonable defaults.
*
* @retval 0 Successful operation.
* @retval -1 An error occurred. The errno is set to indicate the error.
*/ */
void int
nfsInit(int smallPoolDepth, int bigPoolDepth); nfsInit(int smallPoolDepth, int bigPoolDepth);
/** /**

View File

@@ -679,17 +679,6 @@ static struct nfsstats {
* during the system lifetime * during the system lifetime
*/ */
u_short fs_ids; u_short fs_ids;
} nfsGlob = {0, 0, 0, 0, 0, 0};
/*
* Global variable to tune the 'st_blksize' (stat(2)) value this nfs
* client should report.
* size on the server.
*/
#ifndef DEFAULT_NFS_ST_BLKSIZE
#define DEFAULT_NFS_ST_BLKSIZE NFS_MAXDATA
#endif
int nfsStBlksize = DEFAULT_NFS_ST_BLKSIZE;
/* Two pools of RPC transactions; /* Two pools of RPC transactions;
* One with small send buffers * One with small send buffers
@@ -700,8 +689,19 @@ int nfsStBlksize = DEFAULT_NFS_ST_BLKSIZE;
* Note: The RX buffers are always * Note: The RX buffers are always
* big * big
*/ */
static RpcUdpXactPool smallPool = 0; RpcUdpXactPool smallPool;
static RpcUdpXactPool bigPool = 0; RpcUdpXactPool bigPool;
} nfsGlob = {0, 0, 0xffffffff, 0, 0, 0, NULL, NULL};
/*
* Global variable to tune the 'st_blksize' (stat(2)) value this nfs
* client should report.
* size on the server.
*/
#ifndef DEFAULT_NFS_ST_BLKSIZE
#define DEFAULT_NFS_ST_BLKSIZE NFS_MAXDATA
#endif
int nfsStBlksize = DEFAULT_NFS_ST_BLKSIZE;
/***************************************** /*****************************************
@@ -997,7 +997,7 @@ NfsNode rval = nfsNodeCreate(node->nfs, 0);
* they are created and destroyed * they are created and destroyed
* on the fly). * on the fly).
*/ */
void int
nfsInit(int smallPoolDepth, int bigPoolDepth) nfsInit(int smallPoolDepth, int bigPoolDepth)
{ {
static int initialised = 0; static int initialised = 0;
@@ -1005,7 +1005,7 @@ entry dummy;
rtems_status_code status; rtems_status_code status;
if (initialised) if (initialised)
return; return 0;
initialised = 1; initialised = 1;
@@ -1018,7 +1018,8 @@ rtems_status_code status;
if (RTEMS_SUCCESSFUL != rtems_io_register_driver(0, &drvNfs, &nfsGlob.nfs_major)) { if (RTEMS_SUCCESSFUL != rtems_io_register_driver(0, &drvNfs, &nfsGlob.nfs_major)) {
fprintf(stderr,"Registering NFS driver failed - %s\n", strerror(errno)); fprintf(stderr,"Registering NFS driver failed - %s\n", strerror(errno));
return; errno = ENOMEM;
return -1;
} }
if (0==smallPoolDepth) if (0==smallPoolDepth)
@@ -1039,19 +1040,23 @@ rtems_status_code status;
dummy.name = "somename"; /* guess average length of a filename */ dummy.name = "somename"; /* guess average length of a filename */
dirres_entry_size = xdr_sizeof((xdrproc_t)xdr_entry, &dummy); dirres_entry_size = xdr_sizeof((xdrproc_t)xdr_entry, &dummy);
smallPool = rpcUdpXactPoolCreate( nfsGlob.smallPool = rpcUdpXactPoolCreate(
NFS_PROGRAM, NFS_PROGRAM,
NFS_VERSION_2, NFS_VERSION_2,
CONFIG_NFS_SMALL_XACT_SIZE, CONFIG_NFS_SMALL_XACT_SIZE,
smallPoolDepth); smallPoolDepth);
assert( smallPool ); if (nfsGlob.smallPool == NULL) {
goto cleanup;
}
bigPool = rpcUdpXactPoolCreate( nfsGlob.bigPool = rpcUdpXactPoolCreate(
NFS_PROGRAM, NFS_PROGRAM,
NFS_VERSION_2, NFS_VERSION_2,
CONFIG_NFS_BIG_XACT_SIZE, CONFIG_NFS_BIG_XACT_SIZE,
bigPoolDepth); bigPoolDepth);
assert( bigPool ); if (nfsGlob.bigPool == NULL) {
goto cleanup;
}
status = rtems_semaphore_create( status = rtems_semaphore_create(
rtems_build_name('N','F','S','l'), rtems_build_name('N','F','S','l'),
@@ -1059,14 +1064,19 @@ rtems_status_code status;
MUTEX_ATTRIBUTES, MUTEX_ATTRIBUTES,
0, 0,
&nfsGlob.llock); &nfsGlob.llock);
assert( status == RTEMS_SUCCESSFUL ); if (status != RTEMS_SUCCESSFUL) {
goto cleanup;
}
status = rtems_semaphore_create( status = rtems_semaphore_create(
rtems_build_name('N','F','S','m'), rtems_build_name('N','F','S','m'),
1, 1,
MUTEX_ATTRIBUTES, MUTEX_ATTRIBUTES,
0, 0,
&nfsGlob.lock); &nfsGlob.lock);
assert( status == RTEMS_SUCCESSFUL ); if (status != RTEMS_SUCCESSFUL) {
goto cleanup;
}
if (sizeof(ino_t) < sizeof(u_int)) { if (sizeof(ino_t) < sizeof(u_int)) {
fprintf(stderr, fprintf(stderr,
@@ -1075,6 +1085,15 @@ rtems_status_code status;
"you should fix newlib's sys/stat.h - for now I'll enable a hack...\n"); "you should fix newlib's sys/stat.h - for now I'll enable a hack...\n");
} }
return 0;
cleanup:
nfsCleanup();
initialised = 0;
return -1;
} }
/* Driver cleanup code /* Driver cleanup code
@@ -1082,14 +1101,9 @@ rtems_status_code status;
int int
nfsCleanup(void) nfsCleanup(void)
{ {
rtems_id l;
int refuse; int refuse;
if (!nfsGlob.llock) { if (nfsGlob.llock != 0) {
/* registering the driver failed - let them still cleanup */
return 0;
}
LOCK(nfsGlob.llock); LOCK(nfsGlob.llock);
if ( (refuse = nfsGlob.num_mounted_fs) ) { if ( (refuse = nfsGlob.num_mounted_fs) ) {
fprintf(stderr,"Refuse to unload NFS; %i filesystems still mounted.\n", fprintf(stderr,"Refuse to unload NFS; %i filesystems still mounted.\n",
@@ -1101,19 +1115,33 @@ int refuse;
UNLOCK(nfsGlob.llock); UNLOCK(nfsGlob.llock);
return -1; return -1;
} }
}
if (nfsGlob.lock != 0) {
rtems_semaphore_delete(nfsGlob.lock); rtems_semaphore_delete(nfsGlob.lock);
nfsGlob.lock = 0; nfsGlob.lock = 0;
}
/* hold the lock while cleaning up... */ if (nfsGlob.smallPool != NULL) {
rpcUdpXactPoolDestroy(nfsGlob.smallPool);
nfsGlob.smallPool = NULL;
}
rpcUdpXactPoolDestroy(smallPool); if (nfsGlob.bigPool != NULL) {
rpcUdpXactPoolDestroy(bigPool); rpcUdpXactPoolDestroy(nfsGlob.bigPool);
l = nfsGlob.llock; nfsGlob.bigPool = NULL;
}
if (nfsGlob.nfs_major != 0xffffffff) {
rtems_io_unregister_driver(nfsGlob.nfs_major); rtems_io_unregister_driver(nfsGlob.nfs_major);
nfsGlob.nfs_major = 0xffffffff;
}
rtems_semaphore_delete(l); if (nfsGlob.llock != 0) {
rtems_semaphore_delete(nfsGlob.llock);
nfsGlob.llock = 0; nfsGlob.llock = 0;
}
return 0; return 0;
} }
@@ -1153,8 +1181,8 @@ int rval = -1;
switch (proc) { switch (proc) {
case NFSPROC_SYMLINK: case NFSPROC_SYMLINK:
case NFSPROC_WRITE: case NFSPROC_WRITE:
pool = bigPool; break; pool = nfsGlob.bigPool; break;
default: pool = smallPool; break; default: pool = nfsGlob.smallPool; break;
} }
xact = rpcUdpXactPoolGet(pool, XactGetCreate); xact = rpcUdpXactPoolGet(pool, XactGetCreate);
@@ -1776,7 +1804,10 @@ char *path = mt_entry->dev;
return -1; return -1;
} }
nfsInit(0, 0); if (nfsInit(0, 0) != 0) {
fprintf (stderr, "error: initialising NFS\n");
return -1;
};
#if 0 #if 0
printf("Trying to mount %s on %s\n",path,mntpoint); printf("Trying to mount %s on %s\n",path,mntpoint);