diff options
| -rw-r--r-- | meta/classes/package_ipk.bbclass | 2 | ||||
| -rw-r--r-- | meta/classes/rootfs_ipk.bbclass | 26 | ||||
| -rw-r--r-- | meta/recipes-devtools/opkg/opkg/fix_installorder.patch | 174 | ||||
| -rw-r--r-- | meta/recipes-devtools/opkg/opkg/offline_postinstall.patch | 57 | ||||
| -rw-r--r-- | meta/recipes-devtools/opkg/opkg/offlineroot_varname.patch | 20 | ||||
| -rw-r--r-- | meta/recipes-devtools/opkg/opkg_svn.bb | 7 |
6 files changed, 260 insertions, 26 deletions
diff --git a/meta/classes/package_ipk.bbclass b/meta/classes/package_ipk.bbclass index b5319bcbd0..9a1e5852c4 100644 --- a/meta/classes/package_ipk.bbclass +++ b/meta/classes/package_ipk.bbclass | |||
| @@ -130,7 +130,7 @@ package_install_internal_ipk() { | |||
| 130 | 130 | ||
| 131 | mkdir -p ${target_rootfs}${localstatedir}/lib/opkg/ | 131 | mkdir -p ${target_rootfs}${localstatedir}/lib/opkg/ |
| 132 | 132 | ||
| 133 | local ipkg_args="-f ${conffile} -o ${target_rootfs} --force-overwrite" | 133 | local ipkg_args="-f ${conffile} -o ${target_rootfs} --force-overwrite --force_postinstall" |
| 134 | 134 | ||
| 135 | opkg-cl ${ipkg_args} update | 135 | opkg-cl ${ipkg_args} update |
| 136 | 136 | ||
diff --git a/meta/classes/rootfs_ipk.bbclass b/meta/classes/rootfs_ipk.bbclass index 89ce86d741..37241274d2 100644 --- a/meta/classes/rootfs_ipk.bbclass +++ b/meta/classes/rootfs_ipk.bbclass | |||
| @@ -60,14 +60,14 @@ fakeroot rootfs_ipk_do_rootfs () { | |||
| 60 | export INSTALL_CONF_IPK="${IPKGCONF_TARGET}" | 60 | export INSTALL_CONF_IPK="${IPKGCONF_TARGET}" |
| 61 | export INSTALL_PACKAGES_IPK="${PACKAGE_INSTALL}" | 61 | export INSTALL_PACKAGES_IPK="${PACKAGE_INSTALL}" |
| 62 | 62 | ||
| 63 | package_install_internal_ipk | ||
| 64 | |||
| 65 | #post install | 63 | #post install |
| 66 | export D=${IMAGE_ROOTFS} | 64 | export D=${IMAGE_ROOTFS} |
| 67 | export OFFLINE_ROOT=${IMAGE_ROOTFS} | 65 | export OFFLINE_ROOT=${IMAGE_ROOTFS} |
| 68 | export IPKG_OFFLINE_ROOT=${IMAGE_ROOTFS} | 66 | export IPKG_OFFLINE_ROOT=${IMAGE_ROOTFS} |
| 69 | export OPKG_OFFLINE_ROOT=${IPKG_OFFLINE_ROOT} | 67 | export OPKG_OFFLINE_ROOT=${IPKG_OFFLINE_ROOT} |
| 70 | 68 | ||
| 69 | package_install_internal_ipk | ||
| 70 | |||
| 71 | # Distro specific packages should create this | 71 | # Distro specific packages should create this |
| 72 | #mkdir -p ${IMAGE_ROOTFS}/etc/opkg/ | 72 | #mkdir -p ${IMAGE_ROOTFS}/etc/opkg/ |
| 73 | #grep "^arch" ${IPKGCONF_TARGET} >${IMAGE_ROOTFS}/etc/opkg/arch.conf | 73 | #grep "^arch" ${IPKGCONF_TARGET} >${IMAGE_ROOTFS}/etc/opkg/arch.conf |
| @@ -75,28 +75,8 @@ fakeroot rootfs_ipk_do_rootfs () { | |||
| 75 | ${OPKG_POSTPROCESS_COMMANDS} | 75 | ${OPKG_POSTPROCESS_COMMANDS} |
| 76 | ${ROOTFS_POSTINSTALL_COMMAND} | 76 | ${ROOTFS_POSTINSTALL_COMMAND} |
| 77 | 77 | ||
| 78 | runtime_script_required=0 | ||
| 79 | |||
| 80 | # Base-passwd needs to run first to install /etc/passwd and friends | ||
| 81 | if [ -e ${IMAGE_ROOTFS}${opkglibdir}/info/base-passwd.preinst ] ; then | ||
| 82 | sh ${IMAGE_ROOTFS}${opkglibdir}/info/base-passwd.preinst | ||
| 83 | fi | ||
| 84 | |||
| 85 | for i in ${IMAGE_ROOTFS}${opkglibdir}/info/*.preinst; do | ||
| 86 | if [ -f $i ] && ! sh $i; then | ||
| 87 | runtime_script_required=1 | ||
| 88 | opkg-cl ${IPKG_ARGS} flag unpacked `basename $i .preinst` | ||
| 89 | fi | ||
| 90 | done | ||
| 91 | for i in ${IMAGE_ROOTFS}${opkglibdir}/info/*.postinst; do | ||
| 92 | if [ -f $i ] && ! sh $i configure; then | ||
| 93 | runtime_script_required=1 | ||
| 94 | opkg-cl ${IPKG_ARGS} flag unpacked `basename $i .postinst` | ||
| 95 | fi | ||
| 96 | done | ||
| 97 | |||
| 98 | if ${@base_contains("IMAGE_FEATURES", "read-only-rootfs", "true", "false" ,d)}; then | 78 | if ${@base_contains("IMAGE_FEATURES", "read-only-rootfs", "true", "false" ,d)}; then |
| 99 | if [ $runtime_script_required -eq 1 ]; then | 79 | if grep Status:.install.ok.unpacked ${IMAGE_ROOTFS}${opkglibdir}status; then |
| 100 | echo "Some packages could not be configured offline and rootfs is read-only." | 80 | echo "Some packages could not be configured offline and rootfs is read-only." |
| 101 | exit 1 | 81 | exit 1 |
| 102 | fi | 82 | fi |
diff --git a/meta/recipes-devtools/opkg/opkg/fix_installorder.patch b/meta/recipes-devtools/opkg/opkg/fix_installorder.patch new file mode 100644 index 0000000000..e782ce738d --- /dev/null +++ b/meta/recipes-devtools/opkg/opkg/fix_installorder.patch | |||
| @@ -0,0 +1,174 @@ | |||
| 1 | There is a problem with dependency order when installing packages. The key | ||
| 2 | problem revolves around the satisfy_dependencies_for() function which is | ||
| 3 | called from opkg_install_pkg just before the installation (and preinst) | ||
| 4 | happens. | ||
| 5 | |||
| 6 | The satisfy_dependencies_for() function calls pkg_hash_fetch_unsatisfied_dependencies() | ||
| 7 | which will only return packages which were previously not marked as | ||
| 8 | *going* to be installed at some point. For the purposes of | ||
| 9 | opkg_install_pkg() we really need to know which dependencies haven't been | ||
| 10 | installed yet. | ||
| 11 | |||
| 12 | This patch adds pkg_hash_fetch_satisfied_dependencies() which returns a | ||
| 13 | list of package dependencies. We can then directly check the status of | ||
| 14 | these and ensure any hard dependencies (not suggestions or recommendations) | ||
| 15 | are installed before returning. | ||
| 16 | |||
| 17 | Consider the situation (where -> means 'depends on'): | ||
| 18 | |||
| 19 | X -> A,E | ||
| 20 | A -> B,E | ||
| 21 | E -> B | ||
| 22 | B -> C | ||
| 23 | |||
| 24 | Currently X would install A and E. When installing A the packages B, E | ||
| 25 | and C would be marked as "to install". When the package B is considered | ||
| 26 | the second time (as a dependency of E rather than A), it would install | ||
| 27 | straight away even though C was not currently installed, just marked | ||
| 28 | as needing to be installed. | ||
| 29 | |||
| 30 | The patch changes the behaviour so B can't install until C really is installed. | ||
| 31 | |||
| 32 | This change is required to run the postinst scripts in the correct order. | ||
| 33 | |||
| 34 | Upstream-Status: Pending | ||
| 35 | |||
| 36 | RP 2011/12/15 | ||
| 37 | |||
| 38 | Index: trunk/libopkg/opkg_install.c | ||
| 39 | =================================================================== | ||
| 40 | --- trunk.orig/libopkg/opkg_install.c 2011-12-15 15:58:39.000000000 +0000 | ||
| 41 | +++ trunk/libopkg/opkg_install.c 2011-12-15 15:58:41.838334788 +0000 | ||
| 42 | @@ -76,6 +77,27 @@ | ||
| 43 | } | ||
| 44 | |||
| 45 | if (ndepends <= 0) { | ||
| 46 | + pkg_vec_free(depends); | ||
| 47 | + depends = pkg_hash_fetch_satisfied_dependencies(pkg); | ||
| 48 | + | ||
| 49 | + for (i = 0; i < depends->len; i++) { | ||
| 50 | + dep = depends->pkgs[i]; | ||
| 51 | + /* The package was uninstalled when we started, but another | ||
| 52 | + dep earlier in this loop may have depended on it and pulled | ||
| 53 | + it in, so check first. */ | ||
| 54 | + if ((dep->state_status != SS_INSTALLED) && (dep->state_status != SS_UNPACKED)) { | ||
| 55 | + opkg_msg(DEBUG2,"Calling opkg_install_pkg.\n"); | ||
| 56 | + err = opkg_install_pkg(dep, 0); | ||
| 57 | + /* mark this package as having been automatically installed to | ||
| 58 | + * satisfy a dependancy */ | ||
| 59 | + dep->auto_installed = 1; | ||
| 60 | + if (err) { | ||
| 61 | + pkg_vec_free(depends); | ||
| 62 | + return err; | ||
| 63 | + } | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | pkg_vec_free(depends); | ||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | Index: trunk/libopkg/pkg_depends.c | ||
| 71 | =================================================================== | ||
| 72 | --- trunk.orig/libopkg/pkg_depends.c 2010-12-22 16:04:43.000000000 +0000 | ||
| 73 | +++ trunk/libopkg/pkg_depends.c 2011-12-15 15:58:41.838334788 +0000 | ||
| 74 | @@ -259,6 +259,88 @@ | ||
| 75 | return unsatisfied->len; | ||
| 76 | } | ||
| 77 | |||
| 78 | + | ||
| 79 | +pkg_vec_t * | ||
| 80 | +pkg_hash_fetch_satisfied_dependencies(pkg_t * pkg) | ||
| 81 | +{ | ||
| 82 | + pkg_vec_t *satisfiers; | ||
| 83 | + int i, j, k; | ||
| 84 | + int count; | ||
| 85 | + abstract_pkg_t * ab_pkg; | ||
| 86 | + | ||
| 87 | + satisfiers = pkg_vec_alloc(); | ||
| 88 | + | ||
| 89 | + /* | ||
| 90 | + * this is a setup to check for redundant/cyclic dependency checks, | ||
| 91 | + * which are marked at the abstract_pkg level | ||
| 92 | + */ | ||
| 93 | + if (!(ab_pkg = pkg->parent)) { | ||
| 94 | + opkg_msg(ERROR, "Internal error, with pkg %s.\n", pkg->name); | ||
| 95 | + return satisfiers; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count; | ||
| 99 | + if (!count) | ||
| 100 | + return satisfiers; | ||
| 101 | + | ||
| 102 | + /* foreach dependency */ | ||
| 103 | + for (i = 0; i < count; i++) { | ||
| 104 | + compound_depend_t * compound_depend = &pkg->depends[i]; | ||
| 105 | + depend_t ** possible_satisfiers = compound_depend->possibilities;; | ||
| 106 | + | ||
| 107 | + if (compound_depend->type == RECOMMEND || compound_depend->type == SUGGEST) | ||
| 108 | + continue; | ||
| 109 | + | ||
| 110 | + if (compound_depend->type == GREEDY_DEPEND) { | ||
| 111 | + /* foreach possible satisfier */ | ||
| 112 | + for (j = 0; j < compound_depend->possibility_count; j++) { | ||
| 113 | + /* foreach provided_by, which includes the abstract_pkg itself */ | ||
| 114 | + abstract_pkg_t *abpkg = possible_satisfiers[j]->pkg; | ||
| 115 | + abstract_pkg_vec_t *ab_provider_vec = abpkg->provided_by; | ||
| 116 | + int nposs = ab_provider_vec->len; | ||
| 117 | + abstract_pkg_t **ab_providers = ab_provider_vec->pkgs; | ||
| 118 | + int l; | ||
| 119 | + for (l = 0; l < nposs; l++) { | ||
| 120 | + pkg_vec_t *test_vec = ab_providers[l]->pkgs; | ||
| 121 | + /* if no depends on this one, try the first package that Provides this one */ | ||
| 122 | + if (!test_vec){ /* no pkg_vec hooked up to the abstract_pkg! (need another feed?) */ | ||
| 123 | + continue; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + /* cruise this possiblity's pkg_vec looking for an installed version */ | ||
| 127 | + for (k = 0; k < test_vec->len; k++) { | ||
| 128 | + pkg_t *pkg_scout = test_vec->pkgs[k]; | ||
| 129 | + /* not installed, and not already known about? */ | ||
| 130 | + if (pkg_scout->state_want == SW_INSTALL && pkg_scout != pkg) | ||
| 131 | + pkg_vec_insert(satisfiers, pkg_scout); | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + continue; | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | + /* foreach possible satisfier, look for installed package */ | ||
| 140 | + for (j = 0; j < compound_depend->possibility_count; j++) { | ||
| 141 | + /* foreach provided_by, which includes the abstract_pkg itself */ | ||
| 142 | + depend_t *dependence_to_satisfy = possible_satisfiers[j]; | ||
| 143 | + abstract_pkg_t *satisfying_apkg = possible_satisfiers[j]->pkg; | ||
| 144 | + pkg_t *satisfying_pkg = | ||
| 145 | + pkg_hash_fetch_best_installation_candidate(satisfying_apkg, | ||
| 146 | + pkg_installed_and_constraint_satisfied, | ||
| 147 | + dependence_to_satisfy, 1); | ||
| 148 | + /* Being that I can't test constraing in pkg_hash, I will test it here */ | ||
| 149 | + if (satisfying_pkg != NULL && satisfying_pkg != pkg) { | ||
| 150 | + if (pkg_constraint_satisfied(satisfying_pkg, dependence_to_satisfy) && satisfying_pkg->state_want == SW_INSTALL) | ||
| 151 | + pkg_vec_insert(satisfiers, satisfying_pkg); | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + } | ||
| 155 | + } | ||
| 156 | + return satisfiers; | ||
| 157 | +} | ||
| 158 | + | ||
| 159 | + | ||
| 160 | /*checking for conflicts !in replaces | ||
| 161 | If a packages conflicts with another but is also replacing it, I should not consider it a | ||
| 162 | really conflicts | ||
| 163 | Index: trunk/libopkg/pkg_depends.h | ||
| 164 | =================================================================== | ||
| 165 | --- trunk.orig/libopkg/pkg_depends.h 2010-12-22 16:04:43.000000000 +0000 | ||
| 166 | +++ trunk/libopkg/pkg_depends.h 2011-12-15 15:58:41.838334788 +0000 | ||
| 167 | @@ -82,6 +82,7 @@ | ||
| 168 | void buildDependedUponBy(pkg_t * pkg, abstract_pkg_t * ab_pkg); | ||
| 169 | int version_constraints_satisfied(depend_t * depends, pkg_t * pkg); | ||
| 170 | int pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t *depends, char *** unresolved); | ||
| 171 | +pkg_vec_t * pkg_hash_fetch_satisfied_dependencies(pkg_t * pkg); | ||
| 172 | pkg_vec_t * pkg_hash_fetch_conflicts(pkg_t * pkg); | ||
| 173 | int pkg_dependence_satisfiable(depend_t *depend); | ||
| 174 | int pkg_dependence_satisfied(depend_t *depend); | ||
diff --git a/meta/recipes-devtools/opkg/opkg/offline_postinstall.patch b/meta/recipes-devtools/opkg/opkg/offline_postinstall.patch new file mode 100644 index 0000000000..b197f6b731 --- /dev/null +++ b/meta/recipes-devtools/opkg/opkg/offline_postinstall.patch | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | When we have an offline root and have specified force-postinstall, | ||
| 2 | attempt to run the postinstall but if it fails, just leave it in the | ||
| 3 | status file as neeing to run. We can issue a NOTICE this is happened | ||
| 4 | but supress errors. This means the OE class doesn't have to do any | ||
| 5 | further post processing of the postinstalls itself. | ||
| 6 | |||
| 7 | Upstream-Status: Pending | ||
| 8 | |||
| 9 | RP 2011/12/15 | ||
| 10 | |||
| 11 | |||
| 12 | Index: trunk/libopkg/pkg.c | ||
| 13 | =================================================================== | ||
| 14 | --- trunk.orig/libopkg/pkg.c 2011-12-15 15:58:39.000000000 +0000 | ||
| 15 | +++ trunk/libopkg/pkg.c 2011-12-15 20:04:50.109992736 +0000 | ||
| 16 | @@ -1297,8 +1297,9 @@ | ||
| 17 | free(cmd); | ||
| 18 | |||
| 19 | if (err) { | ||
| 20 | - opkg_msg(ERROR, "package \"%s\" %s script returned status %d.\n", | ||
| 21 | - pkg->name, script, err); | ||
| 22 | + if (!conf->offline_root) | ||
| 23 | + opkg_msg(ERROR, "package \"%s\" %s script returned status %d.\n", | ||
| 24 | + pkg->name, script, err); | ||
| 25 | return err; | ||
| 26 | } | ||
| 27 | |||
| 28 | Index: trunk/libopkg/opkg_cmd.c | ||
| 29 | =================================================================== | ||
| 30 | --- trunk.orig/libopkg/opkg_cmd.c 2011-12-15 19:49:25.826014150 +0000 | ||
| 31 | +++ trunk/libopkg/opkg_cmd.c 2011-12-15 19:50:52.346012148 +0000 | ||
| 32 | @@ -453,7 +453,8 @@ | ||
| 33 | pkg->state_flag &= ~SF_PREFER; | ||
| 34 | opkg_state_changed++; | ||
| 35 | } else { | ||
| 36 | - err = -1; | ||
| 37 | + if (!conf->offline_root) | ||
| 38 | + err = -1; | ||
| 39 | } | ||
| 40 | } | ||
| 41 | } | ||
| 42 | Index: trunk/libopkg/opkg_configure.c | ||
| 43 | =================================================================== | ||
| 44 | --- trunk.orig/libopkg/opkg_configure.c 2011-12-15 19:50:11.586013081 +0000 | ||
| 45 | +++ trunk/libopkg/opkg_configure.c 2011-12-15 19:52:15.082010347 +0000 | ||
| 46 | @@ -35,7 +35,10 @@ | ||
| 47 | |||
| 48 | err = pkg_run_script(pkg, "postinst", "configure"); | ||
| 49 | if (err) { | ||
| 50 | - opkg_msg(ERROR, "%s.postinst returned %d.\n", pkg->name, err); | ||
| 51 | + if (!conf->offline_root) | ||
| 52 | + opkg_msg(ERROR, "%s.postinst returned %d.\n", pkg->name, err); | ||
| 53 | + else | ||
| 54 | + opkg_msg(NOTICE, "%s.postinst returned %d, marking as unpacked only, configuration required on target.\n", pkg->name, err); | ||
| 55 | return err; | ||
| 56 | } | ||
| 57 | |||
diff --git a/meta/recipes-devtools/opkg/opkg/offlineroot_varname.patch b/meta/recipes-devtools/opkg/opkg/offlineroot_varname.patch new file mode 100644 index 0000000000..a67f389bac --- /dev/null +++ b/meta/recipes-devtools/opkg/opkg/offlineroot_varname.patch | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | OE uses D as the offline install directory in its scripts, not PKG_ROOT. | ||
| 2 | |||
| 3 | Upstream-Status: Inappropriate [OE specific usage] | ||
| 4 | |||
| 5 | RP 2011/12/15 | ||
| 6 | |||
| 7 | Index: trunk/libopkg/pkg.c | ||
| 8 | =================================================================== | ||
| 9 | --- trunk.orig/libopkg/pkg.c 2011-12-15 15:58:39.000000000 +0000 | ||
| 10 | +++ trunk/libopkg/pkg.c 2011-12-15 20:04:50.109992736 +0000 | ||
| 11 | @@ -1280,7 +1280,7 @@ | ||
| 12 | |||
| 13 | opkg_msg(INFO, "Running script %s.\n", path); | ||
| 14 | |||
| 15 | - setenv("PKG_ROOT", | ||
| 16 | + setenv("D", | ||
| 17 | pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1); | ||
| 18 | |||
| 19 | if (! file_exists(path)) { | ||
| 20 | |||
diff --git a/meta/recipes-devtools/opkg/opkg_svn.bb b/meta/recipes-devtools/opkg/opkg_svn.bb index acb21f2cb9..2645d52c81 100644 --- a/meta/recipes-devtools/opkg/opkg_svn.bb +++ b/meta/recipes-devtools/opkg/opkg_svn.bb | |||
| @@ -12,13 +12,16 @@ RREPLACES_${PN} = "opkg-nogpg" | |||
| 12 | SRC_URI = "svn://opkg.googlecode.com/svn;module=trunk;proto=http \ | 12 | SRC_URI = "svn://opkg.googlecode.com/svn;module=trunk;proto=http \ |
| 13 | file://add_vercmp.patch \ | 13 | file://add_vercmp.patch \ |
| 14 | file://add_uname_support.patch \ | 14 | file://add_uname_support.patch \ |
| 15 | file://fix_installorder.patch \ | ||
| 16 | file://offline_postinstall.patch\ | ||
| 17 | file://offlineroot_varname.patch \ | ||
| 15 | " | 18 | " |
| 16 | 19 | ||
| 17 | S = "${WORKDIR}/trunk" | 20 | S = "${WORKDIR}/trunk" |
| 18 | 21 | ||
| 19 | SRCREV = "625" | 22 | SRCREV = "633" |
| 20 | PV = "0.1.8+svnr${SRCPV}" | 23 | PV = "0.1.8+svnr${SRCPV}" |
| 21 | PR = "r4" | 24 | PR = "r2" |
| 22 | 25 | ||
| 23 | PACKAGES =+ "libopkg${PKGSUFFIX}-dev libopkg${PKGSUFFIX} update-alternatives-cworth${PKGSUFFIX}" | 26 | PACKAGES =+ "libopkg${PKGSUFFIX}-dev libopkg${PKGSUFFIX} update-alternatives-cworth${PKGSUFFIX}" |
| 24 | 27 | ||
