From 54755eba5f04aa18b4c3dd6facb62aed74ff35dd Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 31 Dec 2017 23:01:28 +0000 Subject: [PATCH] utils: update remount to handle mtab etc Add a -n option for boot time --- Applications/util/remount.c | 92 +++++++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/Applications/util/remount.c b/Applications/util/remount.c index bfaf4f88..eba55e5c 100644 --- a/Applications/util/remount.c +++ b/Applications/util/remount.c @@ -4,12 +4,42 @@ #include #include -static char *getdev(char *arg) +static int quiet; + +/* Strip ro and rw from the entry and append the correct one */ +/* Will want extending when we do nosuid */ +static char *modify_opts(char *opts, int flags) +{ + static char optbuf[_MAX_MNTLEN]; + char *op = optbuf; + char *p = strtok(opts, ","); + while(p) { + if (strcmp(p, "ro") != 0 && strcmp(p, "rw") != 0) { + if (op != optbuf) + *op++ = ','; + strcpy(op, p); + op += strlen(p); + } + p = strtok(NULL,","); + } + if (flags & MS_RDONLY) { + if (op != optbuf) + *op++ = ','; + strcpy(op, "ro"); + op += 2; + } + if (op == optbuf) + return "defaults"; + *op = 0; + return optbuf; +} + +static char *getdev(char *arg, char *p) { FILE *f; struct mntent *mnt; - f = setmntent("/etc/mtab", "r"); + f = setmntent(p, "r"); if (f) { while (mnt = getmntent(f)) { if ((strcmp(mnt->mnt_fsname, arg) == 0) || (strcmp(mnt->mnt_dir, arg) == 0)) { @@ -22,21 +52,60 @@ static char *getdev(char *arg) return NULL; } -/* FIXME: needs to update mtab entry / support nosuid etc ? */ +static void rewrite_mtab(char *name, flags) +{ + FILE *inpf, *outf; + struct mntent *mnt; + + if (quiet) + return; + + inpf = setmntent("/etc/mtab", "r"); + if (!inpf) { + perror("Can't open /etc/mtab"); + exit(1); + } + outf = setmntent("/etc/mtab.new", "w"); + if (!outf) { + perror("Can't create temporary file"); + exit(1); + } + /* Correct the options for the remounted entry */ + while (mnt = getmntent(inpf)) { + if (strcmp(name, mnt->mnt_fsname) == 0) + mnt->mnt_opts = modify_opts(mnt->mnt_opts, flags); + addmntent(outf, mnt); + } + endmntent(inpf); + endmntent(outf); + if (rename("/etc/mtab.new", "/etc/mtab") < 0) { + perror("Error installing /etc/mtab"); + exit(1); + } +} int main(int argc, char *argv[]) { char *dev; unsigned int flags; - + + if (argc == 4 && strcmp(argv[1], "-n") == 0) { + argc--; + argv++; + quiet = 1; + } if (argc != 3) { fprintf(stderr, "%s: remount device [ro][rw]\n", argv[0]); return 1; } - dev = getdev(argv[1]); - if (!dev) dev = argv[1]; - + dev = getdev(argv[1], "/etc/fstab"); + if (!dev) + dev = getdev(argv[1], "/etc/mtab"); + if (!dev) + dev = argv[1]; + + /* TODO - nosuid once supported */ if (strcmp(argv[2], "ro") == 0) flags = MS_RDONLY|MS_REMOUNT; else if (strcmp(argv[2], "rw") == 0) @@ -45,10 +114,17 @@ int main(int argc, char *argv[]) fprintf(stderr, "%s: ro or rw required.\n", argv[0]); return 1; } + + /* Rewrite first in case we are updating /etc to ro */ + if (flags & MS_RDONLY) + rewrite_mtab(dev, flags); if (remount(dev, flags)) { - perror("umount"); + perror("remount"); return 1; } + /* Otherwise rewrite after in case /etc was ro */ + if (!(flags & MS_RDONLY)) + rewrite_mtab(dev, flags); return 0; } -- 2.34.1