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