xref: /original-bsd/usr.sbin/amd/amd/umount_fs.c (revision ca98dac2)
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