From 5593372ffbb0ac9ceaed41943ff84f9c7dff9bb9 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Wed, 20 Apr 2022 07:20:33 +0200 Subject: [PATCH] Refactor, replace deprecated setfsent() & C:o with setmntent() The setfsent() family of APIs was never standardized and on Linux only GLIBC implement them. We've tried to overcome this limitation, and to support uClibc/uClibc-ng and musl libc, by providing replacements APIs in helpers.c. However, and since we want to support alternative /etc/fstab files, the setmntent() family of APIs is more widespread and supports reading from any fstab or mtab file. Signed-off-by: Joachim Wiberg --- configure.ac | 4 +-- src/finit.c | 69 ++++++++++++++++++++------------------------------- src/helpers.c | 42 ------------------------------- src/helpers.h | 19 -------------- src/mount.c | 2 ++ 5 files changed, 31 insertions(+), 105 deletions(-) diff --git a/configure.ac b/configure.ac index b5a96def..abdb1b29 100644 --- a/configure.ac +++ b/configure.ac @@ -33,8 +33,8 @@ AC_PROG_MKDIR_P # Configuration. AC_HEADER_STDC -AC_CHECK_HEADERS([fstab.h termios.h sys/ioctl.h]) -AC_CHECK_FUNCS([strstr getopt getfsenty]) +AC_CHECK_HEADERS([termios.h sys/ioctl.h mntent.h]) +AC_CHECK_FUNCS([strstr getopt getmntent]) # Check for uint[8,16,32]_t AC_TYPE_UINT8_T diff --git a/src/finit.c b/src/finit.c index 766d700d..c36cd860 100644 --- a/src/finit.c +++ b/src/finit.c @@ -26,11 +26,10 @@ #include #include -#ifdef HAVE_FSTAB_H -#include -#endif #include +#ifdef HAVE_MNTENT_H #include +#endif #include /* tzet() */ #include #include @@ -111,41 +110,43 @@ static void banner(void) */ static int fsck(int pass) { - struct fstab *fs; + struct mntent *mnt; int rc = 0; + FILE *fp; - if (!setfsent()) { + fp = setmntent("/etc/fstab", "r"); + if (!fp) { _pe("Failed opening fstab"); return 1; } - while ((fs = getfsent())) { + while ((mnt = getmntent(fp))) { char cmd[80]; struct stat st; int fsck_rc = 0; - if (fs->fs_passno != pass) + if (mnt->mnt_passno != pass) continue; errno = 0; - if (stat(fs->fs_spec, &st) || !S_ISBLK(st.st_mode)) { - if (!string_match(fs->fs_spec, "UUID=") && !string_match(fs->fs_spec, "LABEL=")) { - _d("Cannot fsck %s, not a block device: %s", fs->fs_spec, strerror(errno)); + if (stat(mnt->mnt_fsname, &st) || !S_ISBLK(st.st_mode)) { + if (!string_match(mnt->mnt_fsname, "UUID=") && !string_match(mnt->mnt_fsname, "LABEL=")) { + _d("Cannot fsck %s, not a block device: %s", mnt->mnt_fsname, strerror(errno)); continue; } } - if (ismnt("/proc/mounts", fs->fs_file, "rw")) { - _d("Skipping fsck of %s, already mounted rw on %s.", fs->fs_spec, fs->fs_file); + if (ismnt("/proc/mounts", mnt->mnt_dir, "rw")) { + _d("Skipping fsck of %s, already mounted rw on %s.", mnt->mnt_fsname, mnt->mnt_dir); continue; } #ifdef FSCK_FIX - snprintf(cmd, sizeof(cmd), "fsck -yf %s", fs->fs_spec); + snprintf(cmd, sizeof(cmd), "fsck -yf %s", mnt->mnt_fsname); #else - snprintf(cmd, sizeof(cmd), "fsck -a %s", fs->fs_spec); + snprintf(cmd, sizeof(cmd), "fsck -a %s", mnt->mnt_fsname); #endif - fsck_rc = run_interactive(cmd, "Checking filesystem %.13s", fs->fs_spec); + fsck_rc = run_interactive(cmd, "Checking filesystem %.13s", mnt->mnt_fsname); /* * "failure" is defined as exiting with a return code of * 2 or larger. A return code of 1 indicates that filesystem @@ -169,7 +170,7 @@ static int fsck(int pass) rc += fsck_rc; } - endfsent(); + endmntent(fp); return rc; } @@ -202,38 +203,22 @@ static void fs_mount(const char *src, const char *tgt, const char *fstype, } #ifndef SYSROOT -/* If / is not listed in fstab, or listed as 'ro', leave it alone */ -static int fs_readonly_root(struct fstab *fs) -{ - char *tok, *str; - - if (!fs) - return 1; - - str = fs->fs_mntops; - while ((tok = strtok(str, ","))) { - if (!strcmp(tok, "ro")) - return 1; - - str = NULL; - } - - return 0; -} - static void fs_remount_root(int fsckerr) { - struct fstab *fs; + struct mntent *mnt; + FILE *fp; - if (!setfsent()) + fp = setmntent("/etc/fstab", "r"); + if (!fp) return; - while ((fs = getfsent())) { - if (!strcmp(fs->fs_file, "/")) - break; + while ((mnt = getmntent(fp))) { + if (strcmp(mnt->mnt_dir, "/")) + continue; } - if (fs_readonly_root(fs)) + /* If / is not listed in fstab, or listed as 'ro', leave it alone */ + if (!mnt || hasmntopt(mnt, "ro")) goto out; if (fsckerr) @@ -243,7 +228,7 @@ static void fs_remount_root(int fsckerr) "Remounting / as read-write"); out: - endfsent(); + endmntent(fp); } #else static void fs_remount_root(int fsckerr) diff --git a/src/helpers.c b/src/helpers.c index b0a70009..71f3719b 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -587,48 +587,6 @@ int in_container(void) return 0; } -#ifndef HAVE_GETFSENT -static lfile_t *fstab = NULL; - -int setfsent(void) -{ - if (fstab) - lfclose(fstab); - - fstab = lfopen("/etc/fstab", " \t\n"); - if (!fstab) - return 0; - - return 1; -} - -struct fstab *getfsent(void) -{ - static struct fstab fs; - - fs.fs_spec = lftok(fstab); - if (fs.fs_spec == NULL) - return NULL; - - fs.fs_file = lftok(fstab); - fs.fs_vfstype = lftok(fstab); - fs.fs_mntops = lftok(fstab); - fs.fs_type = "rw"; - fs.fs_freq = atoi(lftok(fstab) ?: "0"); - fs.fs_passno = atoi(lftok(fstab) ?: "0"); - - return &fs; -} - -void endfsent(void) -{ - if (fstab) - lfclose(fstab); - - fstab = NULL; -} -#endif /* HAVE_GETFSENT */ - /** * Local Variables: * indent-tabs-mode: t diff --git a/src/helpers.h b/src/helpers.h index a23d5c27..b87d981b 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -27,9 +27,6 @@ #include "config.h" -#ifdef HAVE_FSTAB_H -#include -#endif #include #include /* sched_yield() */ #include @@ -52,22 +49,6 @@ typedef enum { PROGRESS_MODERN, } pstyle_t; -#ifndef HAVE_FSTAB_H -struct fstab { - char *fs_spec; /* block device name */ - char *fs_file; /* mount point */ - char *fs_vfstype; /* file-system type */ - char *fs_mntops; /* mount options */ - const char *fs_type; /* rw/rq/ro/sw/xx option */ - int fs_freq; /* dump frequency, in days */ - int fs_passno; /* pass number on parallel dump */ -}; - -int setfsent (void); -void endfsent (void); -struct fstab *getfsent (void); -#endif /* HAVE_FSTAB_H */ - char *console (void); void console_init (void); ssize_t cprintf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); diff --git a/src/mount.c b/src/mount.c index 42703dd3..24a48f75 100644 --- a/src/mount.c +++ b/src/mount.c @@ -23,7 +23,9 @@ #include #include +#ifdef HAVE_MNTENT_H #include +#endif #include #include "helpers.h"