[oe-commits] Mike Westerhof : SlugOS: Add SlugOS-specific patch to opkg, switch SlugOS to opkg.

git version control git at git.openembedded.org
Sun Feb 13 01:17:11 UTC 2011


Module: openembedded.git
Branch: org.openembedded.dev
Commit: 17481d563f858fdc6b8d92f433e2746fd8f39e11
URL:    http://gitweb.openembedded.net/?p=openembedded.git&a=commit;h=17481d563f858fdc6b8d92f433e2746fd8f39e11

Author: Mike Westerhof <mwester at dls.net>
Date:   Sat Feb 12 19:12:19 2011 -0600

SlugOS: Add SlugOS-specific patch to opkg, switch SlugOS to opkg.
Nothing changes for any other distros (patch is pulled in via override),
but it enables SlugOS to now use the standard opkg recipe.
Cleanup of the old recipe and patches will happen after further testing.

---

 conf/distro/slugos.conf                        |    6 +-
 recipes/opkg/files/opkg_use_vfork_gunzip.patch |  139 ++++++++++++++++++++++++
 recipes/opkg/opkg.inc                          |    2 +-
 recipes/opkg/opkg_svn.bb                       |    1 +
 4 files changed, 144 insertions(+), 4 deletions(-)

diff --git a/conf/distro/slugos.conf b/conf/distro/slugos.conf
index 96c2f45..049e24e 100644
--- a/conf/distro/slugos.conf
+++ b/conf/distro/slugos.conf
@@ -11,9 +11,9 @@ DISTRO_NAME = "SlugOS"
 DISTRO_TYPE = "alpha"
 TARGET_ARCH ?= "armeb"
 ARM_INSTRUCTION_SET = "thumb"
-IPKG_VARIANT ?= "opkg-nogpg-nocurl-slugos"
-PREFERRED_PROVIDER_opkg ?= "opkg-nogpg-nocurl-slugos"
-PREFERRED_PROVIDER_virtual/update-alternatives ?= "opkg-nogpg-nocurl-slugos"
+IPKG_VARIANT ?= "opkg"
+PREFERRED_PROVIDER_opkg ?= "opkg"
+PREFERRED_PROVIDER_virtual/update-alternatives ?= "opkg"
 IMAGE_INITSCRIPTS ?= "initscripts-slugos"
 IMAGE_DEV_MANAGER = "udev"
 # Disable installing ldconfig
diff --git a/recipes/opkg/files/opkg_use_vfork_gunzip.patch b/recipes/opkg/files/opkg_use_vfork_gunzip.patch
new file mode 100644
index 0000000..d9c40df
--- /dev/null
+++ b/recipes/opkg/files/opkg_use_vfork_gunzip.patch
@@ -0,0 +1,139 @@
+# This patch allows a user to set an environment variable to cause opkg to
+# select either the built-in gunzip code or an external gunzip utility, in
+# order to dodge the OOM Killer.
+# 
+# The built-in code is, of course, is the most desirable way to use opkg,
+# since it is far more efficient.  However, the built-in code can trigger
+# the OOM (out of memory) killer on small-memory machines, like the 32MB
+# NSLU2.  This occurs because a standard fork will duplicate the entire
+# address space of the parent.  Since opkg reads the entire feed database
+# into memory, this problem is compounded by large feeds.
+#
+# This patch introduces a means for the user to cause opkg to use vfork()
+# instead -- vfork() does not behave in the same manner as fork(), and
+# does not trigger the OOM killer.  However, the semantics of vfork() are
+# such that it cannot run the built-in gunzip code.  Instead, it must
+# exec() an external utility to perform the gunzip operation.  It seems
+# counter-intuitive, but the vfork()/exec() approach is the only good way
+# to avoid triggering the dreaded OOM killer.
+#
+# In order to use this, the user must manually set the OPKG_USE_VFORK
+# environment variable to any value.  For example:
+#
+# $ OPKG_USE_VFORK=1 opkg install samba
+#
+# The external utility used to do the gunzip operation is "busybox gunzip".
+# It would have been nice to be able to just invoke "gunzip", but the
+# full gunzip executable behaves slightly differently than does busybox,
+# generating annoying warning messages.
+#
+# This is an update of the original patch by Mike Westerhof, Dec 2008.
+#
+# Mike Westerhof, Feb 2011
+#
+--- orig/libbb/gz_open.c	2011-02-12 10:58:02.035287826 -0600
++++ opkg/libbb/gz_open.c	2011-02-12 11:51:12.120033055 -0600
+@@ -29,10 +29,29 @@
+ #include <unistd.h>
+ #include "libbb.h"
+ 
++int
++gz_use_vfork()
++{
++	char *v = getenv("OPKG_USE_VFORK");
++	return (v != NULL);
++}
++
+ FILE *
+ gz_open(FILE *compressed_file, int *pid)
+ {
+ 	int unzip_pipe[2];
++	off_t floc;
++	int cfile;
++
++	if (gz_use_vfork()) {
++		/* Create a new file descriptor for the input stream
++		 * (it *must* be associated with a file), and lseek()
++		 * to the same position in that fd as the stream.
++		 */
++		cfile = dup(fileno(compressed_file));
++		floc = ftello(compressed_file);
++		lseek(cfile, floc, SEEK_SET);
++	}
+ 
+ 	if (pipe(unzip_pipe)!=0) {
+ 		perror_msg("pipe");
+@@ -44,18 +63,37 @@
+     fflush(stdout);
+     fflush(stderr);
+ 
+-	if ((*pid = fork()) == -1) {
++	if (gz_use_vfork()) {
++		*pid = vfork();
++	} else {
++		*pid = fork();
++	}
++
++	if (*pid<0) {
+ 		perror_msg("fork");
+ 		return(NULL);
+ 	}
++
+ 	if (*pid==0) {
+ 		/* child process */
+ 		close(unzip_pipe[0]);
+-		unzip(compressed_file, fdopen(unzip_pipe[1], "w"));
+-		fflush(NULL);
+-		fclose(compressed_file);
+-		close(unzip_pipe[1]);
+-		_exit(EXIT_SUCCESS);
++		if (gz_use_vfork()) {
++			dup2(unzip_pipe[1], 1);
++			dup2(cfile, 0);
++			execlp("busybox","busybox","gunzip",NULL);
++			/* If we get here, we had a failure */
++			_exit(EXIT_FAILURE);
++		} else {
++			unzip(compressed_file, fdopen(unzip_pipe[1], "w"));
++			fflush(NULL);
++			fclose(compressed_file);
++			close(unzip_pipe[1]);
++			_exit(EXIT_SUCCESS);
++		}
++	}
++	/* Parent process is executing here */
++	if (gz_use_vfork()) {
++		close(cfile);
+ 	}
+ 	close(unzip_pipe[1]);
+ 	return(fdopen(unzip_pipe[0], "r"));
+@@ -67,11 +105,29 @@
+ 	int status;
+ 	int ret;
+ 
++	if (gz_use_vfork()) {
++		/* The gunzip process remains running in the background if we
++		 * used the vfork()/exec() technique - so we have to kill it
++		 * forcibly.  There might be a better way to do this, but that
++		 * affect a lot of other parts of opkg, and this works fine.
++		 */
++		if (kill(gunzip_pid, SIGTERM) == -1) {
++			perror_msg("gz_close(): unable to kill gunzip pid.");
++			return -1;
++		}
++        }
++
++
+ 	if (waitpid(gunzip_pid, &status, 0) == -1) {
+ 		perror_msg("waitpid");
+ 		return -1;
+ 	}
+ 
++	if (gz_use_vfork()) {
++		/* Bail out here if we used the vfork()/exec() technique. */
++		return 0;
++	}
++
+ 	if (WIFSIGNALED(status)) {
+ 		error_msg("Unzip process killed by signal %d.\n",
+ 			WTERMSIG(status));
diff --git a/recipes/opkg/opkg.inc b/recipes/opkg/opkg.inc
index c0025c0..a4878e2 100644
--- a/recipes/opkg/opkg.inc
+++ b/recipes/opkg/opkg.inc
@@ -5,7 +5,7 @@ LICENSE = "GPLv2"
 SRCREV = "599"
 PV = "0.1.8+svnr${SRCPV}"
 CONFLICTS = "ipkg"
-INC_PR = "r3"
+INC_PR = "r4"
 
 SRC_URI = "svn://opkg.googlecode.com/svn;module=trunk;proto=http \
 	   file://configure \
diff --git a/recipes/opkg/opkg_svn.bb b/recipes/opkg/opkg_svn.bb
index 7ea1510..cc377b7 100644
--- a/recipes/opkg/opkg_svn.bb
+++ b/recipes/opkg/opkg_svn.bb
@@ -2,6 +2,7 @@ require opkg.inc
 
 PR = "${INC_PR}"
 
+SRC_URI_append_slugos = " file://opkg_use_vfork_gunzip.patch"
 
 PROVIDES =+ "virtual/update-alternatives"
 RPROVIDES_${PN} = "update-alternatives"





More information about the Openembedded-commits mailing list