1 /* 2 * Copyright (c) 1990 Jan-Simon Pendry 3 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 4 * Copyright (c) 1990 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Jan-Simon Pendry at Imperial College, London. 9 * 10 * %sccs.include.redist.c% 11 * 12 * @(#)umount_fs.c 5.4 (Berkeley) 02/09/92 13 * 14 * $Id: umount_fs.c,v 5.2.2.1 1992/02/09 15:09:10 jsp beta $ 15 * 16 */ 17 18 #include "am.h" 19 20 #ifdef NEED_UMOUNT_BSD 21 22 #include <sys/mount.h> /* For MNT_NOFORCE */ 23 24 int umount_fs P((char *fs_name)); 25 int umount_fs(fs_name) 26 char *fs_name; 27 { 28 int error; 29 30 eintr: 31 error = unmount(fs_name, MNT_NOFORCE); 32 if (error < 0) 33 error = errno; 34 35 switch (error) { 36 case EINVAL: 37 case ENOTBLK: 38 case ENOENT: 39 plog(XLOG_WARNING, "unmount: %s is not mounted", fs_name); 40 error = 0; /* Not really an error */ 41 break; 42 43 case EINTR: 44 #ifdef DEBUG 45 /* not sure why this happens, but it does. ask kirk one day... */ 46 dlog("%s: unmount: %m", fs_name); 47 #endif /* DEBUG */ 48 goto eintr; 49 50 #ifdef DEBUG 51 default: 52 dlog("%s: unmount: %m", fs_name); 53 break; 54 #endif /* DEBUG */ 55 } 56 57 return error; 58 } 59 60 #endif /* NEED_UMOUNT_BSD */ 61 62 #ifdef NEED_UMOUNT_OSF 63 64 #include <sys/mount.h> /* For MNT_NOFORCE */ 65 66 int umount_fs(fs_name) 67 char *fs_name; 68 { 69 int error; 70 71 eintr: 72 error = umount(fs_name, MNT_NOFORCE); 73 if (error < 0) 74 error = errno; 75 76 switch (error) { 77 case EINVAL: 78 case ENOTBLK: 79 plog(XLOG_WARNING, "unmount: %s is not mounted", fs_name); 80 error = 0; /* Not really an error */ 81 break; 82 83 case ENOENT: 84 plog(XLOG_ERROR, "mount point %s: %m", fs_name); 85 break; 86 87 case EINTR: 88 #ifdef DEBUG 89 /* not sure why this happens, but it does. ask kirk one day... */ 90 dlog("%s: unmount: %m", fs_name); 91 #endif /* DEBUG */ 92 goto eintr; 93 94 #ifdef DEBUG 95 default: 96 dlog("%s: unmount: %m", fs_name); 97 break; 98 #endif /* DEBUG */ 99 } 100 101 return error; 102 } 103 104 #endif /* NEED_UMOUNT_OSF */ 105 106 #ifdef NEED_UMOUNT_FS 107 108 int umount_fs(fs_name) 109 char *fs_name; 110 { 111 mntlist *mlist, *mp, *mp_save = 0; 112 int error = 0; 113 114 mp = mlist = read_mtab(fs_name); 115 116 /* 117 * Search the mount table looking for 118 * the correct (ie last) matching entry 119 */ 120 while (mp) { 121 if (strcmp(mp->mnt->mnt_fsname, fs_name) == 0 || 122 strcmp(mp->mnt->mnt_dir, fs_name) == 0) 123 mp_save = mp; 124 mp = mp->mnext; 125 } 126 127 if (mp_save) { 128 #ifdef DEBUG 129 dlog("Trying unmount(%s)", mp_save->mnt->mnt_dir); 130 #endif /* DEBUG */ 131 /* 132 * This unmount may hang leaving this 133 * process with an exlusive lock on 134 * /etc/mtab. Therefore it is necessary 135 * to unlock mtab, do the unmount, then 136 * lock mtab (again) and reread it and 137 * finally update it. 138 */ 139 unlock_mntlist(); 140 if (UNMOUNT_TRAP(mp_save->mnt) < 0) { 141 switch (error = errno) { 142 case EINVAL: 143 case ENOTBLK: 144 plog(XLOG_WARNING, "unmount: %s is not mounted", mp_save->mnt->mnt_dir); 145 error = 0; /* Not really an error */ 146 break; 147 148 case ENOENT: 149 plog(XLOG_ERROR, "mount point %s: %m", mp_save->mnt->mnt_dir); 150 break; 151 152 default: 153 #ifdef DEBUG 154 dlog("%s: unmount: %m", mp_save->mnt->mnt_dir); 155 #endif /* DEBUG */ 156 break; 157 } 158 } 159 #ifdef DEBUG 160 dlog("Finished unmount(%s)", mp_save->mnt->mnt_dir); 161 #endif 162 163 164 #ifdef UPDATE_MTAB 165 if (!error) { 166 free_mntlist(mlist); 167 mp = mlist = read_mtab(fs_name); 168 169 /* 170 * Search the mount table looking for 171 * the correct (ie last) matching entry 172 */ 173 mp_save = 0; 174 while (mp) { 175 if (strcmp(mp->mnt->mnt_fsname, fs_name) == 0 || 176 strcmp(mp->mnt->mnt_dir, fs_name) == 0) 177 mp_save = mp; 178 mp = mp->mnext; 179 } 180 181 if (mp_save) { 182 mnt_free(mp_save->mnt); 183 mp_save->mnt = 0; 184 rewrite_mtab(mlist); 185 } 186 } 187 #endif /* UPDATE_MTAB */ 188 } else { 189 plog(XLOG_ERROR, "Couldn't find how to unmount %s", fs_name); 190 /* 191 * Assume it is already unmounted 192 */ 193 error = 0; 194 } 195 196 free_mntlist(mlist); 197 198 return error; 199 } 200 201 #endif /* NEED_UMOUNT_FS */ 202