+2004-04-28 Ion Badulescu <ionut@moisil.badula.org>
+
+ Fixes for various memory management problems discovered by
+ Rainer's purify run:
+
+ * conf/transp/transp_tli.c (check_pmap_up): zero out struct
+ timeval before using;
+ (get_nfs_version): ditto
+
+ * amd/map.c (umount_exported): make sure we don't try to free the
+ same am_node multiple times, by setting its corresponding
+ exported_ap slot to null
+
+ * amd/get_args.c (get_version_string): a static pointer is pretty
+ pointless, make it automatic
+
+ * amd/conf.c (gopt_debug_options): remove unnecessary strdup();
+ (gopt_log_options): ditto
+ (gopt_print_version): free version string after using it
+
+ * amd/autil.c (mf_mounted): free mntfs->mf_fo instead of leaking
+ it
+
+ * amd/amfs_generic.c (amfs_lookup_one_mntfs): use the CALLOC macro
+ (amfs_lookup_mntfs): free def_opts on return
+
+ * amd/amd.c (daemon_mode): zero out struct sigaction before using
+ it;
+ (main): ditto
+
2004-04-27 Ion Badulescu <ionut@moisil.badula.org>
* amd/amfs_generic.c (amfs_lookup_one_mntfs): force FS_MKMNT on
also fixing a problem with restarting nfsx components
- bugs fixed:
+ * various memory management problems (leaks, etc)
* fixed nfsx support
* fixed a race involving late replies to network queries which
arrive after the filesystem has already been mounted
* SUCH DAMAGE.
*
*
- * $Id: amd.c,v 1.26 2004/01/22 05:01:06 ezk Exp $
+ * $Id: amd.c,v 1.27 2004/04/28 04:22:13 ib42 Exp $
*
*/
#ifdef HAVE_SIGACTION
struct sigaction sa, osa;
+ memset(&sa, 0, sizeof(sa));
sa.sa_handler = parent_exit;
sa.sa_flags = 0;
sigemptyset(&(sa.sa_mask));
* Trap interrupts for shutdowns.
*/
#ifdef HAVE_SIGACTION
+ memset(&sa, 0, sizeof(sa));
sa.sa_handler = sigterm;
sa.sa_flags = 0;
sigemptyset(&(sa.sa_mask));
* SUCH DAMAGE.
*
*
- * $Id: amfs_generic.c,v 1.24 2004/04/27 04:38:40 ib42 Exp $
+ * $Id: amfs_generic.c,v 1.25 2004/04/28 04:22:13 ib42 Exp $
*
*/
#endif /* HAVE_FS_AUTOFS */
/* match the operators */
- fs_opts = calloc(1, sizeof(am_opts));
+ fs_opts = CALLOC(am_opts);
p = ops_match(fs_opts, ivec, def_opts, new_mp->am_path,
pfname, mf->mf_info);
#ifdef HAVE_FS_AUTOFS
/* We're done with ivecs */
XFREE(ivecs);
XFREE(info);
+ XFREE(def_opts);
if (count == 0) { /* no match */
XFREE(mf_array);
ereturn(ENOENT);
* SUCH DAMAGE.
*
*
- * $Id: autil.c,v 1.44 2004/01/06 03:56:20 ezk Exp $
+ * $Id: autil.c,v 1.45 2004/04/28 04:22:13 ib42 Exp $
*
*/
(*mf->mf_ops->mounted) (mf);
}
- mf->mf_fo = 0;
+ free_opts(mf->mf_fo);
+ XFREE(mf->mf_fo);
}
if (mf->mf_flags & MFF_RESTART) {
* SUCH DAMAGE.
*
*
- * $Id: conf.c,v 1.23 2004/01/22 05:01:06 ezk Exp $
+ * $Id: conf.c,v 1.24 2004/04/28 04:22:13 ib42 Exp $
*
*/
gopt_debug_options(const char *val)
{
#ifdef DEBUG
- usage += debug_option(strdup((char *)val));
+ usage += debug_option((char *)val);
return 0;
#else /* not DEBUG */
fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n",
static int
gopt_log_options(const char *val)
{
- usage += switch_option(strdup((char *)val));
+ usage += switch_option((char *)val);
return 0;
}
gopt_print_version(const char *val)
{
if (STREQ(val, "yes")) {
- fputs(get_version_string(), stderr);
+ char *vers = get_version_string();
+ fputs(vers, stderr);
+ XFREE(vers);
return 0;
} else if (STREQ(val, "no")) {
return 0;
* SUCH DAMAGE.
*
*
- * $Id: get_args.c,v 1.22 2004/01/06 03:56:20 ezk Exp $
+ * $Id: get_args.c,v 1.23 2004/04/28 04:22:13 ib42 Exp $
*
*/
char *
get_version_string(void)
{
- static char *vers = NULL;
+ char *vers = NULL;
char tmpbuf[1024];
char *wire_buf;
int wire_buf_len = 0;
* SUCH DAMAGE.
*
*
- * $Id: map.c,v 1.48 2004/04/25 23:58:46 ib42 Exp $
+ * $Id: map.c,v 1.49 2004/04/28 04:22:13 ib42 Exp $
*
*/
for (i = last_used_map; i >= 0; --i) {
am_node *mp = exported_ap[i];
+ mntfs *mf;
- if (mp) {
- mntfs *mf = mp->am_mnt;
- if (mf->mf_flags & MFF_UNMOUNTING) {
- /*
- * If this node is being unmounted then just ignore it. However,
- * this could prevent amd from finishing if the unmount gets blocked
- * since the am_node will never be free'd. am_unmounted needs
- * telling about this possibility. - XXX
- */
- continue;
- }
+ if (!mp)
+ continue;
- if (!(mf->mf_fsflags & FS_DIRECTORY))
- /*
- * When shutting down this had better
- * look like a directory, otherwise it
- * can't be unmounted!
- */
- mk_fattr(&mp->am_fattr, NFDIR);
+ mf = mp->am_mnt;
+ if (mf->mf_flags & MFF_UNMOUNTING) {
+ /*
+ * If this node is being unmounted then just ignore it. However,
+ * this could prevent amd from finishing if the unmount gets blocked
+ * since the am_node will never be free'd. am_unmounted needs
+ * telling about this possibility. - XXX
+ */
+ continue;
+ }
- if ((--immediate_abort < 0 &&
- !(mp->am_flags & AMF_ROOT) && mp->am_parent) ||
- (mf->mf_flags & MFF_RESTART)) {
+ if (!(mf->mf_fsflags & FS_DIRECTORY))
+ /*
+ * When shutting down this had better
+ * look like a directory, otherwise it
+ * can't be unmounted!
+ */
+ mk_fattr(&mp->am_fattr, NFDIR);
- /*
- * Just throw this node away without bothering to unmount it. If
- * the server is not known to be up then don't discard the mounted
- * on directory or Amd might hang...
- */
- if (mf->mf_server &&
- (mf->mf_server->fs_flags & (FSF_DOWN | FSF_VALID)) != FSF_VALID)
- mf->mf_flags &= ~MFF_MKMNT;
- if (gopt.flags & CFM_UNMOUNT_ON_EXIT || mp->am_flags & AMF_AUTOFS) {
- plog(XLOG_INFO, "on-exit attempt to unmount %s", mf->mf_mount);
+ if ((--immediate_abort < 0 &&
+ !(mp->am_flags & AMF_ROOT) && mp->am_parent) ||
+ (mf->mf_flags & MFF_RESTART)) {
+
+ /*
+ * Just throw this node away without bothering to unmount it. If
+ * the server is not known to be up then don't discard the mounted
+ * on directory or Amd might hang...
+ */
+ if (mf->mf_server &&
+ (mf->mf_server->fs_flags & (FSF_DOWN | FSF_VALID)) != FSF_VALID)
+ mf->mf_flags &= ~MFF_MKMNT;
+ if (gopt.flags & CFM_UNMOUNT_ON_EXIT || mp->am_flags & AMF_AUTOFS) {
+ plog(XLOG_INFO, "on-exit attempt to unmount %s", mf->mf_mount);
#ifdef HAVE_FS_AUTOFS
- if (mf->mf_flags & MFF_IS_AUTOFS)
- autofs_release_mp(mp);
+ if (mf->mf_flags & MFF_IS_AUTOFS)
+ autofs_release_mp(mp);
#endif /* HAVE_FS_AUTOFS */
- unmount_node((opaque_t) mp);
- }
- am_unmounted(mp);
- } else {
- /*
- * Any other node gets forcibly timed out.
- */
- mp->am_flags &= ~AMF_NOTIMEOUT;
- mp->am_mnt->mf_flags &= ~MFF_RSTKEEP;
- mp->am_ttl = 0;
- mp->am_timeo = 1;
- mp->am_timeo_w = 0;
+ unmount_node((opaque_t) mp);
}
+ am_unmounted(mp);
+ exported_ap[i] = 0;
+ } else {
+ /*
+ * Any other node gets forcibly timed out.
+ */
+ mp->am_flags &= ~AMF_NOTIMEOUT;
+ mp->am_mnt->mf_flags &= ~MFF_RSTKEEP;
+ mp->am_ttl = 0;
+ mp->am_timeo = 1;
+ mp->am_timeo_w = 0;
}
}
}
* SUCH DAMAGE.
*
*
- * $Id: transp_tli.c,v 1.22 2004/01/22 15:44:37 ezk Exp $
+ * $Id: transp_tli.c,v 1.23 2004/04/28 04:22:13 ib42 Exp $
*
* TLI specific utilities.
* -Erez Zadok <ezk@cs.columbia.edu>
int socket = RPC_ANYSOCK;
struct timeval timeout;
+ memset(&timeout, 0, sizeof(timeout));
timeout.tv_sec = 3;
timeout.tv_usec = 0;
sin->sin_port = htons(PMAPPORT);
}
/* 3 seconds is more than enough for a LAN */
+ memset(&tv, 0, sizeof(tv));
tv.tv_sec = 3;
tv.tv_usec = 0;