Ensure all filesystems listed in /proc/mounts are unmounted

The iterator function getmntent() is not stable. It may skip
entries if the contents of the iterated file changes, which
is the case with /proc/mounts when filesystems are unmounted.
As a result, some filesystems were never unmounted.

To fix this, iteratation is now restarted after every
sucessful unmount.

Signed-off-by: Robert Andersson <robert.m.andersson@atlascopco.com>
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
This commit is contained in:
Robert Andersson authored and Ming Liu committed 2021-08-30 10:16:00 +02:00
1 parent 522a06f864
commit 595e2b4e81
1 file changed
+22 -14
+22 -14
View File
@@ -59,46 +59,54 @@ static int is_protected(char *dir)
return 0; return 0;
} }
static struct mntent *iterator(char *fstab) static void iterator_end(FILE **fp)
{
endmntent(*fp);
*fp = NULL;
}
static struct mntent *iterator(char *fstab, FILE **fp)
{ {
static FILE *fp = NULL;
static struct mntent *mnt; static struct mntent *mnt;
if (!fp && fstab) { if (!*fp && fstab) {
fp = setmntent(fstab, "r"); *fp = setmntent(fstab, "r");
if (!fp) if (!*fp)
return NULL; return NULL;
} }
while ((mnt = getmntent(fp))) { while ((mnt = getmntent(*fp))) {
if (is_protected(mnt->mnt_dir)) if (is_protected(mnt->mnt_dir))
continue; continue;
return mnt; return mnt;
} }
endmntent(fp); iterator_end(fp);
fp = NULL;
return NULL; return NULL;
} }
void unmount_tmpfs(void) void unmount_tmpfs(void)
{ {
struct mntent *mnt; struct mntent *mnt;
FILE *fp = NULL;
while ((mnt = iterator("/proc/mounts"))) { while ((mnt = iterator("/proc/mounts", &fp))) {
if (!strcmp("tmpfs", mnt->mnt_fsname)) if (!strcmp("tmpfs", mnt->mnt_fsname) && !umount(mnt->mnt_dir))
umount(mnt->mnt_dir); iterator_end(&fp); // Restart iteration
} }
} }
void unmount_regular(void) void unmount_regular(void)
{ {
struct mntent *mnt; struct mntent *mnt;
FILE *fp = NULL;
while ((mnt = iterator("/proc/mounts"))) { while ((mnt = iterator("/proc/mounts", &fp))) {
umount(mnt->mnt_dir); if (!umount(mnt->mnt_dir)) {
print(0, "Unmounted %s", mnt->mnt_dir);
iterator_end(&fp); // Restart iteration
}
} }
} }