[ostree] gnomeos: Mounts work, far fewer boot errors



commit 073aa5973c1b59108ce85ccfc0f08c1ffe9a2efc
Author: Colin Walters <walters verbum org>
Date:   Wed Nov 16 12:51:24 2011 -0500

    gnomeos: Mounts work, far fewer boot errors

 gnomeos/yocto/conf/distro/gnomeosdistro.conf       |   48 ++++
 .../recipies-core/images/gnomeos-image-contents.bb |   17 ++-
 .../initscripts/initscripts-1.0/checkfs.sh         |   49 ----
 .../initscripts/initscripts-1.0/checkroot.sh       |  137 -----------
 .../initscripts/initscripts-1.0/devpts             |    5 -
 .../initscripts/initscripts-1.0/devpts.sh          |   28 ---
 .../initscripts-1.0/populate-volatile.sh           |  197 ----------------
 .../initscripts/initscripts-1.0/sysfs.sh           |   19 --
 .../initscripts/initscripts-1.0/volatiles          |   39 ---
 .../recipies-core/initscripts/initscripts_1.0.bb   |   19 --
 .../yocto/recipies-core/ostree-init/ostree-init.c  |  246 +++++++++++++++-----
 11 files changed, 246 insertions(+), 558 deletions(-)
---
diff --git a/gnomeos/yocto/conf/distro/gnomeosdistro.conf b/gnomeos/yocto/conf/distro/gnomeosdistro.conf
new file mode 100644
index 0000000..2c76aae
--- /dev/null
+++ b/gnomeos/yocto/conf/distro/gnomeosdistro.conf
@@ -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";
+
diff --git a/gnomeos/yocto/recipies-core/images/gnomeos-image-contents.bb b/gnomeos/yocto/recipies-core/images/gnomeos-image-contents.bb
index 7e2e273..abe5d63 100644
--- a/gnomeos/yocto/recipies-core/images/gnomeos-image-contents.bb
+++ b/gnomeos/yocto/recipies-core/images/gnomeos-image-contents.bb
@@ -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"
diff --git a/gnomeos/yocto/recipies-core/initscripts/initscripts_1.0.bb b/gnomeos/yocto/recipies-core/initscripts/initscripts_1.0.bb
index ffca817..aa20e5f 100644
--- a/gnomeos/yocto/recipies-core/initscripts/initscripts_1.0.bb
+++ b/gnomeos/yocto/recipies-core/initscripts/initscripts_1.0.bb
@@ -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
diff --git a/gnomeos/yocto/recipies-core/ostree-init/ostree-init.c b/gnomeos/yocto/recipies-core/ostree-init/ostree-init.c
index 2c214e8..952f8ea 100644
--- a/gnomeos/yocto/recipies-core/ostree-init/ostree-init.c
+++ b/gnomeos/yocto/recipies-core/ostree-init/ostree-init.c
@@ -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,69 +134,158 @@ int main(int argc, char *argv[])
     }
   if (bytes_read < 0)
     {
-      perrorv ("Failed to read from /proc/cmdline");
-      exit (1);
+      saved_errno = errno;
+      goto out;
     }
 
-  fprintf (stderr, "ostree-init kernel cmdline: %s\n", buf);
-  fflush (stderr);
-  p = buf;
-  while (p != NULL)
+  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 (!strncmp (p, "ostree=", strlen ("ostree=")))
+      if (mount ("proc", "/proc", "proc", 0, 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 mount /proc");
+	  return 1;
+	}
+      cmdline = get_file_contents ("/proc/cmdline", &len);
+      if (!cmdline)
+	{
+	  perrorv ("Failed to read /proc/cmdline");
+	  return 1;
 	}
-      p = strchr (p, ' ');
-      if (p)
-	p += 1;
     }
 
-  if (ostree_root)
+  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)
     {
-      snprintf (destpath, sizeof(destpath), "/ostree/%s", ostree_root);
-      if (stat (destpath, &stbuf) < 0)
+      fprintf (stderr, "No ostree= argument specified\n");
+      exit (1);
+    }
+
+  if (!readonly)
+    {
+      if (mount ("/dev/root", "/", NULL, MS_MGC_VAL|MS_REMOUNT, NULL) < 0)
 	{
-	  perrorv ("Invalid ostree root '%s'", destpath);
+	  perrorv ("Failed to remount / read/write");
 	  exit (1);
 	}
+    }
+
+  snprintf (destpath, sizeof(destpath), "/ostree/%s", ostree_root);
+  if (stat (destpath, &stbuf) < 0)
+    {
+      perrorv ("Invalid ostree root '%s'", destpath);
+      exit (1);
+    }
+  
+  snprintf (destpath, sizeof(destpath), "/ostree/%s/var", ostree_root);
+  if (mount ("/ostree/var", destpath, NULL, MS_BIND, NULL) < 0)
+    {
+      perrorv ("Failed to bind mount / to '%s'", destpath);
+      exit (1);
+    }
+  
+  snprintf (destpath, sizeof(destpath), "/ostree/%s/sysroot", ostree_root);
+  if (mount ("/", destpath, NULL, MS_BIND, NULL) < 0)
+    {
+      perrorv ("Failed to bind mount / to '%s'", destpath);
+      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);
+    }
 
-      snprintf (destpath, sizeof(destpath), "/ostree/%s/var", ostree_root);
-      if (mount ("/ostree/var", destpath, NULL, MS_BIND, NULL) < 0)
+  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 / to '%s'", destpath);
+	  perrorv ("failed to bind mount (class:toproot) %s to %s", toproot_bind_mounts[i], destpath);
 	  exit (1);
 	}
+    }
 
-      snprintf (destpath, sizeof(destpath), "/ostree/%s/sysroot", ostree_root);
-      if (mount ("/", destpath, NULL, MS_BIND, NULL) < 0)
+  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 / to '%s'", destpath);
+	  perrorv ("failed to bind mount (class:bind) %s to %s", srcpath, destpath);
 	  exit (1);
 	}
+    }
 
-      snprintf (destpath, sizeof(destpath), "/ostree/%s", ostree_root);
-      if (chroot (destpath) < 0)
+  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 change root to '%s'", destpath);
+	  perrorv ("failed to bind mount (class:readonly) %s", destpath);
 	  exit (1);
 	}
-
-      if (chdir ("/") < 0)
+      if (mount (destpath, destpath, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0)
 	{
-	  perrorv ("failed to chdir to subroot");
+	  perrorv ("failed to bind mount (class:readonly) %s", destpath);
 	  exit (1);
 	}
     }
-  else
+  
+  snprintf (destpath, sizeof(destpath), "/ostree/%s", ostree_root);
+  if (chroot (destpath) < 0)
     {
-      fprintf (stderr, "No ostree= argument specified\n");
+      perrorv ("failed to change root to '%s'", destpath);
+      exit (1);
+    }
+
+  if (chdir ("/") < 0)
+    {
+      perrorv ("failed to chdir to subroot");
       exit (1);
     }
 
@@ -178,14 +293,17 @@ int main(int argc, char *argv[])
     (void)umount ("/proc");
 
   init_argv = malloc (sizeof (char*)*(argc+1));
-  init_argv[0] = INIT_PATH;
+  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);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]