Home | History | Annotate | Download | only in common
      1 //
      2 // CDDL HEADER START
      3 //
      4 // The contents of this file are subject to the terms of the
      5 // Common Development and Distribution License (the License).
      6 // You may not use this file except in compliance with the License.
      7 //
      8 // You can obtain a copy of the license at usr/src/CDDL.txt
      9 // or http://www.opensolaris.org/os/licensing.
     10 // See the License for the specific language governing permissions
     11 // and limitations under the License.
     12 //
     13 // When distributing Covered Code, include this CDDL HEADER in each
     14 // file and include the License file at usr/src/CDDL.txt.
     15 // If applicable, add the following below this CDDL HEADER, with the
     16 // fields enclosed by brackets [] replaced with your own identifying
     17 // information: Portions Copyright [yyyy] [name of copyright owner]
     18 //
     19 // CDDL HEADER END
     20 //
     21 
     22 //
     23 // Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24 // Use is subject to license terms.
     25 //
     26 
     27 #pragma ident	"@(#)pxfs_main.cc	1.66	08/05/20 SMI"
     28 
     29 //
     30 // The purpose of this file is to support C++ startup and shutdown methods
     31 // for module load and unload.
     32 //
     33 #include <sys/vfs.h>
     34 #include <sys/mount.h>
     35 
     36 #include <sys/sol_version.h>
     37 #include <solobj/solobj_handler.h>
     38 #include <pxfs/common/pxfslib.h>
     39 
     40 #include <h/pxfs.h>
     41 #include <pxfs/common/pxfslib.h>
     42 #include <pxfs/mount/mount_debug.h>
     43 #include <pxfs/mount/mount_replica_impl.h>
     44 #include <pxfs/mount/mount_client_impl.h>
     45 #include <pxfs/lock/fs_collection_impl.h>
     46 #include <pxfs/server/fs_base_impl.h>
     47 #include <pxfs/client/pxvfs.h>
     48 #include <pxfs/client/pxdir.h>
     49 #include <pxfs/bulkio/bulkio_impl.h>
     50 
     51 #if SOL_VERSION >= __s10
     52 #ifndef FSI
     53 #define	FSI // PSARC 2001/679 Storage Infrastructure: File System Interfaces
     54 #endif
     55 #endif
     56 
     57 extern void pxfs_check_assertions(void);
     58 extern int cl_flk_init(void);
     59 extern int px_vfs_init(void);
     60 extern void px_vfs_uninit(void);
     61 extern int px_vn_init(char *namep);
     62 extern void px_vn_uninit(void);
     63 extern int pgio_vn_init(void);
     64 extern void pgio_vn_uninit(void);
     65 
     66 extern void nlm_init(void);
     67 
     68 //
     69 // The following variable determines the highest version of pxfs software
     70 // that can be used to support a mounted file system. The version manager
     71 // provides information about the highest version of pxfs software that is
     72 // available on the cluster.
     73 //	1 = version 1
     74 //	2 = version 2
     75 //
     76 // This parameter can be set in "/etc/system". It is meant for debugging
     77 // and is not supported.
     78 //
     79 int	pxfs_software_mount_level = 2;
     80 
     81 //
     82 // This variable can be used to enable/disable fastwrites through /etc/system.
     83 // To enable fastwrite,  pxfs_fastwrite_enabled should be set to 1.
     84 // To disable fastwrite, pxfs_fastwrite_enabled should be set to 0.
     85 //
     86 // NOTE : Please make sure that it has the same value on all the nodes
     87 //	of the cluster.
     88 //
     89 
     90 
     91 int pxfs_fastwrite_enabled = 1;
     92 
     93 
     94 //
     95 // This section defines a set of operation functions for the proxy vfs.
     96 // The purpose of this set of operation function is to capture the
     97 // first mount and determine which version of pxfs software should
     98 // support this particular file system. The system will then replace
     99 // this set of operation functions with a set for that file system.
    100 //
    101 // This set of operation functions also supports a sync of all pxfs type
    102 // file systems.
    103 //
    104 // None of the other vfs functions should be called.
    105 //
    106 static int px_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr);
    107 static int px_mountroot(vfs_t *vfsp, enum whymountroot why);
    108 static int px_unmount(vfs_t *vfsp, int flags, cred_t *cr);
    109 static int px_root(vfs_t *vfsp, vnode_t **vpp);
    110 static int px_statvfs(vfs_t *vfsp, struct statvfs64 *sp);
    111 static int px_sync(vfs_t *vfsp, short flag, cred_t *cr);
    112 static int px_vget(vfs_t *vfsp, vnode_t **vpp, struct fid *fidp);
    113 static int px_swapvp(vfs_t *vfsp, vnode_t **vpp, char *nm);
    114 
    115 #ifdef FSI
    116 
    117 struct vfsops	*pxfs_vfs_opsp;
    118 
    119 //
    120 // pxfs_vfs_init - initializes the data structures, including the
    121 // operations vectors, for the pxfs vfs data structures.
    122 //
    123 extern "C" int
    124 pxfs_vfs_init(int fstype, char *)
    125 {
    126 	static const fs_operation_def_t px_vfsops_template[] = {
    127 		VFSNAME_MOUNT, (fs_generic_func_p)px_mount,
    128 		VFSNAME_UNMOUNT, (fs_generic_func_p)px_unmount,
    129 		VFSNAME_ROOT, (fs_generic_func_p)px_root,
    130 		VFSNAME_STATVFS, (fs_generic_func_p)px_statvfs,
    131 		VFSNAME_SYNC, (fs_generic_func_p)px_sync,
    132 		VFSNAME_VGET, (fs_generic_func_p)px_vget,
    133 		VFSNAME_MOUNTROOT, (fs_generic_func_p)px_mountroot,
    134 		"swapvp", (fs_generic_func_p)px_swapvp,
    135 		VFSNAME_FREEVFS, (fs_generic_func_p)fs_freevfs,
    136 		NULL, NULL
    137 	};
    138 
    139 	int error;
    140 
    141 	//
    142 	// Create the generic (version independent) vfs operations for pxfs
    143 	//
    144 	error = vfs_setfsops(fstype, px_vfsops_template, &pxfs_vfs_opsp);
    145 	if (error != 0) {
    146 		return (error);
    147 	}
    148 
    149 	//
    150 	// Create vfs operations for pxfs
    151 	//
    152 	error = px_vfs_init();
    153 	if (error != 0) {
    154 		(void) vfs_freevfsops_by_type(fstype);
    155 		return (error);
    156 	}
    157 
    158 	pxvfs::setfstype(fstype);
    159 	return (0);
    160 }
    161 
    162 //
    163 // pxfs_vfs_uninit - undoes the vfs initialization for pxfs
    164 //
    165 extern "C" void
    166 pxfs_vfs_uninit(int fstype)
    167 {
    168 	(void) vfs_freevfsops_by_type(fstype);
    169 	px_vfs_uninit();
    170 }
    171 
    172 //
    173 // pxfs_vn_init - initializes the vnode data structures for pxfs
    174 //
    175 extern "C" int
    176 pxfs_vn_init(char *namep)
    177 {
    178 	int error;
    179 
    180 	// Initialize vnode data structures for pxfs version 1
    181 	error = px_vn_init(namep);
    182 	if (error != 0) {
    183 		return (error);
    184 	}
    185 
    186 	// Initialize vnode data structures for bulkio subsystem
    187 	// for pxfs version 1
    188 	error = pgio_vn_init();
    189 	if (error != 0) {
    190 		px_vn_uninit();
    191 		return (error);
    192 	}
    193 
    194 	return (error);
    195 }
    196 
    197 #else	// FSI
    198 
    199 struct vfsops pxfs_vfsops = {
    200 
    201 	px_mount,
    202 	px_unmount,
    203 	px_root,
    204 	px_statvfs,
    205 	px_sync,
    206 	px_vget,
    207 	px_mountroot,
    208 	px_swapvp,
    209 	fs_freevfs
    210 };
    211 
    212 struct vfsops *pxfs_vfs_opsp = &pxfs_vfsops;
    213 
    214 //
    215 // pxfs_vfs_init is called when the pxfs module is loaded
    216 //
    217 extern "C" void
    218 pxfs_vfs_init(int fstype)
    219 {
    220 	pxvfs::setfstype(fstype);
    221 }
    222 
    223 #endif	// FSI
    224 
    225 static int
    226 px_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *credp)
    227 {
    228 	//
    229 	// A remount operation uses the already existing vfs of the mounted
    230 	// file system. The mounted file system will have a vfs that already
    231 	// has the correct operations vector for the chosen pxfs software
    232 	// version. Thus a remount operation should not arrive here.
    233 	//
    234 	ASSERT((vfsp->vfs_flag & VFS_REMOUNT) == 0);
    235 
    236 	ASSERT(uap->flags & MS_GLOBAL);
    237 	//
    238 	// "mount -g" mounts use the static form of the
    239 	// mount method.
    240 	//
    241 
    242 #ifdef FSI
    243 	vfs_setops(vfsp, pxfs_vfsopsp);
    244 #else
    245 	vfsp->vfs_op = pxfs_vfsopsp;
    246 #endif
    247 	//
    248 	// This method allocates
    249 	// the pxvfs object after determining the fs reference.
    250 	//
    251 	return (pxvfs::mount(vfsp, mvp, uap, credp));
    252 }
    253 
    254 static int
    255 px_unmount(vfs_t *, int, cred_t *)
    256 {
    257 	ASSERT(0);
    258 	return (ENOTSUP);
    259 }
    260 
    261 static int
    262 px_mountroot(vfs_t *, enum whymountroot)
    263 {
    264 	ASSERT(0);
    265 	return (ENOTSUP);
    266 }
    267 
    268 static int
    269 px_root(vfs_t *, vnode_t **)
    270 {
    271 	ASSERT(0);
    272 	return (ENOTSUP);
    273 }
    274 
    275 static int
    276 px_statvfs(vfs_t *, struct statvfs64 *)
    277 {
    278 	ASSERT(0);
    279 	return (ENOTSUP);
    280 }
    281 
    282 //
    283 // vfsp will be non-NULL if this is a sync in order to unmount one file system.
    284 // vfsp will be NULL if this is a sync of all PXFS type file systems.
    285 //
    286 static int
    287 px_sync(vfs_t *vfsp, short flag, cred_t *credp)
    288 {
    289 	if (vfsp != NULL) {
    290 		ASSERT(0);
    291 		return (ENOTSUP);
    292 	} else {
    293 		return (pxvfs::sync_all(flag, credp));
    294 	}
    295 }
    296 
    297 static int
    298 px_vget(vfs_t *, vnode_t **, struct fid *)
    299 {
    300 	ASSERT(0);
    301 	return (ENOTSUP);
    302 }
    303 
    304 static int
    305 px_swapvp(vfs_t *, vnode_t **, char *)
    306 {
    307 	ASSERT(0);
    308 	return (ENOTSUP);
    309 }
    310 
    311 extern "C" int
    312 stop_pxfs_server()
    313 {
    314 	// XXX need to check that all memory freed, no _unreferenced()
    315 	// pending, etc.
    316 	return (EBUSY);
    317 }
    318 
    319 //
    320 // When a cluster node is going down cleanly (using init 0), we don't
    321 // want that node to unmount all PXFS mounts on the way down (init 0
    322 // calls umountall).  So we disable global unmounts via a rc0.d/K
    323 // script that uses the cladm utility.  Any
    324 // unmounts after that will see 'unmount_disabled' set to true, and
    325 // return EBUSY.
    326 //
    327 extern "C" void
    328 pxfs_disable_unmounts()
    329 {
    330 	pxvfs::disable_unmounts();
    331 }
    332 
    333 void
    334 support_disable_unmount()
    335 {
    336 	extern void (*pxfs_disable_unmounts_ptr)(void);
    337 	pxfs_disable_unmounts_ptr = pxfs_disable_unmounts;
    338 }
    339 
    340 extern "C" int
    341 pxfs_main_startup()
    342 {
    343 	int	error;
    344 
    345 #ifdef	DEBUG
    346 	pxfs_check_assertions();
    347 #endif	/* DEBUG */
    348 
    349 	if ((error = Solobj_handler_kit::initialize()) != 0 ||
    350 
    351 	    (error = fs_base_ii::startup()) != 0 ||
    352 
    353 	    (error = mount_replica_impl::startup()) != 0 ||
    354 
    355 	    (error = fs_collection_impl::startup()) != 0 ||
    356 
    357 	    (error = cl_flk_init()) != 0 ||
    358 
    359 	    (error = pxdir::startup()) != 0 ||
    360 
    361 	    (error = access_cache::startup()) != 0 ||
    362 
    363 	    (error = bulkio_impl::startup()) != 0 ||
    364 
    365 	    (error = pxfs_mount_client_startup()) != 0 ||
    366 
    367 	    (error = pxvfs::startup()) != 0) {
    368 		return (error);
    369 	}
    370 	support_disable_unmount();
    371 	nlm_init();
    372 	return (0);
    373 }
    374