linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: NeilBrown <neilb@suse.de>
To: Tony Asleson <tasleson@redhat.com>
Cc: linux-nfs@vger.kernel.org, Steve Dickson <SteveD@redhat.com>
Subject: Re: [PATCH] exportfs: Return non-zero exit value on error
Date: Tue, 22 Oct 2013 09:25:19 +1100	[thread overview]
Message-ID: <20131022092519.4f4683a8@notabene.brown> (raw)
In-Reply-To: <1380756584-13335-1-git-send-email-tasleson@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 8772 bytes --]

On Wed,  2 Oct 2013 18:29:44 -0500 Tony Asleson <tasleson@redhat.com> wrote:

> To improve error handling when scripting exportfs it's useful
> to have non-zero exit codes when the requested operation did not
> succeed.
> 
> This patch also returns a non-zero exit code if you request to
> unexport a non-existant share.
> 
> Signed-off-by: Tony Asleson <tasleson@redhat.com>
> ---
>  support/export/hostname.c |  2 ++
>  utils/exportfs/exportfs.c | 37 +++++++++++++++++++++++++++----------
>  2 files changed, 29 insertions(+), 10 deletions(-)
> 
> diff --git a/support/export/hostname.c b/support/export/hostname.c
> index 3e949a1..e53d692 100644
> --- a/support/export/hostname.c
> +++ b/support/export/hostname.c
> @@ -175,10 +175,12 @@ host_addrinfo(const char *hostname)
>  	case 0:
>  		return ai;
>  	case EAI_SYSTEM:
> +		export_errno = errno;
>  		xlog(D_GENERAL, "%s: failed to resolve %s: (%d) %m",
>  				__func__, hostname, errno);
>  		break;
>  	default:
> +		export_errno = EINVAL;
>  		xlog(D_GENERAL, "%s: failed to resolve %s: %s",
>  				__func__, hostname, gai_strerror(error));
>  		break;
> diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
> index 52fc03d..318deb3 100644
> --- a/utils/exportfs/exportfs.c
> +++ b/utils/exportfs/exportfs.c
> @@ -35,8 +35,8 @@
>  #include "xlog.h"
>  
>  static void	export_all(int verbose);
> -static void	exportfs(char *arg, char *options, int verbose);
> -static void	unexportfs(char *arg, int verbose);
> +static int	exportfs(char *arg, char *options, int verbose);
> +static int	unexportfs(char *arg, int verbose);
>  static void	exports_update(int verbose);
>  static void	dump(int verbose, int export_format);
>  static void	error(nfs_export *exp, int err);
> @@ -187,8 +187,12 @@ main(int argc, char **argv)
>  		if (f_all)
>  			export_all(f_verbose);
>  		else
> -			for (i = optind; i < argc ; i++)
> -				exportfs(argv[i], options, f_verbose);
> +			for (i = optind; i < argc ; i++) {
> +				if(!exportfs(argv[i], options, f_verbose)) {
> +					/* Only flag a generic EINVAL if no errno is set */
> +					export_errno = (export_errno) ? export_errno : EINVAL;
> +				}
> +			}
>  	}
>  	/* If we are unexporting everything, then
>  	 * don't care about what should be exported, as that
> @@ -201,8 +205,12 @@ main(int argc, char **argv)
>  		if (!f_reexport)
>  			xtab_export_read();
>  		if (!f_export)
> -			for (i = optind ; i < argc ; i++)
> -				unexportfs(argv[i], f_verbose);
> +			for (i = optind ; i < argc ; i++) {
> +				if (!unexportfs(argv[i], f_verbose)) {
> +					/* Only flag a generic EINVAL if no errno is set */
> +					export_errno = (export_errno) ? export_errno : EINVAL;
> +				}
> +			}
>  		if (!new_cache)
>  			rmtab_read();
>  	}
> @@ -296,9 +304,10 @@ export_all(int verbose)
>  }
>  
>  
> -static void
> +static int
>  exportfs(char *arg, char *options, int verbose)
>  {
> +	int rc = 0;
>  	struct exportent *eep;
>  	nfs_export	*exp = NULL;
>  	struct addrinfo	*ai = NULL;
> @@ -311,7 +320,8 @@ exportfs(char *arg, char *options, int verbose)
>  
>  	if (!path || *path != '/') {
>  		xlog(L_ERROR, "Invalid exporting option: %s", arg);
> -		return;
> +		export_errno = EINVAL;
> +		return rc;
>  	}
>  
>  	if ((htype = client_gettype(hname)) == MCL_FQDN) {
> @@ -339,13 +349,16 @@ exportfs(char *arg, char *options, int verbose)
>  	exp->m_warned = 0;
>  	validate_export(exp);
>  
> +	rc = 1;
>  out:
>  	freeaddrinfo(ai);
> +	return rc;
>  }
>  
> -static void
> +static int
>  unexportfs(char *arg, int verbose)
>  {
> +	int rc = 0;
>  	nfs_export	*exp;
>  	struct addrinfo *ai = NULL;
>  	char		*path;
> @@ -357,7 +370,8 @@ unexportfs(char *arg, int verbose)
>  
>  	if (!path || *path != '/') {
>  		xlog(L_ERROR, "Invalid unexporting option: %s", arg);
> -		return;
> +		export_errno = EINVAL;
> +		return rc;
>  	}
>  
>  	if ((htype = client_gettype(hname)) == MCL_FQDN) {
> @@ -397,9 +411,11 @@ unexportfs(char *arg, int verbose)
>  #endif
>  		exp->m_xtabent = 0;
>  		exp->m_mayexport = 0;
> +		rc = 1;
>  	}
>  
>  	freeaddrinfo(ai);
> +	return rc;
>  }
>  
>  static int can_test(void)
> @@ -728,6 +744,7 @@ error(nfs_export *exp, int err)
>  {
>  	xlog(L_ERROR, "%s:%s: %s", exp->m_client->m_hostname,
>  		exp->m_export.e_path, strerror(err));
> +	export_errno = (export_errno) ? export_errno : err;
>  }
>  
>  static void

This seems the have been forgotten, so maybe by replying to it someone will
notice (hi Steve).

Though I agree with the need for the patch, I don't much like it's shape.

Why change exportfs and unexportfs to return a status?  The status is only
used to set export_errno, and they sometimes set export_errno anyway, so why
not leave them returning  void and just setting export_errno as needed?


My preference is actually to get 'xlog' to set export_errno.

See below.

Thanks,
NeilBrown



From 2f63d6c3c38e673216a3351aff47d32059056638 Mon Sep 17 00:00:00 2001
From: Neil Brown <neilb@suse.de>
Date: Mon, 21 Oct 2013 17:40:55 +1100
Subject: [PATCH] exportfs: exit with error code if there was any error.

exportfs currently exits with a non-zero error for some errors,
but not for others.

It does this by having various support routines set the global
variable "export_errno".

Change this to have 'xlog' set export_errno if an ERROR is
reported.  That way all errors will be caught.

Note that the exit error code is changed from 22 (EINVAL)
to the more traditional '1'.

Signed-off-by: NeilBrown <neilb@suse.de>

diff --git a/support/include/exportfs.h b/support/include/exportfs.h
index 1fbf754..97b2327 100644
--- a/support/include/exportfs.h
+++ b/support/include/exportfs.h
@@ -179,7 +179,4 @@ struct export_features {
 struct export_features *get_export_features(void);
 void fix_pseudoflavor_flags(struct exportent *ep);
 
-/* Record export error.  */
-extern int export_errno;
-
 #endif /* EXPORTFS_H */
diff --git a/support/include/xlog.h b/support/include/xlog.h
index fd1a3f4..fd34ec2 100644
--- a/support/include/xlog.h
+++ b/support/include/xlog.h
@@ -35,6 +35,7 @@ struct xlog_debugfac {
 	int		df_fac;
 };
 
+extern int export_errno;
 void			xlog_open(char *progname);
 void			xlog_stderr(int on);
 void			xlog_syslog(int on);
diff --git a/support/nfs/exports.c b/support/nfs/exports.c
index d3160d3..d18667f 100644
--- a/support/nfs/exports.c
+++ b/support/nfs/exports.c
@@ -47,8 +47,6 @@ struct flav_info flav_map[] = {
 
 const int flav_map_size = sizeof(flav_map)/sizeof(flav_map[0]);
 
-int export_errno;
-
 static char	*efname = NULL;
 static XFILE	*efp = NULL;
 static int	first;
@@ -133,7 +131,6 @@ getexportent(int fromkernel, int fromexports)
 	}
 	if (ok < 0) {
 		xlog(L_ERROR, "expected client(options...)");
-		export_errno = EINVAL;
 		return NULL;
 	}
 	first = 0;
@@ -153,7 +150,6 @@ getexportent(int fromkernel, int fromexports)
 		ok = getexport(exp, sizeof(exp));
 		if (ok < 0) {
 			xlog(L_ERROR, "expected client(options...)");
-			export_errno = EINVAL;
 			return NULL;
 		}
 	}
@@ -173,7 +169,6 @@ getexportent(int fromkernel, int fromexports)
 		*opt++ = '\0';
 		if (!(sp = strchr(opt, ')')) || sp[1] != '\0') {
 			syntaxerr("bad option list");
-			export_errno = EINVAL;
 			return NULL;
 		}
 		*sp = '\0';
@@ -590,7 +585,6 @@ parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr)
 				     flname, flline, opt);	
 bad_option:
 				free(opt);
-				export_errno = EINVAL;
 				return -1;
 			}
 		} else if (strncmp(opt, "anongid=", 8) == 0) {
diff --git a/support/nfs/xlog.c b/support/nfs/xlog.c
index 6820346..9f9e63e 100644
--- a/support/nfs/xlog.c
+++ b/support/nfs/xlog.c
@@ -38,6 +38,8 @@ static int  logmask = 0;		/* What will be logged		*/
 static char log_name[256];		/* name of this program		*/
 static int  log_pid = -1;		/* PID of this program		*/
 
+int export_errno = 0;
+
 static void	xlog_toggle(int sig);
 static struct xlog_debugfac	debugnames[] = {
 	{ "general",	D_GENERAL, },
@@ -189,6 +191,8 @@ void
 xlog(int kind, const char* fmt, ...)
 {
 	va_list args;
+	if (kind & (L_ERROR|D_GENERAL))
+		export_errno = 1;
 
 	va_start(args, fmt);
 	xlog_backend(kind, fmt, args);
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
index 4331697..c2cb2fc 100644
--- a/utils/exportfs/exportfs.c
+++ b/utils/exportfs/exportfs.c
@@ -103,8 +103,6 @@ main(int argc, char **argv)
 	xlog_stderr(1);
 	xlog_syslog(0);
 
-	export_errno = 0;
-
 	while ((c = getopt(argc, argv, "afhio:ruv")) != EOF) {
 		switch(c) {
 		case 'a':

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

  reply	other threads:[~2013-10-21 22:25 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-02 23:29 [PATCH] exportfs: Return non-zero exit value on error Tony Asleson
2013-10-21 22:25 ` NeilBrown [this message]
2013-10-22  8:38   ` Steve Dickson
2013-10-22 15:23   ` Tony Asleson
2013-10-23  1:44     ` NeilBrown
2013-10-23 17:36       ` Tony Asleson
2013-10-23 22:18         ` NeilBrown
2013-10-23 23:31           ` Chuck Lever
2013-10-24 15:56             ` Steve Dickson
2013-10-24 16:05               ` Chuck Lever
2013-10-28  3:39                 ` NeilBrown
2013-10-28 14:09                   ` Chuck Lever
2013-10-24  5:34           ` Tony Asleson
2013-10-22  8:30 ` Steve Dickson
2013-10-22  8:36   ` Steve Dickson
2013-10-28 22:35     ` NeilBrown
2013-11-04 15:33       ` Steve Dickson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20131022092519.4f4683a8@notabene.brown \
    --to=neilb@suse.de \
    --cc=SteveD@redhat.com \
    --cc=linux-nfs@vger.kernel.org \
    --cc=tasleson@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).