1398a5aebSmckusick /*
2398a5aebSmckusick * Copyright (c) 1990 Jan-Simon Pendry
3398a5aebSmckusick * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
4*4092c5ccSbostic * Copyright (c) 1990, 1993
5*4092c5ccSbostic * The Regents of the University of California. All rights reserved.
6398a5aebSmckusick *
7398a5aebSmckusick * This code is derived from software contributed to Berkeley by
8398a5aebSmckusick * Jan-Simon Pendry at Imperial College, London.
9398a5aebSmckusick *
10398a5aebSmckusick * %sccs.include.redist.c%
11398a5aebSmckusick *
12*4092c5ccSbostic * @(#)umount_fs.c 8.1 (Berkeley) 06/06/93
13c626267eSpendry *
14cc0207dcSpendry * $Id: umount_fs.c,v 5.2.2.1 1992/02/09 15:09:10 jsp beta $
15c626267eSpendry *
16398a5aebSmckusick */
17398a5aebSmckusick
18398a5aebSmckusick #include "am.h"
19398a5aebSmckusick
20398a5aebSmckusick #ifdef NEED_UMOUNT_BSD
21398a5aebSmckusick
228a89c22cSpendry int umount_fs P((char *fs_name));
umount_fs(fs_name)23398a5aebSmckusick int umount_fs(fs_name)
24398a5aebSmckusick char *fs_name;
25398a5aebSmckusick {
26398a5aebSmckusick int error;
27398a5aebSmckusick
28398a5aebSmckusick eintr:
29d4dfefc4Smckusick error = unmount(fs_name, 0);
30398a5aebSmckusick if (error < 0)
31398a5aebSmckusick error = errno;
32398a5aebSmckusick
33398a5aebSmckusick switch (error) {
34398a5aebSmckusick case EINVAL:
35398a5aebSmckusick case ENOTBLK:
368a89c22cSpendry case ENOENT:
37398a5aebSmckusick plog(XLOG_WARNING, "unmount: %s is not mounted", fs_name);
38398a5aebSmckusick error = 0; /* Not really an error */
39398a5aebSmckusick break;
40398a5aebSmckusick
41398a5aebSmckusick case EINTR:
42398a5aebSmckusick #ifdef DEBUG
43398a5aebSmckusick /* not sure why this happens, but it does. ask kirk one day... */
44398a5aebSmckusick dlog("%s: unmount: %m", fs_name);
45398a5aebSmckusick #endif /* DEBUG */
46398a5aebSmckusick goto eintr;
47398a5aebSmckusick
48398a5aebSmckusick #ifdef DEBUG
49398a5aebSmckusick default:
50398a5aebSmckusick dlog("%s: unmount: %m", fs_name);
51398a5aebSmckusick break;
52398a5aebSmckusick #endif /* DEBUG */
53398a5aebSmckusick }
54398a5aebSmckusick
55398a5aebSmckusick return error;
56398a5aebSmckusick }
57398a5aebSmckusick
58398a5aebSmckusick #endif /* NEED_UMOUNT_BSD */
59398a5aebSmckusick
60cc0207dcSpendry #ifdef NEED_UMOUNT_OSF
61cc0207dcSpendry
62cc0207dcSpendry #include <sys/mount.h> /* For MNT_NOFORCE */
63cc0207dcSpendry
umount_fs(fs_name)64cc0207dcSpendry int umount_fs(fs_name)
65cc0207dcSpendry char *fs_name;
66cc0207dcSpendry {
67cc0207dcSpendry int error;
68cc0207dcSpendry
69cc0207dcSpendry eintr:
70cc0207dcSpendry error = umount(fs_name, MNT_NOFORCE);
71cc0207dcSpendry if (error < 0)
72cc0207dcSpendry error = errno;
73cc0207dcSpendry
74cc0207dcSpendry switch (error) {
75cc0207dcSpendry case EINVAL:
76cc0207dcSpendry case ENOTBLK:
77cc0207dcSpendry plog(XLOG_WARNING, "unmount: %s is not mounted", fs_name);
78cc0207dcSpendry error = 0; /* Not really an error */
79cc0207dcSpendry break;
80cc0207dcSpendry
81cc0207dcSpendry case ENOENT:
82cc0207dcSpendry plog(XLOG_ERROR, "mount point %s: %m", fs_name);
83cc0207dcSpendry break;
84cc0207dcSpendry
85cc0207dcSpendry case EINTR:
86cc0207dcSpendry #ifdef DEBUG
87cc0207dcSpendry /* not sure why this happens, but it does. ask kirk one day... */
88cc0207dcSpendry dlog("%s: unmount: %m", fs_name);
89cc0207dcSpendry #endif /* DEBUG */
90cc0207dcSpendry goto eintr;
91cc0207dcSpendry
92cc0207dcSpendry #ifdef DEBUG
93cc0207dcSpendry default:
94cc0207dcSpendry dlog("%s: unmount: %m", fs_name);
95cc0207dcSpendry break;
96cc0207dcSpendry #endif /* DEBUG */
97cc0207dcSpendry }
98cc0207dcSpendry
99cc0207dcSpendry return error;
100cc0207dcSpendry }
101cc0207dcSpendry
102cc0207dcSpendry #endif /* NEED_UMOUNT_OSF */
103cc0207dcSpendry
104398a5aebSmckusick #ifdef NEED_UMOUNT_FS
105398a5aebSmckusick
umount_fs(fs_name)106398a5aebSmckusick int umount_fs(fs_name)
107398a5aebSmckusick char *fs_name;
108398a5aebSmckusick {
109398a5aebSmckusick mntlist *mlist, *mp, *mp_save = 0;
110398a5aebSmckusick int error = 0;
111398a5aebSmckusick
112398a5aebSmckusick mp = mlist = read_mtab(fs_name);
113398a5aebSmckusick
114398a5aebSmckusick /*
115398a5aebSmckusick * Search the mount table looking for
116398a5aebSmckusick * the correct (ie last) matching entry
117398a5aebSmckusick */
118398a5aebSmckusick while (mp) {
119398a5aebSmckusick if (strcmp(mp->mnt->mnt_fsname, fs_name) == 0 ||
120398a5aebSmckusick strcmp(mp->mnt->mnt_dir, fs_name) == 0)
121398a5aebSmckusick mp_save = mp;
122398a5aebSmckusick mp = mp->mnext;
123398a5aebSmckusick }
124398a5aebSmckusick
125398a5aebSmckusick if (mp_save) {
126398a5aebSmckusick #ifdef DEBUG
127398a5aebSmckusick dlog("Trying unmount(%s)", mp_save->mnt->mnt_dir);
128398a5aebSmckusick #endif /* DEBUG */
129cc0207dcSpendry /*
130cc0207dcSpendry * This unmount may hang leaving this
131cc0207dcSpendry * process with an exlusive lock on
132cc0207dcSpendry * /etc/mtab. Therefore it is necessary
133cc0207dcSpendry * to unlock mtab, do the unmount, then
134cc0207dcSpendry * lock mtab (again) and reread it and
135cc0207dcSpendry * finally update it.
136cc0207dcSpendry */
137cc0207dcSpendry unlock_mntlist();
138398a5aebSmckusick if (UNMOUNT_TRAP(mp_save->mnt) < 0) {
139398a5aebSmckusick switch (error = errno) {
140398a5aebSmckusick case EINVAL:
141398a5aebSmckusick case ENOTBLK:
142398a5aebSmckusick plog(XLOG_WARNING, "unmount: %s is not mounted", mp_save->mnt->mnt_dir);
143398a5aebSmckusick error = 0; /* Not really an error */
144398a5aebSmckusick break;
145398a5aebSmckusick
146398a5aebSmckusick case ENOENT:
147398a5aebSmckusick plog(XLOG_ERROR, "mount point %s: %m", mp_save->mnt->mnt_dir);
148398a5aebSmckusick break;
149398a5aebSmckusick
150398a5aebSmckusick default:
151398a5aebSmckusick #ifdef DEBUG
152398a5aebSmckusick dlog("%s: unmount: %m", mp_save->mnt->mnt_dir);
153398a5aebSmckusick #endif /* DEBUG */
154398a5aebSmckusick break;
155398a5aebSmckusick }
156398a5aebSmckusick }
157cc0207dcSpendry #ifdef DEBUG
158cc0207dcSpendry dlog("Finished unmount(%s)", mp_save->mnt->mnt_dir);
159cc0207dcSpendry #endif
160cc0207dcSpendry
161398a5aebSmckusick
162398a5aebSmckusick #ifdef UPDATE_MTAB
163398a5aebSmckusick if (!error) {
164cc0207dcSpendry free_mntlist(mlist);
165cc0207dcSpendry mp = mlist = read_mtab(fs_name);
166cc0207dcSpendry
167cc0207dcSpendry /*
168cc0207dcSpendry * Search the mount table looking for
169cc0207dcSpendry * the correct (ie last) matching entry
170cc0207dcSpendry */
171cc0207dcSpendry mp_save = 0;
172cc0207dcSpendry while (mp) {
173cc0207dcSpendry if (strcmp(mp->mnt->mnt_fsname, fs_name) == 0 ||
174cc0207dcSpendry strcmp(mp->mnt->mnt_dir, fs_name) == 0)
175cc0207dcSpendry mp_save = mp;
176cc0207dcSpendry mp = mp->mnext;
177cc0207dcSpendry }
178cc0207dcSpendry
179cc0207dcSpendry if (mp_save) {
180398a5aebSmckusick mnt_free(mp_save->mnt);
181398a5aebSmckusick mp_save->mnt = 0;
182398a5aebSmckusick rewrite_mtab(mlist);
183398a5aebSmckusick }
184cc0207dcSpendry }
185398a5aebSmckusick #endif /* UPDATE_MTAB */
186398a5aebSmckusick } else {
187398a5aebSmckusick plog(XLOG_ERROR, "Couldn't find how to unmount %s", fs_name);
188398a5aebSmckusick /*
189398a5aebSmckusick * Assume it is already unmounted
190398a5aebSmckusick */
191398a5aebSmckusick error = 0;
192398a5aebSmckusick }
193398a5aebSmckusick
194398a5aebSmckusick free_mntlist(mlist);
195398a5aebSmckusick
196398a5aebSmckusick return error;
197398a5aebSmckusick }
198398a5aebSmckusick
199398a5aebSmckusick #endif /* NEED_UMOUNT_FS */
200