From f33a84b5553a67aaea9d19b02701689058297c3c Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 9 Jan 2013 17:22:51 +0100 Subject: nfsclient: Return an error status in nfsInit() Avoid assert() and use proper cleanup if nfsInit() fails to allocate a resource. --- cpukit/libfs/src/nfsclient/src/librtemsNfs.h | 7 +- cpukit/libfs/src/nfsclient/src/nfs.c | 127 +++++++++++++++++---------- 2 files changed, 84 insertions(+), 50 deletions(-) diff --git a/cpukit/libfs/src/nfsclient/src/librtemsNfs.h b/cpukit/libfs/src/nfsclient/src/librtemsNfs.h index ddef9eeab9..f1b2b4f50c 100644 --- a/cpukit/libfs/src/nfsclient/src/librtemsNfs.h +++ b/cpukit/libfs/src/nfsclient/src/librtemsNfs.h @@ -135,8 +135,11 @@ rpcUdpCleanup(void); * * Supply zero values to have the * 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); /** @@ -201,4 +204,4 @@ nfsGetTimeout(void); #endif /** @} */ -#endif \ No newline at end of file +#endif diff --git a/cpukit/libfs/src/nfsclient/src/nfs.c b/cpukit/libfs/src/nfsclient/src/nfs.c index e4e9d88bfe..99e34d5ac7 100644 --- a/cpukit/libfs/src/nfsclient/src/nfs.c +++ b/cpukit/libfs/src/nfsclient/src/nfs.c @@ -679,7 +679,19 @@ static struct nfsstats { * during the system lifetime */ u_short fs_ids; -} nfsGlob = {0, 0, 0, 0, 0, 0}; + + /* Two pools of RPC transactions; + * One with small send buffers + * the other with a big one. + * The actual size of the small + * buffer is configurable (see top). + * + * Note: The RX buffers are always + * big + */ + RpcUdpXactPool smallPool; + RpcUdpXactPool bigPool; +} nfsGlob = {0, 0, 0xffffffff, 0, 0, 0, NULL, NULL}; /* * Global variable to tune the 'st_blksize' (stat(2)) value this nfs @@ -691,18 +703,6 @@ static struct nfsstats { #endif int nfsStBlksize = DEFAULT_NFS_ST_BLKSIZE; -/* Two pools of RPC transactions; - * One with small send buffers - * the other with a big one. - * The actual size of the small - * buffer is configurable (see top). - * - * Note: The RX buffers are always - * big - */ -static RpcUdpXactPool smallPool = 0; -static RpcUdpXactPool bigPool = 0; - /***************************************** Implementation @@ -997,7 +997,7 @@ NfsNode rval = nfsNodeCreate(node->nfs, 0); * they are created and destroyed * on the fly). */ -void +int nfsInit(int smallPoolDepth, int bigPoolDepth) { static int initialised = 0; @@ -1005,7 +1005,7 @@ entry dummy; rtems_status_code status; if (initialised) - return; + return 0; initialised = 1; @@ -1018,7 +1018,8 @@ rtems_status_code status; if (RTEMS_SUCCESSFUL != rtems_io_register_driver(0, &drvNfs, &nfsGlob.nfs_major)) { fprintf(stderr,"Registering NFS driver failed - %s\n", strerror(errno)); - return; + errno = ENOMEM; + return -1; } if (0==smallPoolDepth) @@ -1039,19 +1040,23 @@ rtems_status_code status; dummy.name = "somename"; /* guess average length of a filename */ dirres_entry_size = xdr_sizeof((xdrproc_t)xdr_entry, &dummy); - smallPool = rpcUdpXactPoolCreate( + nfsGlob.smallPool = rpcUdpXactPoolCreate( NFS_PROGRAM, NFS_VERSION_2, CONFIG_NFS_SMALL_XACT_SIZE, smallPoolDepth); - assert( smallPool ); + if (nfsGlob.smallPool == NULL) { + goto cleanup; + } - bigPool = rpcUdpXactPoolCreate( + nfsGlob.bigPool = rpcUdpXactPoolCreate( NFS_PROGRAM, NFS_VERSION_2, CONFIG_NFS_BIG_XACT_SIZE, bigPoolDepth); - assert( bigPool ); + if (nfsGlob.bigPool == NULL) { + goto cleanup; + } status = rtems_semaphore_create( rtems_build_name('N','F','S','l'), @@ -1059,14 +1064,19 @@ rtems_status_code status; MUTEX_ATTRIBUTES, 0, &nfsGlob.llock); - assert( status == RTEMS_SUCCESSFUL ); + if (status != RTEMS_SUCCESSFUL) { + goto cleanup; + } + status = rtems_semaphore_create( rtems_build_name('N','F','S','m'), 1, MUTEX_ATTRIBUTES, 0, &nfsGlob.lock); - assert( status == RTEMS_SUCCESSFUL ); + if (status != RTEMS_SUCCESSFUL) { + goto cleanup; + } if (sizeof(ino_t) < sizeof(u_int)) { 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"); } + + return 0; + +cleanup: + + nfsCleanup(); + initialised = 0; + + return -1; } /* Driver cleanup code @@ -1082,38 +1101,47 @@ rtems_status_code status; int nfsCleanup(void) { -rtems_id l; int refuse; - if (!nfsGlob.llock) { - /* registering the driver failed - let them still cleanup */ - return 0; + if (nfsGlob.llock != 0) { + LOCK(nfsGlob.llock); + if ( (refuse = nfsGlob.num_mounted_fs) ) { + fprintf(stderr,"Refuse to unload NFS; %i filesystems still mounted.\n", + refuse); + nfsMountsShow(stderr); + /* yes, printing is slow - but since you try to unload the driver, + * you assume nobody is using NFS, so what if they have to wait? + */ + UNLOCK(nfsGlob.llock); + return -1; + } } - LOCK(nfsGlob.llock); - if ( (refuse = nfsGlob.num_mounted_fs) ) { - fprintf(stderr,"Refuse to unload NFS; %i filesystems still mounted.\n", - refuse); - nfsMountsShow(stderr); - /* yes, printing is slow - but since you try to unload the driver, - * you assume nobody is using NFS, so what if they have to wait? - */ - UNLOCK(nfsGlob.llock); - return -1; + if (nfsGlob.lock != 0) { + rtems_semaphore_delete(nfsGlob.lock); + nfsGlob.lock = 0; } - rtems_semaphore_delete(nfsGlob.lock); - nfsGlob.lock = 0; + if (nfsGlob.smallPool != NULL) { + rpcUdpXactPoolDestroy(nfsGlob.smallPool); + nfsGlob.smallPool = NULL; + } - /* hold the lock while cleaning up... */ + if (nfsGlob.bigPool != NULL) { + rpcUdpXactPoolDestroy(nfsGlob.bigPool); + nfsGlob.bigPool = NULL; + } - rpcUdpXactPoolDestroy(smallPool); - rpcUdpXactPoolDestroy(bigPool); - l = nfsGlob.llock; - rtems_io_unregister_driver(nfsGlob.nfs_major); + if (nfsGlob.nfs_major != 0xffffffff) { + rtems_io_unregister_driver(nfsGlob.nfs_major); + nfsGlob.nfs_major = 0xffffffff; + } + + if (nfsGlob.llock != 0) { + rtems_semaphore_delete(nfsGlob.llock); + nfsGlob.llock = 0; + } - rtems_semaphore_delete(l); - nfsGlob.llock = 0; return 0; } @@ -1153,8 +1181,8 @@ int rval = -1; switch (proc) { case NFSPROC_SYMLINK: case NFSPROC_WRITE: - pool = bigPool; break; - default: pool = smallPool; break; + pool = nfsGlob.bigPool; break; + default: pool = nfsGlob.smallPool; break; } xact = rpcUdpXactPoolGet(pool, XactGetCreate); @@ -1776,7 +1804,10 @@ char *path = mt_entry->dev; return -1; } - nfsInit(0, 0); + if (nfsInit(0, 0) != 0) { + fprintf (stderr, "error: initialising NFS\n"); + return -1; + }; #if 0 printf("Trying to mount %s on %s\n",path,mntpoint); -- cgit v1.2.3