gnomeos: Mounts work, far fewer boot errors

This commit is contained in:
Colin Walters 2011-11-16 12:51:24 -05:00
parent f51e4ee772
commit 073aa5973c
11 changed files with 265 additions and 577 deletions

View File

@ -0,0 +1,48 @@
DISTRO = "gnomeosdistro"
DISTRO_NAME = "GNOME OS (Built by Poky 6.0)"
DISTRO_VERSION = "0+snapshot-${DATE}"
SDK_VENDOR = "-gnomesdk"
SDK_VERSION := "${@'${DISTRO_VERSION}'.replace('snapshot-${DATE}','snapshot')}"
MAINTAINER = "Colin Walters <walters@verbum.org>"
TARGET_VENDOR = "-gnomeos"
LOCALCONF_VERSION = "1"
DISTRO_FEATURES_append = " largefile opengl"
PREFERRED_VERSION_linux-yocto ?= "3.0.%"
PREFERRED_VERSION_linux-yocto_qemux86 ?= "3.0%"
PREFERRED_VERSION_linux-yocto_qemux86-64 ?= "3.0%"
SDK_NAME = "${DISTRO}-${TCLIBC}-${SDK_ARCH}-${TARGET_ARCH}"
SDKPATH = "/opt/${DISTRO}/${SDK_VERSION}"
DISTRO_EXTRA_RDEPENDS += "task-core-boot"
DISTRO_EXTRA_RRECOMMENDS += "kernel-module-af-packet"
QEMU_TARGETS ?= "i386 x86_64"
PREMIRRORS ?= "\
bzr://.*/.* http://autobuilder.yoctoproject.org/sources/ \n \
cvs://.*/.* http://autobuilder.yoctoproject.org/sources/ \n \
git://.*/.* http://autobuilder.yoctoproject.org/sources/ \n \
hg://.*/.* http://autobuilder.yoctoproject.org/sources/ \n \
osc://.*/.* http://autobuilder.yoctoproject.org/sources/ \n \
p4://.*/.* http://autobuilder.yoctoproject.org/sources/ \n \
svk://.*/.* http://autobuilder.yoctoproject.org/sources/ \n \
svn://.*/.* http://autobuilder.yoctoproject.org/sources/ \n"
MIRRORS =+ "\
ftp://.*/.* http://autobuilder.yoctoproject.org/sources/ \n \
http://.*/.* http://autobuilder.yoctoproject.org/sources/ \n \
https://.*/.* http://autobuilder.yoctoproject.org/sources/ \n"
# The CONNECTIVITY_CHECK_URI's are used to test whether we can succesfully
# fetch from the network (and warn you if not). To disable the test set
# the variable to be empty.
CONNECTIVITY_CHECK_URIS ?= "git://git.yoctoproject.org/yocto-firewall-test;protocol=git;rev=HEAD \
https://eula-downloads.yoctoproject.org/index.php \
http://bugzilla.yoctoproject.org/report.cgi"

View File

@ -8,7 +8,7 @@ LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=3f40d7994397109285ec7b81fdeb3
inherit rootfs_${IMAGE_PKGTYPE}
PACKAGE_INSTALL = "task-core-boot task-base-extended \
ostree ostree-init"
ostree ostree-init strace"
RDEPENDS += "${PACKAGE_INSTALL}"
DEPENDS += "makedevs-native virtual/fakeroot-native"
@ -35,9 +35,24 @@ fakeroot do_rootfs () {
rootfs_${IMAGE_PKGTYPE}_do_rootfs
makedevs -r ${IMAGE_ROOTFS} -D ${@gnomeos_get_devtable_list(d)}
mkdir ${IMAGE_ROOTFS}/dev/pts
# We use devtmpfs
rm -f ${IMAGE_ROOTFS}/etc/init.d/udev-cache
rm -f ${IMAGE_ROOTFS}/etc/rc*.d/*udev-cache*
# The default fstab has /, which we don't want, and we do want /sys and /dev/shm
cat > ${IMAGE_ROOTFS}/etc/fstab << EOF
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
EOF
echo "GNOME OS Unix login" > ${IMAGE_ROOTFS}/etc/issue
ln -sf /var/run/resolv.conf ${IMAGE_ROOTFS}/etc/resolv.conf
TOPROOT_BIND_MOUNTS="home root tmp"
OSTREE_BIND_MOUNTS="var"
OSDIRS="dev proc mnt media sys sysroot"

View File

@ -1,49 +0,0 @@
### BEGIN INIT INFO
# Provides: checkfs
# Required-Start: checkroot
# Required-Stop:
# Default-Start: S
# Default-Stop:
# Short-Description: Check all other file systems
### END INIT INFO
. /etc/default/rcS
#
# Check the rest of the filesystems.
#
if test ! -f /fastboot
then
if test -f /forcefsck
then
force="-f"
else
force=""
fi
if test "$FSCKFIX" = yes
then
fix="-y"
else
fix="-a"
fi
spinner="-C"
case "$TERM" in
dumb|network|unknown|"") spinner="" ;;
esac
test "`uname -m`" = "s390" && spinner="" # This should go away
test "$VERBOSE" != no && echo "Checking all filesystems..."
fsck $spinner -R -A $fix $force
if test "$?" -gt 1
then
echo
echo "fsck failed. Please repair manually."
echo
echo "CONTROL-D will exit from this shell and continue system startup."
echo
# Start a single user shell on the console
/sbin/sulogin $CONSOLE
fi
fi
rm -f /fastboot /forcefsck
: exit 0

View File

@ -1,137 +0,0 @@
### BEGIN INIT INFO
# Provides: checkroot
# Required-Start: udev
# Required-Stop:
# Default-Start: S
# Default-Stop:
# Short-Description: Check to root file system.
### END INIT INFO
. /etc/default/rcS
#
# Set SULOGIN in /etc/default/rcS to yes if you want a sulogin to be spawned
# from this script *before anything else* with a timeout, like SCO does.
#
test "$SULOGIN" = yes && sulogin -t 30 $CONSOLE
#
# Read /etc/fstab.
#
exec 9< /etc/fstab
rootmode=rw
rootopts=rw
rootcheck=no
swap_on_md=no
devfs=
while read fs mnt type opts dump pass junk <&9
do
case "$fs" in
""|\#*)
continue;
;;
/dev/md*)
# Swap on md device.
test "$type" = swap && swap_on_md=yes
;;
/dev/*)
;;
*)
# Might be a swapfile.
test "$type" = swap && swap_on_md=yes
;;
esac
test "$type" = devfs && devfs="$fs"
test "$mnt" != / && continue
rootopts="$opts"
test "$pass" = 0 -o "$pass" = "" && rootcheck=no
case "$opts" in
ro|ro,*|*,ro|*,ro,*)
rootmode=ro
;;
esac
done
exec 0>&9 9>&-
#
# Activate the swap device(s) in /etc/fstab. This needs to be done
# before fsck, since fsck can be quite memory-hungry.
#
test "$VERBOSE" != no && echo "Activating swap"
swapon -a 2> /dev/null
#
# Check the root filesystem.
#
if test -f /fastboot || test $rootcheck = no
then
test $rootcheck = yes && echo "Fast boot, no filesystem check"
else
#
# Ensure that root is quiescent and read-only before fsck'ing.
#
mount -n -o remount,ro /
if test $? = 0
then
if test -f /forcefsck
then
force="-f"
else
force=""
fi
if test "$FSCKFIX" = yes
then
fix="-y"
else
fix="-a"
fi
spinner="-C"
case "$TERM" in
dumb|network|unknown|"") spinner="" ;;
esac
test `uname -m` = s390 && spinner="" # This should go away
test "$VERBOSE" != no && echo "Checking root filesystem..."
fsck $spinner $force $fix /
#
# If there was a failure, drop into single-user mode.
#
# NOTE: "failure" is defined as exiting with a return code of
# 2 or larger. A return code of 1 indicates that filesystem
# errors were corrected but that the boot may proceed.
#
if test "$?" -gt 1
then
# Surprise! Re-directing from a HERE document (as in
# "cat << EOF") won't work, because the root is read-only.
echo
echo "fsck failed. Please repair manually and reboot. Please note"
echo "that the root filesystem is currently mounted read-only. To"
echo "remount it read-write:"
echo
echo " # mount -n -o remount,rw /"
echo
echo "CONTROL-D will exit from this shell and REBOOT the system."
echo
# Start a single user shell on the console
/sbin/sulogin $CONSOLE
reboot -f
fi
else
echo "*** ERROR! Cannot fsck root fs because it is not mounted read-only!"
echo
fi
fi
#
# If the root filesystem was not marked as read-only in /etc/fstab,
# remount the rootfs rw but do not try to change mtab because it
# is on a ro fs until the remount succeeded. Then clean up old mtabs
# and finally write the new mtab.
#
mount -n -o remount,$rootmode /
if test "$rootmode" = rw
then
ln -sf /proc/mounts /dev/mtab
fi
: exit 0

View File

@ -1,5 +0,0 @@
# GID of the `tty' group
TTYGRP=5
# Set to 600 to have `mesg n' be the default
TTYMODE=620

View File

@ -1,28 +0,0 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: devpts
# Required-Start: udev
# Required-Stop:
# Default-Start: S
# Default-Stop:
# Short-Description: Mount /dev/pts file systems.
### END INIT INFO
. /etc/default/devpts
if grep -q devpts /proc/filesystems
then
#
# Create multiplexor device.
#
test -c /dev/ptmx || mknod -m 666 /dev/ptmx c 5 2
#
# Mount /dev/pts if needed.
#
if ! grep -q devpts /proc/mounts
then
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts -ogid=${TTYGRP},mode=${TTYMODE}
fi
fi

View File

@ -1,197 +0,0 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: volatile
# Required-Start: $local_fs
# Required-Stop: $local_fs
# Default-Start: S
# Default-Stop:
# Short-Description: Populate the volatile filesystem
### END INIT INFO
. /etc/default/rcS
CFGDIR="/etc/default/volatiles"
TMPROOT="/var/tmp"
COREDEF="00_core"
[ "${VERBOSE}" != "no" ] && echo "Populating volatile Filesystems."
create_file() {
EXEC="
touch \"$1\";
chown ${TUSER}.${TGROUP} $1 || echo \"Failed to set owner -${TUSER}- for -$1-.\" >/dev/tty0 2>&1;
chmod ${TMODE} $1 || echo \"Failed to set mode -${TMODE}- for -$1-.\" >/dev/tty0 2>&1 "
test "$VOLATILE_ENABLE_CACHE" = yes && echo "$EXEC" >> /etc/volatile.cache
[ -e "$1" ] && {
[ "${VERBOSE}" != "no" ] && echo "Target already exists. Skipping."
} || {
eval $EXEC &
}
}
mk_dir() {
EXEC="
mkdir -p \"$1\";
chown ${TUSER}.${TGROUP} $1 || echo \"Failed to set owner -${TUSER}- for -$1-.\" >/dev/tty0 2>&1;
chmod ${TMODE} $1 || echo \"Failed to set mode -${TMODE}- for -$1-.\" >/dev/tty0 2>&1 "
test "$VOLATILE_ENABLE_CACHE" = yes && echo "$EXEC" >> /etc/volatile.cache
[ -e "$1" ] && {
[ "${VERBOSE}" != "no" ] && echo "Target already exists. Skipping."
} || {
eval $EXEC &
}
}
link_file() {
EXEC="test -e \"$2\" -o -L $2 || ln -s \"$1\" \"$2\" >/dev/tty0 2>&1"
test "$VOLATILE_ENABLE_CACHE" = yes && echo " $EXEC" >> /etc/volatile.cache
[ -e "$2" ] && {
echo "Cannot create link over existing -${TNAME}-." >&2
} || {
eval $EXEC &
}
}
check_requirements() {
cleanup() {
rm "${TMP_INTERMED}"
rm "${TMP_DEFINED}"
rm "${TMP_COMBINED}"
}
CFGFILE="$1"
[ `basename "${CFGFILE}"` = "${COREDEF}" ] && return 0
TMP_INTERMED="${TMPROOT}/tmp.$$"
TMP_DEFINED="${TMPROOT}/tmpdefined.$$"
TMP_COMBINED="${TMPROOT}/tmpcombined.$$"
cat /etc/passwd | sed 's@\(^:\)*:.*@\1@' | sort | uniq > "${TMP_DEFINED}"
cat ${CFGFILE} | grep -v "^#" | cut -d " " -f 2 > "${TMP_INTERMED}"
cat "${TMP_DEFINED}" "${TMP_INTERMED}" | sort | uniq > "${TMP_COMBINED}"
NR_DEFINED_USERS="`cat "${TMP_DEFINED}" | wc -l`"
NR_COMBINED_USERS="`cat "${TMP_COMBINED}" | wc -l`"
[ "${NR_DEFINED_USERS}" -ne "${NR_COMBINED_USERS}" ] && {
echo "Undefined users:"
diff "${TMP_DEFINED}" "${TMP_COMBINED}" | grep "^>"
cleanup
return 1
}
cat /etc/group | sed 's@\(^:\)*:.*@\1@' | sort | uniq > "${TMP_DEFINED}"
cat ${CFGFILE} | grep -v "^#" | cut -d " " -f 3 > "${TMP_INTERMED}"
cat "${TMP_DEFINED}" "${TMP_INTERMED}" | sort | uniq > "${TMP_COMBINED}"
NR_DEFINED_GROUPS="`cat "${TMP_DEFINED}" | wc -l`"
NR_COMBINED_GROUPS="`cat "${TMP_COMBINED}" | wc -l`"
[ "${NR_DEFINED_GROUPS}" -ne "${NR_COMBINED_GROUPS}" ] && {
echo "Undefined groups:"
diff "${TMP_DEFINED}" "${TMP_COMBINED}" | grep "^>"
cleanup
return 1
}
# Add checks for required directories here
cleanup
return 0
}
apply_cfgfile() {
CFGFILE="$1"
check_requirements "${CFGFILE}" || {
echo "Skipping ${CFGFILE}"
return 1
}
cat ${CFGFILE} | grep -v "^#" | \
while read LINE; do
eval `echo "$LINE" | sed -n "s/\(.*\)\ \(.*\) \(.*\)\ \(.*\)\ \(.*\)\ \(.*\)/TTYPE=\1 ; TUSER=\2; TGROUP=\3; TMODE=\4; TNAME=\5 TLTARGET=\6/p"`
[ "${VERBOSE}" != "no" ] && echo "Checking for -${TNAME}-."
[ "${TTYPE}" = "l" ] && {
TSOURCE="$TLTARGET"
[ -L "${TNAME}" ] || {
[ "${VERBOSE}" != "no" ] && echo "Creating link -${TNAME}- pointing to -${TSOURCE}-."
link_file "${TSOURCE}" "${TNAME}" &
}
continue
}
[ -L "${TNAME}" ] && {
[ "${VERBOSE}" != "no" ] && echo "Found link."
NEWNAME=`ls -l "${TNAME}" | sed -e 's/^.*-> \(.*\)$/\1/'`
echo ${NEWNAME} | grep -v "^/" >/dev/null && {
TNAME="`echo ${TNAME} | sed -e 's@\(.*\)/.*@\1@'`/${NEWNAME}"
[ "${VERBOSE}" != "no" ] && echo "Converted relative linktarget to absolute path -${TNAME}-."
} || {
TNAME="${NEWNAME}"
[ "${VERBOSE}" != "no" ] && echo "Using absolute link target -${TNAME}-."
}
}
case "${TTYPE}" in
"f") [ "${VERBOSE}" != "no" ] && echo "Creating file -${TNAME}-."
create_file "${TNAME}" &
;;
"d") [ "${VERBOSE}" != "no" ] && echo "Creating directory -${TNAME}-."
mk_dir "${TNAME}" &
# Add check to see if there's an entry in fstab to mount.
;;
*) [ "${VERBOSE}" != "no" ] && echo "Invalid type -${TTYPE}-."
continue
;;
esac
done
return 0
}
clearcache=0
exec 9</proc/cmdline
while read line <&9
do
case "$line" in
*clearcache*) clearcache=1
;;
*) continue
;;
esac
done
exec 9>&-
if test -e /etc/volatile.cache -a "$VOLATILE_ENABLE_CACHE" = "yes" -a "x$1" != "xupdate" -a "x$clearcache" = "x0"
then
sh /etc/volatile.cache
else
rm -f /etc/volatile.cache
for file in `ls -1 "${CFGDIR}" | sort`; do
apply_cfgfile "${CFGDIR}/${file}"
done
fi
if test -f /etc/ld.so.cache -a ! -f /var/run/ld.so.cache
then
ln -s /etc/ld.so.cache /var/run/ld.so.cache
fi

View File

@ -1,19 +0,0 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: mountvirtfs
# Required-Start:
# Required-Stop:
# Default-Start: S
# Default-Stop:
# Short-Description: Mount kernel virtual file systems.
# Description: Mount initial set of virtual filesystems the kernel
# provides and that are required by everything.
### END INIT INFO
if [ -e /proc ] && ! [ -e /proc/mounts ]; then
mount -t proc proc /proc
fi
if [ -e /sys ] && grep -q sysfs /proc/filesystems; then
mount sysfs /sys -t sysfs
fi

View File

@ -1,39 +0,0 @@
# This configuration file lists filesystem objects that should get verified
# during startup and be created if missing.
#
# Every line must either be a comment starting with #
# or a definition of format:
# <type> <owner> <group> <mode> <path> <linksource>
# where the items are separated by whitespace !
#
# <type> : d|f|l : (d)irectory|(f)ile|(l)ink
#
# A linking example:
# l root root 0777 /var/test /tmp/testfile
# f root root 0644 /var/test none
#
# Understanding links:
# When populate-volatile is to verify/create a directory or file, it will first
# check it's existence. If a link is found to exist in the place of the target,
# the path of the target is replaced with the target the link points to.
# Thus, if a link is in the place to be verified, the object will be created
# in the place the link points to instead.
# This explains the order of "link before object" as in the example above, where
# a link will be created at /var/test pointing to /tmp/testfile and due to this
# link the file defined as /var/test will actually be created as /tmp/testfile.
d root root 0755 /var/volatile/cache none
d root root 1777 /var/volatile/lock none
d root root 0755 /var/volatile/log none
d root root 0755 /var/volatile/run none
d root root 1777 /var/volatile/tmp none
l root root 0755 /var/cache /var/volatile/cache
l root root 1777 /var/lock /var/volatile/lock
l root root 0755 /var/log /var/volatile/log
l root root 0755 /var/run /var/volatile/run
l root root 1777 /var/tmp /var/volatile/tmp
d root root 0755 /var/lock/subsys none
f root root 0664 /var/log/wtmp none
f root root 0664 /var/run/utmp none
l root root 0644 /etc/resolv.conf /var/run/resolv.conf
f root root 0644 /var/run/resolv.conf none

View File

@ -10,8 +10,6 @@ INHIBIT_DEFAULT_DEPS = "1"
SRC_URI = "file://functions \
file://halt \
file://umountfs \
file://devpts.sh \
file://devpts \
file://hostname.sh \
file://mountall.sh \
file://banner.sh \
@ -19,17 +17,12 @@ SRC_URI = "file://functions \
file://bootmisc.sh \
file://mountnfs.sh \
file://reboot \
file://checkfs.sh \
file://single \
file://sendsigs \
file://urandom \
file://rmnologin.sh \
file://checkroot.sh \
file://umountnfs.sh \
file://sysfs.sh \
file://device_table.txt \
file://populate-volatile.sh \
file://volatiles \
file://save-rtc.sh \
file://GPLv2.patch"
@ -58,11 +51,9 @@ do_install () {
install -d ${D}${sysconfdir}/rc5.d
install -d ${D}${sysconfdir}/rc6.d
install -d ${D}${sysconfdir}/default
install -d ${D}${sysconfdir}/default/volatiles
install -m 0644 ${WORKDIR}/functions ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/bootmisc.sh ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/checkroot.sh ${D}${sysconfdir}/init.d
# install -m 0755 ${WORKDIR}/finish.sh ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/halt ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/hostname.sh ${D}${sysconfdir}/init.d
@ -74,12 +65,7 @@ do_install () {
install -m 0755 ${WORKDIR}/single ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/umountnfs.sh ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/urandom ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/devpts.sh ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/devpts ${D}${sysconfdir}/default
install -m 0755 ${WORKDIR}/sysfs.sh ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/populate-volatile.sh ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/save-rtc.sh ${D}${sysconfdir}/init.d
install -m 0644 ${WORKDIR}/volatiles ${D}${sysconfdir}/default/volatiles/00_core
if [ "${TARGET_ARCH}" = "arm" ]; then
install -m 0755 ${WORKDIR}/alignment.sh ${D}${sysconfdir}/init.d
fi
@ -110,18 +96,13 @@ do_install () {
ln -sf ../init.d/save-rtc.sh ${D}${sysconfdir}/rc0.d/S25save-rtc.sh
ln -sf ../init.d/save-rtc.sh ${D}${sysconfdir}/rc6.d/S25save-rtc.sh
ln -sf ../init.d/banner.sh ${D}${sysconfdir}/rcS.d/S02banner.sh
ln -sf ../init.d/checkroot.sh ${D}${sysconfdir}/rcS.d/S10checkroot.sh
# ln -sf ../init.d/checkfs.sh ${D}${sysconfdir}/rcS.d/S30checkfs.sh
ln -sf ../init.d/mountall.sh ${D}${sysconfdir}/rcS.d/S35mountall.sh
ln -sf ../init.d/hostname.sh ${D}${sysconfdir}/rcS.d/S39hostname.sh
ln -sf ../init.d/mountnfs.sh ${D}${sysconfdir}/rcS.d/S45mountnfs.sh
ln -sf ../init.d/bootmisc.sh ${D}${sysconfdir}/rcS.d/S55bootmisc.sh
# ln -sf ../init.d/urandom ${D}${sysconfdir}/rcS.d/S55urandom
# ln -sf ../init.d/finish.sh ${D}${sysconfdir}/rcS.d/S99finish.sh
ln -sf ../init.d/sysfs.sh ${D}${sysconfdir}/rcS.d/S02sysfs.sh
# udev will run at S03 if installed
ln -sf ../init.d/populate-volatile.sh ${D}${sysconfdir}/rcS.d/S37populate-volatile.sh
ln -sf ../init.d/devpts.sh ${D}${sysconfdir}/rcS.d/S38devpts.sh
if [ "${TARGET_ARCH}" = "arm" ]; then
ln -sf ../init.d/alignment.sh ${D}${sysconfdir}/rcS.d/S06alignment.sh
fi

View File

@ -59,44 +59,70 @@ perrorv (const char *format, ...)
return 0;
}
int main(int argc, char *argv[])
static char *
parse_arg (const char *cmdline, const char *arg)
{
FILE *cmdline_f = NULL;
char *ostree_root = NULL;
const char *p = NULL;
const char *p;
int arglen;
char *ret = NULL;
int is_eq;
arglen = strlen (arg);
assert (arglen > 0);
is_eq = *(arg+arglen-1) == '=';
p = cmdline;
while (p != NULL)
{
if (!strncmp (p, arg, arglen))
{
const char *start = p + arglen;
const char *end = strchr (start, ' ');
if (is_eq)
{
if (end)
ret = strndup (start, end - start);
else
ret = strdup (start);
}
else if (!end || end == start)
{
ret = strdup (arg);
}
break;
}
p = strchr (p, ' ');
if (p)
p += 1;
}
return ret;
}
static char *
get_file_contents (const char *path, size_t *len)
{
FILE *f = NULL;
char *ret = NULL;
int saved_errno;
char *buf = NULL;
size_t bytes_read;
size_t buf_size;
size_t buf_used;
char destpath[PATH_MAX];
char *buf;
struct stat stbuf;
char **init_argv = NULL;
int i;
int mounted_proc = 0;
cmdline_f = fopen ("/proc/cmdline", "r");
if (!cmdline_f)
f = fopen (path, "r");
if (!f)
{
if (mount ("procs", "/proc", "proc", 0, NULL) < 0)
{
perrorv ("Failed to mount /proc");
return 1;
}
mounted_proc = 1;
cmdline_f = fopen ("/proc/cmdline", "r");
if (!cmdline_f)
{
perrorv ("Failed to open /proc/cmdline (after mounting)");
return 1;
}
saved_errno = errno;
goto out;
}
buf_size = 8;
buf_size = 1024;
buf_used = 0;
buf = malloc (buf_size);
assert (buf);
while ((bytes_read = fread (buf + buf_used, 1, buf_size - buf_used, cmdline_f)) > 0)
while ((bytes_read = fread (buf + buf_used, 1, buf_size - buf_used, f)) > 0)
{
buf_used += bytes_read;
if (buf_size == buf_used)
@ -108,32 +134,82 @@ int main(int argc, char *argv[])
}
if (bytes_read < 0)
{
perrorv ("Failed to read from /proc/cmdline");
saved_errno = errno;
goto out;
}
ret = buf;
buf = NULL;
*len = buf_used;
out:
if (f)
fclose (f);
free (buf);
errno = saved_errno;
return ret;
}
int
main(int argc, char *argv[])
{
const char *toproot_bind_mounts[] = { "/home", "/root", "/tmp", NULL };
const char *ostree_bind_mounts[] = { "/var", NULL };
const char *readonly_bind_mounts[] = { "/bin", "/etc", "/lib", "/sbin", "/usr",
NULL };
char *ostree_root = NULL;
char *ostree_subinit = NULL;
char srcpath[PATH_MAX];
char destpath[PATH_MAX];
struct stat stbuf;
char **init_argv = NULL;
char *cmdline = NULL;
size_t len;
int i;
int mounted_proc = 0;
char *tmp;
int readonly;
cmdline = get_file_contents ("/proc/cmdline", &len);
if (!cmdline)
{
if (mount ("proc", "/proc", "proc", 0, NULL) < 0)
{
perrorv ("Failed to mount /proc");
return 1;
}
cmdline = get_file_contents ("/proc/cmdline", &len);
if (!cmdline)
{
perrorv ("Failed to read /proc/cmdline");
return 1;
}
}
fprintf (stderr, "ostree-init kernel cmdline: %s\n", cmdline);
fflush (stderr);
ostree_root = parse_arg (cmdline, "ostree=");
ostree_subinit = parse_arg (cmdline, "ostree-subinit=");
tmp = parse_arg (cmdline, "ro");
readonly = tmp != NULL;
free (tmp);
if (!ostree_root)
{
fprintf (stderr, "No ostree= argument specified\n");
exit (1);
}
fprintf (stderr, "ostree-init kernel cmdline: %s\n", buf);
fflush (stderr);
p = buf;
while (p != NULL)
if (!readonly)
{
if (!strncmp (p, "ostree=", strlen ("ostree=")))
if (mount ("/dev/root", "/", NULL, MS_MGC_VAL|MS_REMOUNT, NULL) < 0)
{
const char *start = p + strlen ("ostree=");
const char *end = strchr (start, ' ');
if (end)
ostree_root = strndup (start, end - start);
else
ostree_root = strdup (start);
break;
perrorv ("Failed to remount / read/write");
exit (1);
}
p = strchr (p, ' ');
if (p)
p += 1;
}
if (ostree_root)
{
snprintf (destpath, sizeof(destpath), "/ostree/%s", ostree_root);
if (stat (destpath, &stbuf) < 0)
{
@ -155,6 +231,51 @@ int main(int argc, char *argv[])
exit (1);
}
snprintf (destpath, sizeof(destpath), "/ostree/%s/dev", ostree_root);
if (mount ("udev", destpath, "devtmpfs",
MS_MGC_VAL | MS_NOSUID,
"seclabel,relatime,size=1960040k,nr_inodes=49010,mode=755") < 0)
{
perrorv ("Failed to mount devtmpfs on '%s'", destpath);
exit (1);
}
for (i = 0; toproot_bind_mounts[i] != NULL; i++)
{
snprintf (destpath, sizeof(destpath), "/ostree/%s%s", ostree_root, toproot_bind_mounts[i]);
if (mount (toproot_bind_mounts[i], destpath, NULL, MS_BIND & ~MS_RDONLY, NULL) < 0)
{
perrorv ("failed to bind mount (class:toproot) %s to %s", toproot_bind_mounts[i], destpath);
exit (1);
}
}
for (i = 0; ostree_bind_mounts[i] != NULL; i++)
{
snprintf (srcpath, sizeof(srcpath), "/ostree/%s", ostree_bind_mounts[i]);
snprintf (destpath, sizeof(destpath), "/ostree/%s%s", ostree_root, ostree_bind_mounts[i]);
if (mount (srcpath, destpath, NULL, MS_MGC_VAL|MS_BIND, NULL) < 0)
{
perrorv ("failed to bind mount (class:bind) %s to %s", srcpath, destpath);
exit (1);
}
}
for (i = 0; readonly_bind_mounts[i] != NULL; i++)
{
snprintf (destpath, sizeof(destpath), "/ostree/%s%s", ostree_root, readonly_bind_mounts[i]);
if (mount (destpath, destpath, NULL, MS_BIND, NULL) < 0)
{
perrorv ("failed to bind mount (class:readonly) %s", destpath);
exit (1);
}
if (mount (destpath, destpath, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0)
{
perrorv ("failed to bind mount (class:readonly) %s", destpath);
exit (1);
}
}
snprintf (destpath, sizeof(destpath), "/ostree/%s", ostree_root);
if (chroot (destpath) < 0)
{
@ -167,25 +288,22 @@ int main(int argc, char *argv[])
perrorv ("failed to chdir to subroot");
exit (1);
}
}
else
{
fprintf (stderr, "No ostree= argument specified\n");
exit (1);
}
if (mounted_proc)
(void)umount ("/proc");
init_argv = malloc (sizeof (char*)*(argc+1));
if (ostree_subinit)
init_argv[0] = ostree_subinit;
else
init_argv[0] = INIT_PATH;
for (i = 1; i < argc; i++)
init_argv[i] = argv[i];
init_argv[i] = NULL;
fprintf (stderr, "ostree-init: Running real init (argc=%d)\n", argc);
fprintf (stderr, "ostree-init: Running real init %s (argc=%d)\n", init_argv[0], argc);
fflush (stderr);
execv (INIT_PATH, init_argv);
execv (init_argv[0], init_argv);
perrorv ("Failed to exec init '%s'", INIT_PATH);
exit (1);
}