Revamp the initrd scripts to use a new helper program,

e2initrd_helper, which obviates the need for using /bin/awk
and mounting/unmounting the root filesystem during the initrd
process.  (Addresses Debian Bug #247775)
bitmap-optimize
Theodore Ts'o 2004-09-18 14:53:14 -04:00
parent 414846b126
commit 5d40773ba8
11 changed files with 736 additions and 256 deletions

View File

@ -1,3 +1,9 @@
2004-09-18 Theodore Ts'o <tytso@mit.edu>
* configure.in: Add --disable-e2initrd-helper flag to control
whether or not e2initrd_helper program should be
built/installed.
2004-09-17 Theodore Ts'o <tytso@mit.edu>
* Makefile.in: Remove XSI:isms for greater portability.

462
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -531,6 +531,25 @@ esac]
AC_SUBST(FSCK_PROG)
AC_SUBST(FSCK_MAN)
dnl
dnl See whether to install the `e2initrd-helper' program
dnl
AC_ARG_ENABLE([e2initrd-helper],
[ --enable-e2initrd-helper build e2initrd-helper program],
[if test "$enableval" = "no"
then
E2INITRD_PROG='' E2INITRD_MAN=''
echo "Not building e2initrd helper"
else
E2INITRD_PROG=e2initrd_helper E2INITRD_MAN=e2initrd_helper.8
echo "Building e2initrd helper"
fi]
,
E2INITRD_PROG=e2initrd_helper E2INITRD_MAN=e2initrd_helper.8
echo "Building e2initrd helper by default"
)
AC_SUBST(E2INITRD_PROG)
AC_SUBST(E2INITRD_MAN)
dnl
dnl
MAKEFILE_LIBRARY=$srcdir/lib/Makefile.library
AC_SUBST_FILE(MAKEFILE_LIBRARY)

24
debian/changelog vendored
View File

@ -1,3 +1,27 @@
e2fsprogs (1.35-7) unstable; urgency=low
* Change the initrd scripts to be use a helper program which avoids
needing to mount the root filesystem and use awk to query the
/etc/fstab file. (Closes: #247775)
* Add support for the ocfs2 filesystem to the blkid library.
* Various portability fixes for Hurd and FreeBsd, as well as
removing XSI:isms. (Closes: #256669, #264630, #269044, #255589)
* Update config.guess and config.sub from the FSF.
* Minor manual page clarifications (Closes: #268148)
* Fix write ordering problems to make e2fsck more robust in the face
of system crashes while replaying the journal, etc.
* Fix debugging printf in resize2fs. (Closes: #271605)
* Add debugfs -d option to use a separate source of data blocks when
reading from an e2image file.
* Add e2image -I option which allows the e2image metadata to be
installed into a filesystem.
* Change e2fsck to accept directories greater than 32MB.
* Add test_io mechanisms to abort after reading or writing to a
particular block.
* Fix blkid file descriptor and memory leak.
-- Theodore Y. Ts'o <tytso@mit.edu> Sat, 18 Sep 2004 09:58:46 -0400
e2fsprogs (1.35-6) unstable; urgency=low
* In the mkinitrd script, make sure the directories exist before

View File

@ -1,32 +0,0 @@
#!/bin/sh
cd /
mount -nt proc proc proc
rootdev=$(cat proc/sys/kernel/real-root-dev)
cmdline=$(cat /proc/cmdline)
umount -n proc
if [ $rootdev != 256 ]; then
mount -nt tmpfs tmpfs /dev2
mount -nt proc proc /proc
mount -nt devfs devfs /devfs > /dev/null 2>&1
get_device
mount_device
if test -f /mnt/etc/fstab ; then
ext3root=`awk '!/^ *#/ { if (($2 == "/") && ($3 == "ext3")) {print $1;}}' < /mnt/etc/fstab`
ext2root=`awk '!/^ *#/ { if (($2 == "/") && ($3 == "ext2")) {print $1;}}' < /mnt/etc/fstab`
fi
umount -n /devfs > /dev/null 2>&1
umount -n /mnt > /dev/null 2>&1
if test -n "$ext3root" || test -n "$ext2root" ; then
mount -nt tmpfs tmpfs /etc
echo >> /etc/fstab
echo >> /etc/mtab
if test -n "$ext3root" ; then
/sbin/tune2fs -O has_journal /dev2/root2 > /dev/null 2>&1
else
/sbin/tune2fs -O ^has_journal /dev2/root2 > /dev/null 2>&1
fi
umount -n /etc
fi
umount -n /dev2
umount -n /proc > /dev/null 2>&1
fi

View File

@ -1,8 +1,11 @@
#!/bin/sh
#
# /usr/share/initrd-tools/scripts/e2fsprogs
#
cp /usr/share/e2fsprogs/initrd.ext3-add-journal \
$INITRDDIR/scripts/ext3-add-journal.sh
cp /sbin/tune2fs $INITRDDIR/sbin
cp /usr/bin/awk $INITRDDIR/bin/awk
cp /usr/lib/e2initrd_helper $INITRDDIR/bin/e2initrd_helper
case "$VERSION" in
2.4.*)

27
debian/initrd.ext3-add-journal vendored Normal file
View File

@ -0,0 +1,27 @@
#!/bin/sh
#
# /usr/share/e2fsprogs/initrd.ext3-add-journal
#
cd /
mount -nt proc proc proc
rootdev=$(cat proc/sys/kernel/real-root-dev)
cmdline=$(cat /proc/cmdline)
umount -n proc
if [ $rootdev != 256 ]; then
mount -nt tmpfs tmpfs /dev2
get_device
roottype=`/bin/e2initrd_helper -r /dev2/root2`
if test -n "$roottype" ; then
mount -nt tmpfs tmpfs /etc
echo >> /etc/fstab
echo >> /etc/mtab
if test "$roottype" = "ext3" ; then
/sbin/tune2fs -O has_journal /dev2/root2 > /dev/null 2>&1
else
/sbin/tune2fs -O ^has_journal /dev2/root2 > /dev/null 2>&1
fi
umount -n /etc
fi
umount -n /dev2
umount -n /proc > /dev/null 2>&1
fi

6
debian/rules vendored
View File

@ -91,7 +91,7 @@ STD_CONF_FLAGS = --with-ccopts="${CCOPTS}" --enable-compression
BF_CONF_FLAGS = --with-ccopts="${CCOPTS} ${BF_CCOPTS}" \
--disable-nls --disable-swapfs --disable-imager \
--disable-resizer --disable-debugfs
--disable-resizer --disable-debugfs --disable-e2initrd-helper
MIPS_NOPIC_CONF_FLAGS = --with-ccopts="${CCOPTS}" \
--disable-nls \
@ -263,12 +263,12 @@ binary-arch: install install-udeb
# mkinitrd script
mkdir -p debian/e2fsprogs/usr/share/initrd-tools/scripts
install -m755 debian/e2fsprogs.mkinitrd \
install -m755 debian/initrd-tools.e2fsprogs \
debian/e2fsprogs/usr/share/initrd-tools/scripts/e2fsprogs
# initrd script
mkdir -p debian/e2fsprogs/usr/share/e2fsprogs
install -m755 debian/e2fsprogs.initrd \
install -m755 debian/initrd.ext3-add-journal \
debian/e2fsprogs/usr/share/e2fsprogs/initrd.ext3-add-journal

View File

@ -1,3 +1,10 @@
2004-09-18 Theodore Ts'o <tytso@mit.edu>
* e2initrd_helper.c: New program which allows initrd scripts to
check on the contents of /etc/fstab without (a) needing to
mount the root filesystem, and (b) needing /bin/awk in the
initrd environment. (Addresses Debian Bug #247775)
2004-09-17 Theodore Ts'o <tytso@mit.edu>
* tune2fs.8.in: Mention that e2fsck -D might be useful after

View File

@ -24,6 +24,8 @@ SMANPAGES= tune2fs.8 mklost+found.8 mke2fs.8 dumpe2fs.8 badblocks.8 \
UPROGS= chattr lsattr uuidgen
UMANPAGES= chattr.1 lsattr.1 uuidgen.1
LPROGS= @E2INITRD_PROG@
TUNE2FS_OBJS= tune2fs.o util.o
MKLPF_OBJS= mklost+found.o
MKE2FS_OBJS= mke2fs.o util.o
@ -58,11 +60,15 @@ DEPLIBS_E2P= $(LIBE2P) $(LIBCOM_ERR)
.c.o:
$(CC) -c $(ALL_CFLAGS) $< -o $@
all:: $(SPROGS) $(UPROGS) $(USPROGS) $(SMANPAGES) $(UMANPAGES)
all:: $(SPROGS) $(UPROGS) $(USPROGS) $(SMANPAGES) $(UMANPAGES) $(LPROGS)
findsuper: findsuper.o
$(CC) $(ALL_LDFLAGS) -o findsuper findsuper.o
e2initrd_helper: e2initrd_helper.o $(DEPLIBS) $(DEPLIBS_E2P) $(DEPLIBS_BLKID)
$(CC) $(ALL_LDFLAGS) -o e2initrd_helper e2initrd_helper.o $(LIBS) \
$(LIBS_BLKID) $(LIBS_E2P) $(LIBINTL)
tune2fs: $(TUNE2FS_OBJS) $(DEPLIBS) $(DEPLIBS_E2P) $(DEPLIBS_BLKID)
$(CC) $(ALL_LDFLAGS) -o tune2fs $(TUNE2FS_OBJS) $(LIBS) \
$(LIBS_BLKID) $(LIBS_E2P) $(LIBINTL)
@ -195,6 +201,10 @@ install: all $(SMANPAGES) $(UMANPAGES) installdirs
$(INSTALL_PROGRAM) $$i $(DESTDIR)$(bindir)/$$i; \
$(STRIP) $(DESTDIR)$(bindir)/$$i; \
done
for i in $(LPROGS); do \
$(INSTALL_PROGRAM) $$i $(DESTDIR)$(libdir)/$$i; \
$(STRIP) $(DESTDIR)$(libdir)/$$i; \
done
for i in $(SMANPAGES); do \
for j in $(COMPRESS_EXT); do \
$(RM) -f $(DESTDIR)$(man8dir)/$$i.$$j; \

392
misc/e2initrd_helper.c Normal file
View File

@ -0,0 +1,392 @@
/*
* e2initrd_helper.c - Get the filesystem table
*
* Copyright 2004 by Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Public
* License.
* %End-Header%
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <utime.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern int optind;
extern char *optarg;
#endif
#include "ext2fs/ext2_fs.h"
#include "ext2fs/ext2fs.h"
#include "e2p/e2p.h"
#include "blkid/blkid.h"
#include "../version.h"
#include "nls-enable.h"
const char * program_name = "get_fstab";
char * device_name;
static int open_flag;
static int root_type;
static blkid_cache cache = NULL;
struct mem_file {
char *buf;
int size;
int ptr;
};
struct fs_info {
char *device;
char *mountpt;
char *type;
char *opts;
int freq;
int passno;
int flags;
struct fs_info *next;
};
static void usage(void)
{
fprintf(stderr,
_("Usage: %s -r device\n"), program_name);
exit (1);
}
errcode_t get_file(ext2_filsys fs, const char * filename,
struct mem_file *ret_file)
{
errcode_t retval;
char *buf;
ext2_file_t e2_file;
int nbytes;
unsigned int got;
struct ext2_inode inode;
ext2_ino_t ino;
ret_file->buf = 0;
ret_file->size = 0;
ret_file->ptr = 0;
retval = ext2fs_namei(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
filename, &ino);
if (retval)
return retval;
retval = ext2fs_read_inode(fs, ino, &inode);
if (retval)
return retval;
if (inode.i_size_high || (inode.i_size > 65536))
return EFBIG;
buf = malloc(inode.i_size + 1);
if (!buf)
return ENOMEM;
memset(buf, 0, inode.i_size+1);
retval = ext2fs_file_open(fs, ino, 0, &e2_file);
if (retval)
return retval;
retval = ext2fs_file_read(e2_file, buf, inode.i_size, &got);
if (retval)
goto errout;
retval = ext2fs_file_close(e2_file);
if (retval)
return retval;
ret_file->buf = buf;
ret_file->size = (int) got;
errout:
ext2fs_file_close(e2_file);
return retval;
}
char *get_line(struct mem_file *file)
{
char *cp, *ret;
int s = 0;
cp = file->buf + file->ptr;
while (*cp && *cp != '\n') {
cp++;
s++;
}
ret = malloc(s+1);
if (!ret)
return 0;
ret[s]=0;
memcpy(ret, file->buf + file->ptr, s);
while (*cp && (*cp == '\n' || *cp == '\r')) {
cp++;
s++;
}
file->ptr += s;
return ret;
}
int mem_file_eof(struct mem_file *file)
{
return (file->ptr >= file->size);
}
/*
* fstab parsing code
*/
static char *string_copy(const char *s)
{
char *ret;
if (!s)
return 0;
ret = malloc(strlen(s)+1);
if (ret)
strcpy(ret, s);
return ret;
}
static char *skip_over_blank(char *cp)
{
while (*cp && isspace(*cp))
cp++;
return cp;
}
static char *skip_over_word(char *cp)
{
while (*cp && !isspace(*cp))
cp++;
return cp;
}
static char *parse_word(char **buf)
{
char *word, *next;
word = *buf;
if (*word == 0)
return 0;
word = skip_over_blank(word);
next = skip_over_word(word);
if (*next)
*next++ = 0;
*buf = next;
return word;
}
static void parse_escape(char *word)
{
char *p, *q;
int ac, i;
if (!word)
return;
for (p = word, q = word; *p; p++, q++) {
*q = *p;
if (*p != '\\')
continue;
if (*++p == 0)
break;
if (*p == 't') {
*q = '\t';
continue;
}
if (*p == 'n') {
*q = '\n';
continue;
}
if (!isdigit(*p)) {
*q = *p;
continue;
}
ac = 0;
for (i = 0; i < 3; i++, p++) {
if (!isdigit(*p))
break;
ac = (ac * 8) + (*p - '0');
}
*q = ac;
p--;
}
*q = 0;
}
static int parse_fstab_line(char *line, struct fs_info *fs)
{
char *dev, *device, *mntpnt, *type, *opts, *freq, *passno, *cp;
if ((cp = strchr(line, '#')))
*cp = 0; /* Ignore everything after the comment char */
cp = line;
device = parse_word(&cp);
mntpnt = parse_word(&cp);
type = parse_word(&cp);
opts = parse_word(&cp);
freq = parse_word(&cp);
passno = parse_word(&cp);
if (!device)
return -1; /* Allow blank lines */
if (!mntpnt || !type)
return -1;
parse_escape(device);
parse_escape(mntpnt);
parse_escape(type);
parse_escape(opts);
parse_escape(freq);
parse_escape(passno);
dev = blkid_get_devname(cache, device, NULL);
if (dev)
device = dev;
if (strchr(type, ','))
type = 0;
fs->device = string_copy(device);
fs->mountpt = string_copy(mntpnt);
fs->type = string_copy(type);
fs->opts = string_copy(opts ? opts : "");
fs->freq = freq ? atoi(freq) : -1;
fs->passno = passno ? atoi(passno) : -1;
fs->flags = 0;
fs->next = NULL;
if (dev)
free(dev);
return 0;
}
void free_fstab_line(struct fs_info *fs)
{
if (fs->device)
fs->device = 0;
if (fs->mountpt)
fs->mountpt = 0;
if (fs->type)
fs->type = 0;
if (fs->opts)
fs->opts = 0;
memset(fs, 0, sizeof(struct fs_info));
}
static void PRS(int argc, char **argv)
{
int c;
char * tmp;
struct group * gr;
struct passwd * pw;
#ifdef ENABLE_NLS
setlocale(LC_MESSAGES, "");
setlocale(LC_CTYPE, "");
bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
textdomain(NLS_CAT_NAME);
#endif
while ((c = getopt(argc, argv, "rv")) != EOF) {
switch (c) {
case 'r':
root_type++;
break;
case 'v':
printf("%s %s (%s)\n", program_name,
E2FSPROGS_VERSION, E2FSPROGS_DATE);
break;
default:
usage();
}
}
if (optind < argc - 1 || optind == argc)
usage();
device_name = blkid_get_devname(NULL, argv[optind], NULL);
if (!device_name) {
com_err("tune2fs", 0, _("Unable to resolve '%s'"),
argv[optind]);
exit(1);
}
}
void get_root_type(ext2_filsys fs)
{
errcode_t retval;
struct mem_file file;
char *buf;
struct fs_info fs_info;
int ret;
retval = get_file(fs, "/etc/fstab", &file);
while (!mem_file_eof(&file)) {
buf = get_line(&file);
if (!buf)
continue;
ret = parse_fstab_line(buf, &fs_info);
if (ret < 0)
goto next_line;
if (!strcmp(fs_info.mountpt, "/"))
printf("%s\n", fs_info.type);
free_fstab_line(&fs_info);
next_line:
free(buf);
}
}
int main (int argc, char ** argv)
{
errcode_t retval;
ext2_filsys fs;
struct ext2_super_block *sb;
io_manager io_ptr;
int got, ret;
initialize_ext2_error_table();
blkid_get_cache(&cache, NULL);
PRS(argc, argv);
#ifdef CONFIG_TESTIO_DEBUG
io_ptr = test_io_manager;
test_io_backing_manager = unix_io_manager;
#else
io_ptr = unix_io_manager;
#endif
retval = ext2fs_open (device_name, open_flag, 0, 0, io_ptr, &fs);
if (retval)
exit(1);
if (root_type)
get_root_type(fs);
return (ext2fs_close (fs) ? 1 : 0);
}