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