1    	/*
2    	 * vim:noexpandtab:shiftwidth=8:tabstop=8:
3    	 *
4    	 * Copyright (C) Panasas Inc., 2011
5    	 * Author: Jim Lieb jlieb@panasas.com
6    	 *
7    	 * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
8    	 *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
9    	 *                Patrice LUCAS     patrice.lucas@cea.fr
10   	 *
11   	 *
12   	 * This program is free software; you can redistribute it and/or
13   	 * modify it under the terms of the GNU Lesser General Public
14   	 * License as published by the Free Software Foundation; either
15   	 * version 3 of the License, or (at your option) any later version.
16   	 *
17   	 * This program is distributed in the hope that it will be useful,
18   	 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19   	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20   	 * Lesser General Public License for more details.
21   	 *
22   	 * You should have received a copy of the GNU Lesser General Public
23   	 * License along with this library; if not, write to the Free Software
24   	 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
25   	 *
26   	 * -------------
27   	 */
28   	
29   	/* main.c
30   	 * Module core functions
31   	 */
32   	
33   	#include "config.h"
34   	
35   	#include <libgen.h>		/* used for 'dirname' */
36   	#include <pthread.h>
37   	#include <string.h>
38   	#include <limits.h>
39   	#include <sys/types.h>
40   	#include "gsh_list.h"
41   	#include "fsal.h"
42   	#include "FSAL/fsal_init.h"
43   	#include "fsal_handle_syscalls.h"
44   	#include "vfs_methods.h"
45   	
46   	/* VFS FSAL module private storage
47   	 */
48   	
49   	/* defined the set of attributes supported with POSIX */
50   	#ifndef ENABLE_VFS_DEBUG_ACL
51   	#define VFS_SUPPORTED_ATTRIBUTES ((const attrmask_t) (ATTRS_POSIX | \
52   							      ATTR4_FS_LOCATIONS))
53   	#else
54   	#define VFS_SUPPORTED_ATTRIBUTES ((const attrmask_t) (ATTRS_POSIX | ATTR_ACL | \
55   							      ATTR4_FS_LOCATIONS))
56   	#endif
57   	
58   	const char myname[] = "VFS";
59   	
60   	/* my module private storage
61   	 */
62   	
63   	static struct vfs_fsal_module VFS = {
64   		.module = {
65   			.fs_info = {
66   				.maxfilesize = INT64_MAX,
67   				.maxlink = _POSIX_LINK_MAX,
68   				.maxnamelen = 1024,
69   				.maxpathlen = 1024,
70   				.no_trunc = true,
71   				.chown_restricted = true,
72   				.case_insensitive = false,
73   				.case_preserving = true,
74   				.lock_support = false,
75   				.lock_support_async_block = false,
76   				.named_attr = true,
77   				.unique_handles = true,
78   				.acl_support = FSAL_ACLSUPPORT_ALLOW,
79   				.homogenous = true,
80   				.supported_attrs = VFS_SUPPORTED_ATTRIBUTES,
81   				.maxread = FSAL_MAXIOSIZE,
82   				.maxwrite = FSAL_MAXIOSIZE,
83   				.link_supports_permission_checks = false,
84   				.expire_time_parent = -1,
85   			}
86   		},
87   		.only_one_user = false
88   	};
89   	
90   	static struct config_item vfs_params[] = {
91   		CONF_ITEM_BOOL("link_support", true, vfs_fsal_module,
92   			       module.fs_info.link_support),
93   		CONF_ITEM_BOOL("symlink_support", true, vfs_fsal_module,
94   			       module.fs_info.symlink_support),
95   		CONF_ITEM_BOOL("cansettime", true, vfs_fsal_module,
96   			       module.fs_info.cansettime),
97   		CONF_ITEM_UI64("maxread", 512, FSAL_MAXIOSIZE, FSAL_MAXIOSIZE,
98   			       vfs_fsal_module, module.fs_info.maxread),
99   		CONF_ITEM_UI64("maxwrite", 512, FSAL_MAXIOSIZE, FSAL_MAXIOSIZE,
100  			       vfs_fsal_module, module.fs_info.maxwrite),
101  		CONF_ITEM_MODE("umask", 0, vfs_fsal_module,
102  			       module.fs_info.umask),
103  		CONF_ITEM_BOOL("auth_xdev_export", false, vfs_fsal_module,
104  			       module.fs_info.auth_exportpath_xdev),
105  		CONF_ITEM_BOOL("only_one_user", false, vfs_fsal_module,
106  			       only_one_user),
107  		CONFIG_EOL
108  	};
109  	
110  	struct config_block vfs_param = {
111  		.dbus_interface_name = "org.ganesha.nfsd.config.fsal.vfs",
112  		.blk_desc.name = "VFS",
113  		.blk_desc.type = CONFIG_BLOCK,
114  		.blk_desc.u.blk.init = noop_conf_init,
115  		.blk_desc.u.blk.params = vfs_params,
116  		.blk_desc.u.blk.commit = noop_conf_commit
117  	};
118  	
119  	/* Module methods
120  	 */
121  	
122  	/* init_config
123  	 * must be called with a reference taken (via lookup_fsal)
124  	 */
125  	
126  	static fsal_status_t init_config(struct fsal_module *vfs_fsal_module,
127  					 config_file_t config_struct,
128  					 struct config_error_type *err_type)
129  	{
130  		struct vfs_fsal_module *vfs_module =
131  		    container_of(vfs_fsal_module, struct vfs_fsal_module, module);
132  	
133  	#ifdef F_OFD_GETLK
134  		int fd, rc;
135  		struct flock lock;
136  		char *temp_name;
137  	#endif
138  	
139  	#ifdef F_OFD_GETLK
140  		/* If on a system that might support OFD locks, verify them.
141  		 * Only if they exist will we declare lock support.
142  		 */
(1) Event cond_true: Condition "!!(component_log_level[COMPONENT_FSAL] >= NIV_INFO)", taking true branch.
(2) Event cond_true: Condition "!!(component_log_level[COMPONENT_FSAL] >= NIV_INFO)", taking true branch.
143  		LogInfo(COMPONENT_FSAL, "FSAL_VFS testing OFD Locks");
(3) Event cond_true: Condition "p_ == NULL", taking true branch.
144  		temp_name = gsh_strdup("/tmp/ganesha.nfsd.locktestXXXXXX");
(4) Event secure_temp: Calling "mkstemp" without securely setting umask first.
145  		fd = mkstemp(temp_name);
146  		if (fd >= 0) {
147  			lock.l_whence = SEEK_SET;
148  			lock.l_type = F_RDLCK;
149  			lock.l_start = 0;
150  			lock.l_len = 0;
151  			lock.l_pid = 0;
152  	
153  			rc = fcntl(fd, F_OFD_GETLK, &lock);
154  	
155  			if (rc == 0)
156  				vfs_module->module.fs_info.lock_support = true;
157  			else
158  				LogInfo(COMPONENT_FSAL, "Could not use OFD locks");
159  	
160  			close(fd);
161  			unlink(temp_name);
162  		} else {
163  			LogCrit(COMPONENT_FSAL,
164  				"Could not create file %s to test OFD locks",
165  				temp_name);
166  		}
167  		gsh_free(temp_name);
168  	#endif
169  	
170  		if (vfs_module->module.fs_info.lock_support)
171  			LogInfo(COMPONENT_FSAL, "FSAL_VFS enabling OFD Locks");
172  		else
173  			LogInfo(COMPONENT_FSAL, "FSAL_VFS disabling lock support");
174  	
175  		LogFullDebug(COMPONENT_FSAL,
176  			"Supported attributes default = 0x%" PRIx64,
177  			vfs_module->module.fs_info.supported_attrs);
178  		(void) load_config_from_parse(config_struct,
179  					      &vfs_param,
180  					      vfs_module,
181  					      true,
182  					      err_type);
183  		if (!config_error_is_harmless(err_type))
184  			return fsalstat(ERR_FSAL_INVAL, 0);
185  		display_fsinfo(&vfs_module->module);
186  		LogFullDebug(COMPONENT_FSAL,
187  			     "Supported attributes constant = 0x%" PRIx64,
188  			     VFS_SUPPORTED_ATTRIBUTES);
189  		LogDebug(COMPONENT_FSAL,
190  			 "FSAL INIT: Supported attributes mask = 0x%" PRIx64,
191  			 vfs_module->module.fs_info.supported_attrs);
192  		return fsalstat(ERR_FSAL_NO_ERROR, 0);
193  	}
194  	
195  	/* Module initialization.
196  	 * Called by dlopen() to register the module
197  	 * keep a private pointer to me in myself
198  	 */
199  	
200  	/* linkage to the exports and handle ops initializers
201  	 */
202  	
203  	MODULE_INIT void vfs_init(void)
204  	{
205  		int retval;
206  		struct fsal_module *myself = &VFS.module;
207  	
208  		retval = register_fsal(myself, myname, FSAL_MAJOR_VERSION,
209  				       FSAL_MINOR_VERSION, FSAL_ID_VFS);
210  		if (retval != 0) {
211  			fprintf(stderr, "VFS module failed to register");
212  			return;
213  		}
214  		myself->m_ops.create_export = vfs_create_export;
215  		myself->m_ops.update_export = vfs_update_export;
216  		myself->m_ops.init_config = init_config;
217  	
218  		/* Initialize the fsal_obj_handle ops for FSAL VFS/LUSTRE */
219  		vfs_handle_ops_init(&VFS.handle_ops);
220  	}
221  	
222  	MODULE_FINI void vfs_unload(void)
223  	{
224  		int retval;
225  	
226  		retval = unregister_fsal(&VFS.module);
227  		if (retval != 0) {
228  			fprintf(stderr, "VFS module failed to unregister");
229  			return;
230  		}
231  	}
232