From 41c0d0cab7d24d6bf2fa1f3ada1c86da79aaa762 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 17 Jul 2010 17:57:40 +0200 Subject: [PATCH] dracut: New package. --- lfs/dracut | 83 +++++++++++++++++ make.sh | 1 + src/dracut/dracut.conf | 26 ++++++ src/dracut/switch_root.c | 188 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 298 insertions(+) create mode 100644 lfs/dracut create mode 100644 src/dracut/dracut.conf create mode 100644 src/dracut/switch_root.c diff --git a/lfs/dracut b/lfs/dracut new file mode 100644 index 0000000000..ee83ec3185 --- /dev/null +++ b/lfs/dracut @@ -0,0 +1,83 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include Config + +VER = 006 + +THISAPP = dracut-$(VER) +DL_FILE = $(THISAPP).tar.bz2 +DL_FROM = $(URL_IPFIRE) +DIR_APP = $(DIR_SRC)/$(THISAPP) +TARGET = $(DIR_INFO)/$(THISAPP) + +############################################################################### +# Top-level Rules +############################################################################### + +objects = $(DL_FILE) + +$(DL_FILE) = $(DL_FROM)/$(DL_FILE) + +$(DL_FILE)_MD5 = 016052b57001789ec2acf89d382a82f5 + +install : $(TARGET) + +check : $(patsubst %,$(DIR_CHK)/%,$(objects)) + +download :$(patsubst %,$(DIR_DL)/%,$(objects)) + +md5 : $(subst %,%_MD5,$(objects)) + +############################################################################### +# Downloading, checking, md5sum +############################################################################### + +$(patsubst %,$(DIR_CHK)/%,$(objects)) : + @$(CHECK) + +$(patsubst %,$(DIR_DL)/%,$(objects)) : + @$(LOAD) + +$(subst %,%_MD5,$(objects)) : + @$(MD5) + +############################################################################### +# Installation Details +############################################################################### + +$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) + @$(PREBUILD) + @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar jxf $(DIR_DL)/$(DL_FILE) + + cd $(DIR_APP) && cp -vf $(DIR_SRC)/src/dracut/switch_root.c . + + cd $(DIR_APP) && make $(MAKETUNING) WITH_SWITCH_ROOT=1 + cd $(DIR_APP) && make install WITH_SWITCH_ROOT=1 \ + sysconfdir=/etc + + rm -rf /usr/share/dracut/modules.d/*{dash,fips,redhat-i18n,rpmversion,network,ifcfg,plymouth,btrfs,crypt,dm,dmraid,dmsquash-live,lvm,mdraid,multipath,dasd,fcoe,iscsi,nbd,nfs,resume,uswsusp,zfcp,znet,selinux} + + @rm -rf $(DIR_APP) + @$(POSTBUILD) diff --git a/make.sh b/make.sh index 7834e5a7d9..4566d6ef7d 100755 --- a/make.sh +++ b/make.sh @@ -376,6 +376,7 @@ buildipfire() { ipfiremake klibc ipfiremake mkinitcpio ipfiremake udev KLIBC=1 + ipfiremake dracut ipfiremake expat ipfiremake gdbm ipfiremake gmp diff --git a/src/dracut/dracut.conf b/src/dracut/dracut.conf new file mode 100644 index 0000000000..a6c3cb018a --- /dev/null +++ b/src/dracut/dracut.conf @@ -0,0 +1,26 @@ +# dracut config file + +# Specific list of dracut modules to use +#dracutmodules+="" + +# Dracut modules to omit +#omit_dracutmodules+="" + +# Dracut modules to add to the default +#add_dracutmodules+="" + +# additional kernel modules to the default +#add_drivers+="" + +# list of kernel filesystem modules to be included in the generic initramfs +filesystems+="reiser4" + +# build initrd only to boot current hardware +#hostonly="yes" +# + +# install local /etc/mdadm.conf +mdadmconf="no" + +# install local /etc/lvm/lvm.conf +lvmconf="no" diff --git a/src/dracut/switch_root.c b/src/dracut/switch_root.c new file mode 100644 index 0000000000..1520387239 --- /dev/null +++ b/src/dracut/switch_root.c @@ -0,0 +1,188 @@ +/* + * switchroot.c - switch to new root directory and start init. + * + * Copyright 2002-2008 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authors: + * Peter Jones + * Jeremy Katz + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef MS_MOVE +#define MS_MOVE 8192 +#endif + +enum { + ok, + err_no_directory, + err_usage, +}; + +/* remove all files/directories below dirName -- don't cross mountpoints */ +static int +recursiveRemove(char * dirName) +{ + struct stat sb,rb; + DIR * dir; + struct dirent * d; + char * strBuf = alloca(strlen(dirName) + 1024); + + if (!(dir = opendir(dirName))) { + printf("error opening %s: %m\n", dirName); + return 0; + } + + if (fstat(dirfd(dir),&rb)) { + printf("unable to stat %s: %m\n", dirName); + closedir(dir); + return 0; + } + + errno = 0; + + while ((d = readdir(dir))) { + errno = 0; + + if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) { + errno = 0; + continue; + } + + strcpy(strBuf, dirName); + strcat(strBuf, "/"); + strcat(strBuf, d->d_name); + + if (lstat(strBuf, &sb)) { + printf("failed to stat %s: %m\n", strBuf); + errno = 0; + continue; + } + + /* only descend into subdirectories if device is same as dir */ + if (S_ISDIR(sb.st_mode)) { + if (sb.st_dev == rb.st_dev) { + recursiveRemove(strBuf); + if (rmdir(strBuf)) + printf("failed to rmdir %s: %m\n", strBuf); + } + errno = 0; + continue; + } + if (unlink(strBuf)) { + printf("failed to remove %s: %m\n", strBuf); + errno = 0; + continue; + } + } + + if (errno) { + closedir(dir); + printf("error reading from %s: %m\n", dirName); + return 1; + } + + closedir(dir); + return 0; +} + +static int switchroot(const char *newroot) +{ + /* Don't try to unmount the old "/", there's no way to do it. */ + const char *umounts[] = { "/dev", "/proc", "/sys", NULL }; + int errnum; + int i; + + for (i = 0; umounts[i] != NULL; i++) { + char newmount[PATH_MAX]; + strcpy(newmount, newroot); + strcat(newmount, umounts[i]); + if (mount(umounts[i], newmount, NULL, MS_MOVE, NULL) < 0) { + fprintf(stderr, "Error mount moving old %s %s %m\n", + umounts[i], newmount); + fprintf(stderr, "Forcing unmount of %s\n", umounts[i]); + umount2(umounts[i], MNT_FORCE); + } + } + + if (chdir(newroot) < 0) { + errnum=errno; + fprintf(stderr, "switchroot: chdir failed: %m\n"); + errno=errnum; + return -1; + } + recursiveRemove("/"); + if (mount(newroot, "/", NULL, MS_MOVE, NULL) < 0) { + errnum = errno; + fprintf(stderr, "switchroot: mount failed: %m\n"); + errno = errnum; + return -1; + } + + if (chroot(".")) { + errnum = errno; + fprintf(stderr, "switchroot: chroot failed: %m\n"); + errno = errnum; + return -2; + } + return 1; +} + +static void usage(FILE *output) +{ + fprintf(output, "usage: switchroot \n"); + if (output == stderr) + exit(err_usage); + exit(ok); +} + +int main(int argc, char *argv[]) +{ + char *newroot = argv[1]; + char *init = argv[2]; + char **initargs = &argv[2]; + + if (newroot == NULL || newroot[0] == '\0' || + init == NULL || init[0] == '\0' ) { + usage(stderr); + } + + if (switchroot(newroot) < 0) { + fprintf(stderr, "switchroot has failed. Sorry.\n"); + return 1; + } + if (access(initargs[0], X_OK)) + fprintf(stderr, "WARNING: can't access %s\n", initargs[0]); + + /* get session leader */ + setsid(); + /* set controlling terminal */ + ioctl (0, TIOCSCTTY, 1); + + execv(initargs[0], initargs); +} + -- 2.39.2