summaryrefslogtreecommitdiffstats
path: root/glusterfsd/src/glusterfsd.c
diff options
context:
space:
mode:
authorNiels de Vos <ndevos@redhat.com>2015-01-01 13:15:45 +0100
committerVijay Bellur <vbellur@redhat.com>2015-03-18 22:16:34 -0700
commita1755ee2765f3d1c9c26d51a49ad63d133932710 (patch)
tree71982c048f2c6deb8d05e894f14d568a1da978a4 /glusterfsd/src/glusterfsd.c
parent5394f3cf60b0815d2919d24e9945ba47e3bb1f9b (diff)
glusterfsd: add "print-netgroups" and "print-exports" command
NFS now has the ability to use a separate file for "netgroups" and "exports". An administrator should have the ability to check the validity of the files before applying the configuration. The "glusterfsd" command now has the following additional arguments that can be used to check the configuration: --print-netgroups: Validate the netgroups file and print it out --print-exports: Validate the exports file and print it out BUG: 1143880 Change-Id: I24c40d50110d49d8290f9fd916742f7e4d0df85f URL: http://www.gluster.org/community/documentation/index.php/Features/Exports_Netgroups_Authentication Original-author: Shreyas Siravara <shreyas.siravara@gmail.com> CC: Richard Wareing <rwareing@fb.com> CC: Jiffin Tony Thottan <jthottan@redhat.com> Signed-off-by: Niels de Vos <ndevos@redhat.com> Reviewed-on: http://review.gluster.org/9365 Reviewed-by: Vijay Bellur <vbellur@redhat.com> Tested-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'glusterfsd/src/glusterfsd.c')
-rw-r--r--glusterfsd/src/glusterfsd.c241
1 files changed, 240 insertions, 1 deletions
diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c
index c410ffd40d9..9a174c4bdae 100644
--- a/glusterfsd/src/glusterfsd.c
+++ b/glusterfsd/src/glusterfsd.c
@@ -19,6 +19,7 @@
#include <netdb.h>
#include <signal.h>
#include <libgen.h>
+#include <dlfcn.h>
#include <sys/utsname.h>
@@ -69,6 +70,8 @@
#include "rpc-clnt.h"
#include "syncop.h"
#include "client_t.h"
+#include "netgroups.h"
+#include "exports.h"
#include "daemon.h"
@@ -152,6 +155,12 @@ static struct argp_option gf_options[] = {
"Mount the filesystem with POSIX ACL support"},
{"selinux", ARGP_SELINUX_KEY, 0, 0,
"Enable SELinux label (extened attributes) support on inodes"},
+
+ {"print-netgroups", ARGP_PRINT_NETGROUPS, "NETGROUP-FILE", 0,
+ "Validate the netgroups file and print it out"},
+ {"print-exports", ARGP_PRINT_EXPORTS, "EXPORTS-FILE", 0,
+ "Validate the exports file and print it out"},
+
{"volfile-max-fetch-attempts", ARGP_VOLFILE_MAX_FETCH_ATTEMPTS, "0",
OPTION_HIDDEN, "Maximum number of attempts to fetch the volfile"},
{"aux-gfid-mount", ARGP_AUX_GFID_MOUNT_KEY, 0, 0,
@@ -787,6 +796,14 @@ parse_opts (int key, char *arg, struct argp_state *state)
cmd_args->worm = 1;
break;
+ case ARGP_PRINT_NETGROUPS:
+ cmd_args->print_netgroups = arg;
+ break;
+
+ case ARGP_PRINT_EXPORTS:
+ cmd_args->print_exports = arg;
+ break;
+
case ARGP_MAC_COMPAT_KEY:
if (!arg)
arg = "on";
@@ -1519,6 +1536,195 @@ gf_check_and_set_mem_acct (int argc, char *argv[])
}
}
+/**
+ * print_exports_file - Print out & verify the syntax
+ * of the exports file specified
+ * in the parameter.
+ *
+ * @exports_file : Path of the exports file to print & verify
+ *
+ * @return : success: 0 when successfully parsed
+ * failure: 1 when failed to parse one or more lines
+ * -1 when other critical errors (dlopen () etc)
+ * Critical errors are treated differently than parse errors. Critical
+ * errors terminate the program immediately here and print out different
+ * error messages. Hence there are different return values.
+ */
+int
+print_exports_file (const char *exports_file)
+{
+ void *libhandle = NULL;
+ char *libpathfull = NULL;
+ struct exports_file *file = NULL;
+ int ret = 0;
+
+ int (*exp_file_parse)(const char *filepath,
+ struct exports_file **expfile,
+ struct mount3_state *ms) = NULL;
+ void (*exp_file_print)(const struct exports_file *file) = NULL;
+ void (*exp_file_deinit)(struct exports_file *ptr) = NULL;
+
+ /* XLATORDIR passed through a -D flag to GCC */
+ ret = gf_asprintf (&libpathfull, "%s/%s/server.so", XLATORDIR,
+ "nfs");
+ if (ret < 0) {
+ gf_log ("glusterfs", GF_LOG_CRITICAL, "asprintf () failed.");
+ ret = -1;
+ goto out;
+ }
+
+ /* Load up the library */
+ libhandle = dlopen (libpathfull, RTLD_NOW);
+ if (!libhandle) {
+ gf_log ("glusterfs", GF_LOG_CRITICAL,
+ "Error loading NFS server library : "
+ "%s\n", dlerror ());
+ ret = -1;
+ goto out;
+ }
+
+ /* Load up the function */
+ exp_file_parse = dlsym (libhandle, "exp_file_parse");
+ if (!exp_file_parse) {
+ gf_log ("glusterfs", GF_LOG_CRITICAL,
+ "Error finding function exp_file_parse "
+ "in symbol.");
+ ret = -1;
+ goto out;
+ }
+
+ /* Parse the file */
+ ret = exp_file_parse (exports_file, &file, NULL);
+ if (ret < 0) {
+ ret = 1; /* This means we failed to parse */
+ goto out;
+ }
+
+ /* Load up the function */
+ exp_file_print = dlsym (libhandle, "exp_file_print");
+ if (!exp_file_print) {
+ gf_log ("glusterfs", GF_LOG_CRITICAL,
+ "Error finding function exp_file_print in symbol.");
+ ret = -1;
+ goto out;
+ }
+
+ /* Print it out to screen */
+ exp_file_print (file);
+
+ /* Load up the function */
+ exp_file_deinit = dlsym (libhandle, "exp_file_deinit");
+ if (!exp_file_deinit) {
+ gf_log ("glusterfs", GF_LOG_CRITICAL,
+ "Error finding function exp_file_deinit in lib.");
+ ret = -1;
+ goto out;
+ }
+
+ /* Free the file */
+ exp_file_deinit (file);
+
+out:
+ if (libhandle)
+ dlclose(libhandle);
+ GF_FREE (libpathfull);
+ return ret;
+}
+
+
+/**
+ * print_netgroups_file - Print out & verify the syntax
+ * of the netgroups file specified
+ * in the parameter.
+ *
+ * @netgroups_file : Path of the netgroups file to print & verify
+ * @return : success: 0 when successfully parsed
+ * failure: 1 when failed to parse one more more lines
+ * -1 when other critical errors (dlopen () etc)
+ *
+ * We have multiple returns here because for critical errors, we abort
+ * operations immediately and exit. For example, if we can't load the
+ * NFS server library, then we have a real bad problem so we don't continue.
+ * Or if we cannot allocate anymore memory, we don't want to continue. Also,
+ * we want to print out a different error messages based on the ret value.
+ */
+int
+print_netgroups_file (const char *netgroups_file)
+{
+ void *libhandle = NULL;
+ char *libpathfull = NULL;
+ struct netgroups_file *file = NULL;
+ int ret = 0;
+
+ struct netgroups_file *(*ng_file_parse)(const char *file_path) = NULL;
+ void (*ng_file_print)(const struct netgroups_file *file) = NULL;
+ void (*ng_file_deinit)(struct netgroups_file *ptr) = NULL;
+
+ /* XLATORDIR passed through a -D flag to GCC */
+ ret = gf_asprintf (&libpathfull, "%s/%s/server.so", XLATORDIR,
+ "nfs");
+ if (ret < 0) {
+ gf_log ("glusterfs", GF_LOG_CRITICAL, "asprintf () failed.");
+ ret = -1;
+ goto out;
+ }
+ /* Load up the library */
+ libhandle = dlopen (libpathfull, RTLD_NOW);
+ if (!libhandle) {
+ gf_log ("glusterfs", GF_LOG_CRITICAL,
+ "Error loading NFS server library : %s\n", dlerror ());
+ ret = -1;
+ goto out;
+ }
+
+ /* Load up the function */
+ ng_file_parse = dlsym (libhandle, "ng_file_parse");
+ if (!ng_file_parse) {
+ gf_log ("glusterfs", GF_LOG_CRITICAL,
+ "Error finding function ng_file_parse in symbol.");
+ ret = -1;
+ goto out;
+ }
+
+ /* Parse the file */
+ file = ng_file_parse (netgroups_file);
+ if (!file) {
+ ret = 1; /* This means we failed to parse */
+ goto out;
+ }
+
+ /* Load up the function */
+ ng_file_print = dlsym (libhandle, "ng_file_print");
+ if (!ng_file_print) {
+ gf_log ("glusterfs", GF_LOG_CRITICAL,
+ "Error finding function ng_file_print in symbol.");
+ ret = -1;
+ goto out;
+ }
+
+ /* Print it out to screen */
+ ng_file_print (file);
+
+ /* Load up the function */
+ ng_file_deinit = dlsym (libhandle, "ng_file_deinit");
+ if (!ng_file_deinit) {
+ gf_log ("glusterfs", GF_LOG_CRITICAL,
+ "Error finding function ng_file_deinit in lib.");
+ ret = -1;
+ goto out;
+ }
+
+ /* Free the file */
+ ng_file_deinit (file);
+
+out:
+ if (libhandle)
+ dlclose(libhandle);
+ GF_FREE (libpathfull);
+ return ret;
+}
+
+
int
parse_cmdline (int argc, char *argv[], glusterfs_ctx_t *ctx)
{
@@ -1539,6 +1745,22 @@ parse_cmdline (int argc, char *argv[], glusterfs_ctx_t *ctx)
}
argp_parse (&argp, argc, argv, ARGP_IN_ORDER, NULL, cmd_args);
+ if (cmd_args->print_netgroups) {
+ /* When this option is set we don't want to do anything else
+ * except for printing & verifying the netgroups file.
+ */
+ ret = 0;
+ goto out;
+ }
+
+ if (cmd_args->print_exports) {
+ /* When this option is set we don't want to do anything else
+ * except for printing & verifying the exports file.
+ */
+ ret = 0;
+ goto out;
+ }
+
ctx->secure_mgmt = cmd_args->secure_mgmt;
@@ -2006,6 +2228,7 @@ main (int argc, char *argv[])
glusterfs_ctx_t *ctx = NULL;
int ret = -1;
char cmdlinestr[PATH_MAX] = {0,};
+ cmd_args_t *cmd = NULL;
gf_check_and_set_mem_acct (argc, argv);
@@ -2029,6 +2252,23 @@ main (int argc, char *argv[])
ret = parse_cmdline (argc, argv, ctx);
if (ret)
goto out;
+ cmd = &ctx->cmd_args;
+ if (cmd->print_netgroups) {
+ /* If this option is set we want to print & verify the file,
+ * set the return value (exit code in this case) and exit.
+ */
+ ret = print_netgroups_file (cmd->print_netgroups);
+ goto out;
+ }
+
+ if (cmd->print_exports) {
+ /* If this option is set we want to print & verify the file,
+ * set the return value (exit code in this case)
+ * and exit.
+ */
+ ret = print_exports_file (cmd->print_exports);
+ goto out;
+ }
ret = logging_init (ctx, argv[0]);
if (ret)
@@ -2074,6 +2314,5 @@ main (int argc, char *argv[])
out:
// glusterfs_ctx_destroy (ctx);
-
return ret;
}