Index: kern/kern_shutdown.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_shutdown.c,v retrieving revision 1.174 diff -u -r1.174 kern_shutdown.c --- kern/kern_shutdown.c 12 Apr 2005 05:45:58 -0000 1.174 +++ kern/kern_shutdown.c 10 May 2005 17:09:02 -0000 @@ -64,6 +64,9 @@ #include #include +#include +#include + #include #include #include @@ -374,6 +377,12 @@ if (!first_buf_printf) printf("Final sync complete\n"); /* + * Disable swapping + */ + if (panicstr == 0) + swap_swapoff_all(curthread); + + /* * Unmount filesystems */ if (panicstr == 0) Index: kern/vfs_subr.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_subr.c,v retrieving revision 1.624 diff -u -r1.624 vfs_subr.c --- kern/vfs_subr.c 6 May 2005 02:48:20 -0000 1.624 +++ kern/vfs_subr.c 11 May 2005 01:04:03 -0000 @@ -2660,6 +2660,7 @@ { struct mount *mp; struct thread *td; + struct vnode *vp; int error; KASSERT(curthread != NULL, ("vfs_unmountall: NULL curthread")); @@ -2669,6 +2670,39 @@ */ while(!TAILQ_EMPTY(&mountlist)) { mp = TAILQ_LAST(&mountlist, mntlist); + +#ifdef DIAGNOSTIC + printf("vfs_unmountall: TAILQ_LAST gave us: %s\n", + mp->mnt_stat.f_mntfromname); +#endif /* DIAGNOSTIC */ + + if(!strcmp(mp->mnt_stat.f_mntfromname, "devfs") && + TAILQ_FIRST(&mountlist) != + TAILQ_LAST(&mountlist, mntlist)) + { + mp = TAILQ_PREV(mp, mntlist, mnt_list); + printf("vfs_unmount_all: Found devfs. " + "deferring unmount.\n"); + } + +#ifdef DIAGNOSTIC + printf("vfs_unmountall: unmounting: %s\n", + mp->mnt_stat.f_mntfromname); +#endif /* DIAGNOSTIC */ + + if(!strcmp(mp->mnt_stat.f_mntfromname, "devfs")) + { + TAILQ_FOREACH(vp, &mp->mnt_nvnodelist, v_nmntvnodes) + { + if(!(vp->v_vflag & VI_FREE)) + /*vp->v_usecount > 0)*/ + { + vn_printf(vp, "%s", ""); + /*VOP_DESTROYVOBJECT(vp);*/ + } + } + } + error = dounmount(mp, MNT_FORCE, td); if (error) { TAILQ_REMOVE(&mountlist, mp, mnt_list); @@ -2682,6 +2716,9 @@ /* The unmount has removed mp from the mountlist */ } } +#ifdef DIAGNOSTIC + printf("vfs_unmountall(): done!\n"); +#endif /* DIAGNOSTIC */ } /* Index: vm/swap_pager.c =================================================================== RCS file: /home/ncvs/src/sys/vm/swap_pager.c,v retrieving revision 1.273 diff -u -r1.273 swap_pager.c --- vm/swap_pager.c 20 May 2005 21:26:05 -0000 1.273 +++ vm/swap_pager.c 24 May 2005 02:21:30 -0000 @@ -2193,6 +2193,60 @@ return (error); } + + +/* + * swap_swapoff_all(thread) - Disable all swap for system shutdown. This + * function exists because of the bad design of swapoff with its requirement + * for a pathname instead of a swap index. To get around the overhead of VFS + * lookups, we iterate through the swap tailq, force page-ins then remove the + * reference to each sw in queue. + */ +void +swap_swapoff_all(struct thread *td) +{ + struct swdevt *sp; + + /* printf("swap_swapoff_all: called!\n"); */ + KASSERT((nswapdev > -1), ("nswapdev is negative: %i", nswapdev)); + + mtx_lock(&sw_dev_mtx); + sp = TAILQ_FIRST(&swtailq); + + while (nswapdev) + { + /* XXX When the system is going down, it should be safe to page + * anything on swap back in without any issues, as all user + * processes have been killed off. + */ + sp->sw_flags |= SW_CLOSING; + mtx_unlock(&sw_dev_mtx); + + /*printf("swap_swapoff_all: Iterating in loop...\n"); */ + swap_pager_swapoff(sp); + + sp->sw_close(td, sp); + sp->sw_id = NULL; + + nswapdev--; + + mtx_lock(&sw_dev_mtx); + TAILQ_REMOVE(&swtailq, sp, sw_list); + + sp = TAILQ_FIRST(&swtailq); + free(sp, M_VMPGDATA); + } + mtx_unlock(&sw_dev_mtx); + + swap_pager_full = 2; + swap_pager_almost_full = 1; + swdevhd = NULL; + + /* printf("swap_swapoff_all: done!\n"); */ +} + + + void swap_pager_status(int *total, int *used) { Index: vm/swap_pager.h =================================================================== RCS file: /home/ncvs/src/sys/vm/swap_pager.h,v retrieving revision 1.50 diff -u -r1.50 swap_pager.h --- vm/swap_pager.h 7 Jan 2005 02:29:27 -0000 1.50 +++ vm/swap_pager.h 10 May 2005 17:54:41 -0000 @@ -50,6 +50,7 @@ int swap_pager_isswapped(vm_object_t, struct swdevt *); int swap_pager_reserve(vm_object_t, vm_pindex_t, vm_size_t); void swap_pager_status(int *total, int *used); +void swap_swapoff_all(struct thread *); #endif /* _KERNEL */ #endif /* _VM_SWAP_PAGER_H_ */