1/* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 45 unchanged lines hidden (view full) --- 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 */ 60 61#include <sys/cdefs.h> |
62__FBSDID("$FreeBSD: head/sys/kern/vfs_mount.c 132902 2004-07-30 22:08:52Z phk $"); |
63 64#include <sys/param.h> 65#include <sys/conf.h> 66#include <sys/cons.h> 67#include <sys/jail.h> 68#include <sys/kernel.h> 69#include <sys/linker.h> 70#include <sys/mac.h> --- 28 unchanged lines hidden (view full) --- 99 100static void checkdirs(struct vnode *olddp, struct vnode *newdp); 101static void gets(char *cp); 102static int vfs_domount(struct thread *td, const char *fstype, 103 char *fspath, int fsflags, void *fsdata, int compat); 104static int vfs_mount_alloc(struct vnode *dvp, struct vfsconf *vfsp, 105 const char *fspath, struct thread *td, struct mount **mpp); 106static int vfs_mountroot_ask(void); |
107static int vfs_mountroot_try(const char *mountfrom); |
108static int vfs_donmount(struct thread *td, int fsflags, 109 struct uio *fsoptions); 110 111static int usermount = 0; 112SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, 113 "Unprivileged users may mount and unmount file systems"); 114 115MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure"); --- 27 unchanged lines hidden (view full) --- 143static char *cdrom_rootdevnames[] = { 144 "cd9660:cd0", 145 "cd9660:acd0", 146 NULL 147}; 148 149/* legacy find-root code */ 150char *rootdevnames[2] = {NULL, NULL}; |
151struct cdev *rootdev = NULL; |
152#ifdef ROOTDEVNAME 153const char *ctrootdevname = ROOTDEVNAME; 154#else 155const char *ctrootdevname = NULL; 156#endif |
157 158/* 159 * Has to be dynamic as the value of rootdev can change; however, it can't 160 * change after the root is mounted, so a user process can't access this 161 * sysctl until after the value is unchangeable. 162 */ 163static int 164sysctl_rootdev(SYSCTL_HANDLER_ARGS) --- 657 unchanged lines hidden (view full) --- 822 } 823 VOP_UNLOCK(vp, 0, td); 824 825 /* XXXMAC: pass to vfs_mount_alloc? */ 826 if (compat == 0) 827 mp->mnt_optnew = fsdata; 828 } 829 /* |
830 * Check if the fs implements the type VFS_[O]MOUNT() |
831 * function we are looking for. 832 */ |
833 if ((compat == 0) == (mp->mnt_op->vfs_omount != NULL)) { |
834 printf("%s doesn't support the %s mount syscall\n", 835 mp->mnt_vfc->vfc_name, compat ? "old" : "new"); 836 VI_LOCK(vp); 837 vp->v_iflag &= ~VI_MOUNT; 838 VI_UNLOCK(vp); 839 if (mp->mnt_flag & MNT_UPDATE) 840 vfs_unbusy(mp, td); 841 else --- 11 unchanged lines hidden (view full) --- 853 mp->mnt_kern_flag |= MNTK_WANTRDWR; 854 mp->mnt_flag &=~ MNT_UPDATEMASK; 855 mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE); 856 /* 857 * Mount the filesystem. 858 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they 859 * get. No freeing of cn_pnbuf. 860 */ |
861 if (compat) 862 error = VFS_OMOUNT(mp, fspath, fsdata, td); 863 else 864 error = VFS_MOUNT(mp, td); |
865 if (!error) { 866 if (mp->mnt_opt != NULL) 867 vfs_freeopts(mp->mnt_opt); 868 mp->mnt_opt = mp->mnt_optnew; 869 } 870 /* 871 * Prevent external consumers of mount options from reading 872 * mnt_optnew. --- 323 unchanged lines hidden (view full) --- 1196 1197/* 1198 * Find and mount the root filesystem 1199 */ 1200void 1201vfs_mountroot(void) 1202{ 1203 char *cp; |
1204 int error, i, asked = 0; |
1205 |
1206 1207 /* |
1208 * Wait for GEOM to settle down |
1209 */ |
1210 g_waitidle(); 1211 |
1212 /* |
1213 * We are booted with instructions to prompt for the root filesystem. |
1214 */ |
1215 if (boothowto & RB_ASKNAME) { |
1216 if (!vfs_mountroot_ask()) 1217 return; |
1218 asked = 1; |
1219 } 1220 1221 /* |
1222 * The root filesystem information is compiled in, and we are 1223 * booted with instructions to use it. 1224 */ 1225 if (ctrootdevname != NULL && (boothowto & RB_DFLTROOT)) { 1226 if (!vfs_mountroot_try(ctrootdevname)) 1227 return; 1228 ctrootdevname = NULL; 1229 } 1230 1231 /* |
1232 * We've been given the generic "use CDROM as root" flag. This is 1233 * necessary because one media may be used in many different 1234 * devices, so we need to search for them. 1235 */ 1236 if (boothowto & RB_CDROM) { 1237 for (i = 0; cdrom_rootdevnames[i] != NULL; i++) { 1238 if (!vfs_mountroot_try(cdrom_rootdevnames[i])) 1239 return; 1240 } 1241 } 1242 1243 /* 1244 * Try to use the value read by the loader from /etc/fstab, or 1245 * supplied via some other means. This is the preferred 1246 * mechanism. 1247 */ |
1248 cp = getenv("vfs.root.mountfrom"); 1249 if (cp != NULL) { |
1250 error = vfs_mountroot_try(cp); 1251 freeenv(cp); 1252 if (!error) 1253 return; 1254 } 1255 1256 /* |
1257 * Try values that may have been computed by code during boot |
1258 */ 1259 if (!vfs_mountroot_try(rootdevnames[0])) 1260 return; 1261 if (!vfs_mountroot_try(rootdevnames[1])) 1262 return; 1263 1264 /* |
1265 * If we (still) have a compiled-in default, try it. |
1266 */ |
1267 if (ctrootdevname != NULL) 1268 if (!vfs_mountroot_try(ctrootdevname)) |
1269 return; |
1270 1271 /* 1272 * Everything so far has failed, prompt on the console if we haven't 1273 * already tried that. 1274 */ |
1275 if (!asked) 1276 if (!vfs_mountroot_ask()) 1277 return; |
1278 panic("Root mount failed, startup aborted."); 1279} 1280 1281/* 1282 * Mount (mountfrom) as the root filesystem. 1283 */ 1284static int |
1285vfs_mountroot_try(const char *mountfrom) |
1286{ 1287 struct mount *mp; 1288 char *vfsname, *path; 1289 const char *devname; 1290 int error; 1291 char patt[32]; 1292 int s; 1293 --- 21 unchanged lines hidden (view full) --- 1315 error = vfs_rootmountalloc(vfsname, path[0] != 0 ? path : ROOTNAME, 1316 &mp); 1317 if (error != 0) { 1318 printf("Can't allocate root mount for filesystem '%s': %d\n", 1319 vfsname, error); 1320 goto done; 1321 } 1322 |
1323 /* 1324 * do our best to set rootdev 1325 * XXX: This does not belong here! 1326 */ 1327 if (path[0] != '\0') { 1328 struct cdev *diskdev; 1329 diskdev = getdiskbyname(path); 1330 if (diskdev != NULL) 1331 rootdev = diskdev; 1332 else 1333 printf("setrootbyname failed\n"); 1334 } |
1335 1336 /* If the root device is a type "memory disk", mount RW */ 1337 if (rootdev != NULL && devsw(rootdev) != NULL) { 1338 devname = devtoname(rootdev); 1339 if (devname[0] == 'm' && devname[1] == 'd') 1340 mp->mnt_flag &= ~MNT_RDONLY; 1341 } 1342 |
1343 error = VFS_OMOUNT(mp, NULL, NULL, curthread); |
1344 1345done: 1346 if (vfsname != NULL) 1347 free(vfsname, M_MOUNT); 1348 if (path != NULL) 1349 free(path, M_MOUNT); 1350 if (error != 0) { 1351 if (mp != NULL) --- 113 unchanged lines hidden (view full) --- 1465 vfsp = vfs_byname("devfs"); 1466 if (vfsp == NULL) 1467 break; 1468 error = vfs_mount_alloc(NULLVP, vfsp, "/dev", td, &mp); 1469 if (error) 1470 break; 1471 mp->mnt_flag |= MNT_RDONLY; 1472 |
1473 error = VFS_MOUNT(mp, curthread); |
1474 if (error) 1475 break; 1476 VFS_START(mp, 0, td); 1477 VFS_ROOT(mp, &vroot, td); 1478 VOP_UNLOCK(vroot, 0, td); 1479 1480 NDINIT(&nid, LOOKUP, NOCACHE|FOLLOW, 1481 UIO_SYSSPACE, cp, curthread); --- 11 unchanged lines hidden (view full) --- 1493 1494 if (vroot != NULL) 1495 VFS_UNMOUNT(mp, 0, td); 1496 if (mp != NULL) 1497 vfs_mount_destroy(mp, td); 1498 return (dev); 1499} 1500 |
1501/* Show the struct cdev *for a disk specified by name */ 1502#ifdef DDB 1503DB_SHOW_COMMAND(disk, db_getdiskbyname) 1504{ 1505 struct cdev *dev; 1506 1507 if (modif[0] == '\0') { 1508 db_error("usage: show disk/devicename"); --- 97 unchanged lines hidden --- |