/* Mount and unmount helpers * * Copyright (c) 2016 Joachim Nilsson * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include #include #include /* * SysV init on Debian/Ubuntu skips these protected mount points * * It also skips anything below /proc, /sys and /run for good meausre so * we do the same here. What we want is a list of non-protected tmpfs * and regular filesystems that can be safely unmounted before we do * swapoff, and remount / as read-only, respectively. */ static int is_protected(char *dir) { size_t i; char *protected[] = { "/sys", "/proc", "/.dev", "/dev", "/dev/pts", "/dev/shm", "dev/.static/dev", "/dev/vcs", "/run", "/var/run", "/", NULL }; char *any[] = { "/proc/", "/sys/", "/run/", NULL }; for (i = 0; protected[i]; i++) { if (!strcmp(dir, protected[i])) return 1; } for (i = 0; any[i]; i++) { if (!strncmp(dir, any[i], strlen(any[i]))) return 1; } return 0; } static struct mntent *iterator(char *fstab) { static FILE *fp = NULL; static struct mntent *mnt; if (!fp && fstab) { fp = setmntent(fstab, "r"); if (!fp) return NULL; } while ((mnt = getmntent(fp))) { if (is_protected(mnt->mnt_dir)) continue; return mnt; } endmntent(fp); fp = NULL; return NULL; } void unmount_tmpfs(void) { struct mntent *mnt; while ((mnt = iterator("/proc/mounts"))) { if (!strcmp("tmpfs", mnt->mnt_fsname)) umount(mnt->mnt_dir); } } void unmount_regular(void) { struct mntent *mnt; while ((mnt = iterator("/proc/mounts"))) { umount(mnt->mnt_dir); } } /** * Local Variables: * indent-tabs-mode: t * c-file-style: "linux" * End: */