statd: not unlinking host files
Subsystems (2)
PATCH 1/1 statd: not unlinking host files
Again working with the state file code, I notice that statd was not unlinking hosts files when the kernel sent up the sm_unmon messages. This following patch address the reason why...
Comments?
steved.
commit f8536d0e210a8151900f8c68185927790239eb62
Author: Steve Dickson <[email protected]> Date: Sat Dec 6 09:30:43 2008 -0500
statd: not unlinking host files
Statd is not unlinking host files during SM_UNMON and SM_UNMON_ALL calls because the given host is still on the run-time notify list (rtnl) and the check flag is set when xunlink() is called. But the next thing the caller of xunlink() does is remove the host from the rtnl list which means the unlink will never happen.
So in cases where xunlink() is immediately follow by a call to nlist_free() (which removes the host from the list) the check flag to xunlink() is not set.
utils/statd/monitor.c +2 -2
@@ -352,7 +352,7 @@ sm_unmon_1_svc(struct mon_id *argp, struct svc_req *rqstp)/* PRC: do the HA callout: */ ha_callout ("del-client" , mon_name, my_name,-1 ); -xunlink (SM_DIR , clnt->dns_name,1 ); +xunlink (SM_DIR , clnt->dns_name,0 );nlist_free (&rtnl, clnt);return (&result);
@@ -404,7 +404,7 @@ sm_unmon_all_1_svc(struct my_id *argp, struct svc_req *rqstp) temp =NL_NEXT (clnt);/* PRC: do the HA callout: */ ha_callout ("del-client" , mon_name, my_name,-1 ); -xunlink (SM_DIR , clnt->dns_name,1 ); +xunlink (SM_DIR , clnt->dns_name,0 );nlist_free (&rtnl, clnt); ++count; clnt = temp;
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 5 lines · Steve Dickson
Again working with the state file code, I notice that statd was not unlinking hosts files when the kernel sent up the
sm_unmonmessages. This following patch address the reason why...Comments?
Bizarre--thanks for catching that.
But it looks like these are actually the only two callers to xunlink? In which case, we should just ditch the "check" parameter entirely and avoid some confusion....
(I wonder how it ever got this way in the first case?)
--b.
Quoted 48 lines
steved.
commit
f8536d0e210a8151900f8c68185927790239eb62Author: Steve Dickson <[email protected]> Date: Sat Dec 6 09:30:43 2008 -0500statd: not unlinking host files
Statd is not unlinking host files during
SM_UNMONandSM_UNMON_ALLcalls because the given host is still on the run-time notify list (rtnl) and the check flag is set whenxunlink()is called. But the next thing the caller ofxunlink()does is remove the host from the rtnl list which means the unlink will never happen.So in cases where
xunlink()is immediately follow by a call tonlist_free()(which removes the host from the list) the check flag toxunlink()is not set.Signed-off-by Steve Dickson <[email protected]>utils/statd/monitor.c +2
-3@@ -352,7 +352,7 @@ sm_unmon_1_svc(struct mon_id *argp, struct svc_req *rqstp)/* PRC: do the HA callout: */ ha_callout ("del-client" , mon_name, my_name,-1 ); -xunlink (SM_DIR , clnt->dns_name,1 ); +xunlink (SM_DIR , clnt->dns_name,0 );nlist_free (&rtnl, clnt);return (&result);@@ -404,7 +404,7 @@ sm_unmon_all_1_svc(struct my_id *argp, struct svc_req *rqstp) temp =NL_NEXT (clnt);/* PRC: do the HA callout: */ ha_callout ("del-client" , mon_name, my_name,-1 ); -xunlink (SM_DIR , clnt->dns_name,1 ); +xunlink (SM_DIR , clnt->dns_name,0 );nlist_free (&rtnl, clnt); ++count; clnt = temp; --To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 5 lines · J. Bruce Fields
Quoted 4 lines · Steve Dickson
Again working with the state file code, I notice that statd was not unlinking hosts files when the kernel sent up the
sm_unmonmessages. This following patch address the reason why...
Quoted 7 lines
Quoted 1 line
Comments?
Bizarre--thanks for catching that.
But it looks like these are actually the only two callers to xunlink? In which case, we should just ditch the "check" parameter entirely and avoid some confusion....
It looks like xunlink() doesn't check error returns properly either. alloca() is a convenience, but the price is a SIGSEGV if the stack frame can't be extended.
For a system-level daemon like rpc.statd, I would rather see a proper implementation of this using malloc(3) or automatic storage, and ensuring that sprintf doesn't overrun its buffer. This also makes it possible to track the buffer allocation here using valgrind. alloca() is a completely inline implementation, according to its man page.
I'm not sure why statd has it's own implementation of xstrdup and xmalloc here as well; support/nfs/* already has both of these. It would be worth getting rid of these too.
Quoted 1 line
(I wonder how it ever got this way in the first case?)
Likely that rpc.statd was integrated into nfs-utils a long time ago from somewhere else that needed the switch argument.
Quoted 58 lines
--b.
Quoted 46 lines
steved.
commit
f8536d0e210a8151900f8c68185927790239eb62Author: Steve Dickson <[email protected]> Date: Sat Dec 6 09:30:43 2008 -0500statd: not unlinking host files
Statd is not unlinking host files during
SM_UNMONandSM_UNMON_ALLcalls because the given host is still on the run-time notify list (rtnl) and the check flag is set whenxunlink()is called. But the next thing the caller ofxunlink()does is remove the host from the rtnl list which means the unlink will never happen.So in cases where
xunlink()is immediately follow by a call tonlist_free()(which removes the host from the list) the check flag toxunlink()is not set.Signed-off-by Steve Dickson <[email protected]>utils/statd/monitor.c +1
-1@@ -352,7 +352,7 @@ sm_unmon_1_svc(struct mon_id *argp, struct svc_req *rqstp) /* PRC: do the HA callout: */ ha_callout("del-client", mon_name, my_name, -1); -xunlink (SM_DIR , clnt->dns_name,1 ); +xunlink (SM_DIR , clnt->dns_name,0 );nlist_free (&rtnl, clnt);return (&result);utils/statd/monitor.c +1
-1@@ -404,7 +404,7 @@ sm_unmon_all_1_svc(struct my_id *argp, struct svc_req *rqstp) temp =NL_NEXT (clnt);/* PRC: do the HA callout: */ ha_callout ("del-client" , mon_name, my_name,-1 ); -xunlink (SM_DIR , clnt->dns_name,1 ); +xunlink (SM_DIR , clnt->dns_name,0 );nlist_free (&rtnl, clnt); ++count;clnt = temp;Quoted 4 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 2 lines
Chuck Lever chuck[dot]lever[at]oracle[dot]com
Quoted 24 lines · Chuck Lever
Quoted 5 lines · J. Bruce Fields
Quoted 4 lines · Steve Dickson
Again working with the state file code, I notice that statd was not unlinking hosts files when the kernel sent up the
sm_unmonmessages. This following patch address the reason why...Quoted 7 lines
Quoted 1 line
Comments?
Bizarre--thanks for catching that.
But it looks like these are actually the only two callers to xunlink? In which case, we should just ditch the "check" parameter entirely and avoid some confusion....
It looks like
xunlink()doesn't check error returns properly either.alloca()is a convenience, but the price is a SIGSEGV if the stack frame can't be extended.For a system-level daemon like rpc.statd, I would rather see a proper implementation of this using malloc(3) or automatic storage, and ensuring that sprintf doesn't overrun its buffer. This also makes it possible to track the buffer allocation here using valgrind.
alloca()is a completely inline implementation, according to its man page.
Quoted 3 lines
I'm not sure why statd has it's own implementation of xstrdup and xmalloc here as well; support/nfs/* already has both of these. It would be worth getting rid of these too.
Added to the TODO list...
steved.
Quoted 5 lines · J. Bruce Fields
Quoted 4 lines · Steve Dickson
Again working with the state file code, I notice that statd was not unlinking hosts files when the kernel sent up the
sm_unmonmessages. This following patch address the reason why...
Quoted 7 lines
Quoted 1 line
Comments?
Bizarre--thanks for catching that.
But it looks like these are actually the only two callers to xunlink? In which case, we should just ditch the "check" parameter entirely and avoid some confusion....
I thought of that... I wanted to get the patch out and I wanted to get some context from the list as to why the check was there... I'll clean it up...
steved.
This is the patch I committed....
steved.
commit bc870150cc2116584aee288d15ac2b9a2f825ff5
Author: Steve Dickson <[email protected]> Date: Wed Dec 17 16:41:35 2008 -0500
statd: not unlinking host files
Statd is not unlinking host files during SM_UNMON and SM_UNMON_ALL calls because the given host is still on the run-time notify list (rtnl) and the check flag is set when xunlink() is called. But the next thing the caller of xunlink() does is remove the host from the rtnl list which means the unlink will never happen.
So this patch removes the check flag from xunlink() since its not needed and correctly allocates and frees memory used by xunlink().
utils/statd/misc.c +16 -14
@@ -53,23 +53,25 @@ xstrdup (const char *string)/* -* Call with check=1 to verify that this host is not still on the rtnl -* before unlinking file. +* Unlinking a file. */ void -xunlink (char *path,char *host,short int check) +xunlink (char *path,char *host) { -char *tozap; +char *tozap; - tozap=alloca (strlen (path)+strlen (host)+2 ); -sprintf (tozap,"%s/%s" , path, host); + tozap =malloc (strlen (path)+strlen (host)+2 ); +if (tozap ==NULL ) { +note (N_ERROR ,"xunlink: malloc failed: errno %d (%s)" , + errno,strerror (errno)); +return ; + } +sprintf (tozap,"%s/%s" , path, host); -if (!check || !nlist_gethost (rtnl, host,0 )) { -if (unlink (tozap) ==-1 ) -note (N_ERROR ,"unlink (%s): %s" , tozap,strerror (errno)); -else -dprintf (N_DEBUG ,"Unlinked %s" , tozap); - } -else -dprintf (N_DEBUG ,"Not unlinking %s--host still monitored." , tozap); +if (unlink (tozap) ==-1 ) +note (N_ERROR ,"unlink (%s): %s" , tozap,strerror (errno)); +else +dprintf (N_DEBUG ,"Unlinked %s" , tozap); + +free (tozap); }
utils/statd/monitor.c +2 -2
@@ -352,7 +352,7 @@ sm_unmon_1_svc(struct mon_id *argp, struct svc_req *rqstp)/* PRC: do the HA callout: */ ha_callout ("del-client" , mon_name, my_name,-1 ); -xunlink (SM_DIR , clnt->dns_name,1 ); +xunlink (SM_DIR , clnt->dns_name);nlist_free (&rtnl, clnt);return (&result);
@@ -404,7 +404,7 @@ sm_unmon_all_1_svc(struct my_id *argp, struct svc_req *rqstp) temp =NL_NEXT (clnt);/* PRC: do the HA callout: */ ha_callout ("del-client" , mon_name, my_name,-1 ); -xunlink (SM_DIR , clnt->dns_name,1 ); +xunlink (SM_DIR , clnt->dns_name);nlist_free (&rtnl, clnt); ++count; clnt = temp;
utils/statd/statd.h +1 -1
@@ -53,7 +53,7 @@ extern int process_notify_list(void);extern int process_reply (FD_SET_TYPE *);extern char *xstrdup (const char *);extern void *xmalloc (size_t ); -extern void xunlink (char *,char *,short int ); +extern void xunlink (char *,char *);extern void load_state (void );/*