From 704c787b8c852acea33842744897fea41ca2fb32 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 12 Nov 2017 21:33:45 +0000 Subject: [PATCH] remount, umount: updates for mtab Fix parsing in remount Add umount -a support to the umount tool --- Applications/util/remount.c | 4 ++ Applications/util/umount.c | 116 +++++++++++++++++++++++++++--------- 2 files changed, 92 insertions(+), 28 deletions(-) diff --git a/Applications/util/remount.c b/Applications/util/remount.c index 9a9ad3c9..0b846a91 100644 --- a/Applications/util/remount.c +++ b/Applications/util/remount.c @@ -17,7 +17,11 @@ char *getdev(char *arg) if (f) { while (fgets(tmp, sizeof(tmp), f)) { dev = strtok(tmp, " \t"); + if (*tmp == '#' || dev == NULL) + continue; mntpt = strtok(NULL, " \t"); + if (mntpt == NULL) + continue; if ((strcmp(dev, arg) == 0) || (strcmp(mntpt, arg) == 0)) { fclose(f); return strdup(dev); diff --git a/Applications/util/umount.c b/Applications/util/umount.c index 273d881b..77ac925e 100644 --- a/Applications/util/umount.c +++ b/Applications/util/umount.c @@ -5,19 +5,35 @@ /* Assumed length of a line in /etc/mtab */ #define MTAB_LINE 160 +#define MAXFS 16 + +static char *devlist[MAXFS]; +static char **devp = &devlist[0]; + +static char tmp[MTAB_LINE]; + +const char *readmtab(FILE *fp) +{ + char *dev; + while (fgets(tmp, sizeof(tmp), fp) != NULL) { + dev = strtok(tmp, " \t"); + if (dev == NULL || *tmp == '#') + continue; + return dev; + } + return NULL; +} char *getdev(char *arg) { FILE *f; - char tmp[MTAB_LINE]; - char* dev; + const char *dev; char* mntpt; f = fopen("/etc/mtab", "r"); if (f) { - while (fgets(tmp, sizeof(tmp), f)) { - dev = strtok(tmp, " "); - mntpt = strtok(NULL, " "); + while ((dev = readmtab(f)) != NULL) { + mntpt = strtok(NULL, " \t"); if ((strcmp(dev, arg) == 0) || (strcmp(mntpt, arg) == 0)) { fclose(f); return strdup(dev); @@ -28,8 +44,28 @@ char *getdev(char *arg) return NULL; } +int deleted(const char *p) +{ + char **d = &devlist[0]; -int rm_mtab(char *devname) + while(d < devp) { + if (*d && strcmp(*d, p) == 0) + return 1; + d++; + } + return 0; +} + +static void queue_rm_mtab(const char *p) +{ + if (devp == &devlist[MAXFS]) + fputs("umount: too many file systems.\n", stderr); + else + *devp++ = strdup(p); +} + +/* FIXME: error checking, atomicity */ +int rewrite_mtab(void) { FILE *inpf, *outf; char *tmp_fname; @@ -37,36 +73,28 @@ int rm_mtab(char *devname) static char tmp2[MTAB_LINE]; char* dev; - if ((tmp_fname = tmpnam(NULL)) == NULL) { - perror("Error getting temporary file name"); - exit(1); - } inpf = fopen("/etc/mtab", "r"); if (!inpf) { perror("Can't open /etc/mtab"); exit(1); } - outf = fopen(tmp_fname, "w"); + outf = fopen("/etc/mtab.new", "w"); if (!outf) { perror("Can't create temporary file"); exit(1); } while (fgets(tmp, sizeof(tmp), inpf)) { strncpy( tmp2, tmp, MTAB_LINE ); - dev = strtok(tmp, " "); - if (strcmp(dev, devname) == 0) { + dev = strtok(tmp, " \t"); + if (dev && deleted(dev)) { continue; } else { - fprintf(outf, "%s", tmp2); + fputs(tmp2, outf); } } fclose(inpf); fclose(outf); - if (unlink("/etc/mtab") < 0) { - perror("Can't delete old /etc/mtab file"); - exit(1); - } - if (rename(tmp_fname, "/etc/mtab") < 0) { + if (rename("/etc/mtab.new", "/etc/mtab") < 0) { perror("Error installing /etc/mtab"); exit(1); } @@ -75,21 +103,53 @@ int rm_mtab(char *devname) int main(int argc, char *argv[]) { - char *dev; + const char *dev; + char **dp; + FILE *f; + int err = 0; + + umask(022); if (argc != 2) { fprintf(stderr, "%s: umount device\n", argv[0]); return 1; } - - dev = getdev(argv[1]); - if (!dev) dev = argv[1]; - - if (umount(dev) == 0) { - rm_mtab(dev); + if (strcmp(argv[1], "-a") == 0) { + /* We need to umount things in reverse order if we have + mounts on mounts */ + f = fopen("/etc/mtab", "r"); + if (f == NULL) { + perror("mtab"); + exit(1); + } + while((dev = readmtab(f)) != NULL) { + char *mntpt = strtok(NULL, " \t"); + /* We can't unmount / */ + if (strcmp(mntpt, "/")) + queue_rm_mtab(dev); + } + fclose(f); + dp = devp; + /* Unmount in reverse order of mounting */ + while(--dp >= devlist) { + if (umount(*dp) == -1) { + perror(*dp); + *dp = NULL; + err |= 1; + } + } + rewrite_mtab(); } else { - perror("umount"); + dev = getdev(argv[1]); + if (!dev) + dev = argv[1]; + + if (umount(dev) == 0) { + queue_rm_mtab(dev); + rewrite_mtab(); + } else + perror("umount"); return 1; } - return 0; + return err; } -- 2.34.1