summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/opkg/opkg/0003-Fix-dependency-issues-for-preinst-scripts.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/opkg/opkg/0003-Fix-dependency-issues-for-preinst-scripts.patch')
-rw-r--r--meta/recipes-devtools/opkg/opkg/0003-Fix-dependency-issues-for-preinst-scripts.patch188
1 files changed, 188 insertions, 0 deletions
diff --git a/meta/recipes-devtools/opkg/opkg/0003-Fix-dependency-issues-for-preinst-scripts.patch b/meta/recipes-devtools/opkg/opkg/0003-Fix-dependency-issues-for-preinst-scripts.patch
new file mode 100644
index 0000000000..195598f287
--- /dev/null
+++ b/meta/recipes-devtools/opkg/opkg/0003-Fix-dependency-issues-for-preinst-scripts.patch
@@ -0,0 +1,188 @@
1From 6a294b6dad681b0e95aa061bc368d801d2ddc781 Mon Sep 17 00:00:00 2001
2From: Richard Purdie <richard.purdie@linuxfoundation.org>
3Date: Thu, 15 Dec 2011 21:08:49 +0000
4Subject: [PATCH 3/7] Fix dependency issues for preinst scripts
5
6There is a problem with dependency order when installing packages. The key
7problem revolves around the satisfy_dependencies_for() function which is
8called from opkg_install_pkg just before the installation (and preinst)
9happens.
10
11The satisfy_dependencies_for() function calls pkg_hash_fetch_unsatisfied_dependencies()
12which will only return packages which were previously not marked as
13*going* to be installed at some point. For the purposes of
14opkg_install_pkg() we really need to know which dependencies haven't been
15installed yet.
16
17This patch adds pkg_hash_fetch_satisfied_dependencies() which returns a
18list of package dependencies. We can then directly check the status of
19these and ensure any hard dependencies (not suggestions or recommendations)
20are installed before returning.
21
22Consider the situation (where -> means 'depends on'):
23
24X -> A,E
25A -> B,E
26E -> B
27B -> C
28
29Currently X would install A and E. When installing A the packages B, E
30and C would be marked as "to install". When the package B is considered
31the second time (as a dependency of E rather than A), it would install
32straight away even though C was not currently installed, just marked
33as needing to be installed.
34
35The patch changes the behaviour so B can't install until C really is installed.
36
37This change is required to run the postinst scripts in the correct order.
38
39Upstream-Status: Submitted
40http://code.google.com/p/opkg/issues/detail?id=93
41
42Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
43---
44 libopkg/opkg_install.c | 21 +++++++++++++
45 libopkg/pkg_depends.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++
46 libopkg/pkg_depends.h | 1 +
47 3 files changed, 104 insertions(+)
48
49diff --git a/libopkg/opkg_install.c b/libopkg/opkg_install.c
50index 3925f58..1632066 100644
51--- a/libopkg/opkg_install.c
52+++ b/libopkg/opkg_install.c
53@@ -76,6 +76,27 @@ satisfy_dependencies_for(pkg_t *pkg)
54 }
55
56 if (ndepends <= 0) {
57+ pkg_vec_free(depends);
58+ depends = pkg_hash_fetch_satisfied_dependencies(pkg);
59+
60+ for (i = 0; i < depends->len; i++) {
61+ dep = depends->pkgs[i];
62+ /* The package was uninstalled when we started, but another
63+ dep earlier in this loop may have depended on it and pulled
64+ it in, so check first. */
65+ if ((dep->state_status != SS_INSTALLED) && (dep->state_status != SS_UNPACKED)) {
66+ opkg_msg(DEBUG2,"Calling opkg_install_pkg.\n");
67+ err = opkg_install_pkg(dep, 0);
68+ /* mark this package as having been automatically installed to
69+ * satisfy a dependency */
70+ dep->auto_installed = 1;
71+ if (err) {
72+ pkg_vec_free(depends);
73+ return err;
74+ }
75+ }
76+ }
77+
78 pkg_vec_free(depends);
79 return 0;
80 }
81diff --git a/libopkg/pkg_depends.c b/libopkg/pkg_depends.c
82index 1e14d1f..36c76aa 100644
83--- a/libopkg/pkg_depends.c
84+++ b/libopkg/pkg_depends.c
85@@ -259,6 +259,88 @@ pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t *unsatisfied,
86 return unsatisfied->len;
87 }
88
89+
90+pkg_vec_t *
91+pkg_hash_fetch_satisfied_dependencies(pkg_t * pkg)
92+{
93+ pkg_vec_t *satisfiers;
94+ int i, j, k;
95+ int count;
96+ abstract_pkg_t * ab_pkg;
97+
98+ satisfiers = pkg_vec_alloc();
99+
100+ /*
101+ * this is a setup to check for redundant/cyclic dependency checks,
102+ * which are marked at the abstract_pkg level
103+ */
104+ if (!(ab_pkg = pkg->parent)) {
105+ opkg_msg(ERROR, "Internal error, with pkg %s.\n", pkg->name);
106+ return satisfiers;
107+ }
108+
109+ count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count;
110+ if (!count)
111+ return satisfiers;
112+
113+ /* foreach dependency */
114+ for (i = 0; i < count; i++) {
115+ compound_depend_t * compound_depend = &pkg->depends[i];
116+ depend_t ** possible_satisfiers = compound_depend->possibilities;;
117+
118+ if (compound_depend->type == RECOMMEND || compound_depend->type == SUGGEST)
119+ continue;
120+
121+ if (compound_depend->type == GREEDY_DEPEND) {
122+ /* foreach possible satisfier */
123+ for (j = 0; j < compound_depend->possibility_count; j++) {
124+ /* foreach provided_by, which includes the abstract_pkg itself */
125+ abstract_pkg_t *abpkg = possible_satisfiers[j]->pkg;
126+ abstract_pkg_vec_t *ab_provider_vec = abpkg->provided_by;
127+ int nposs = ab_provider_vec->len;
128+ abstract_pkg_t **ab_providers = ab_provider_vec->pkgs;
129+ int l;
130+ for (l = 0; l < nposs; l++) {
131+ pkg_vec_t *test_vec = ab_providers[l]->pkgs;
132+ /* if no depends on this one, try the first package that Provides this one */
133+ if (!test_vec){ /* no pkg_vec hooked up to the abstract_pkg! (need another feed?) */
134+ continue;
135+ }
136+
137+ /* cruise this possiblity's pkg_vec looking for an installed version */
138+ for (k = 0; k < test_vec->len; k++) {
139+ pkg_t *pkg_scout = test_vec->pkgs[k];
140+ /* not installed, and not already known about? */
141+ if (pkg_scout->state_want == SW_INSTALL && pkg_scout != pkg)
142+ pkg_vec_insert(satisfiers, pkg_scout);
143+ }
144+ }
145+ }
146+
147+ continue;
148+ }
149+
150+ /* foreach possible satisfier, look for installed package */
151+ for (j = 0; j < compound_depend->possibility_count; j++) {
152+ /* foreach provided_by, which includes the abstract_pkg itself */
153+ depend_t *dependence_to_satisfy = possible_satisfiers[j];
154+ abstract_pkg_t *satisfying_apkg = possible_satisfiers[j]->pkg;
155+ pkg_t *satisfying_pkg =
156+ pkg_hash_fetch_best_installation_candidate(satisfying_apkg,
157+ pkg_installed_and_constraint_satisfied,
158+ dependence_to_satisfy, 0);
159+ /* Being that I can't test constraing in pkg_hash, I will test it here */
160+ if (satisfying_pkg != NULL && satisfying_pkg != pkg) {
161+ if (pkg_constraint_satisfied(satisfying_pkg, dependence_to_satisfy) && (satisfying_pkg->state_want == SW_INSTALL || satisfying_pkg->state_want == SW_UNKNOWN))
162+ pkg_vec_insert(satisfiers, satisfying_pkg);
163+ }
164+
165+ }
166+ }
167+ return satisfiers;
168+}
169+
170+
171 /*checking for conflicts !in replaces
172 If a packages conflicts with another but is also replacing it, I should not consider it a
173 really conflicts
174diff --git a/libopkg/pkg_depends.h b/libopkg/pkg_depends.h
175index 5d1f074..b8072e2 100644
176--- a/libopkg/pkg_depends.h
177+++ b/libopkg/pkg_depends.h
178@@ -82,6 +82,7 @@ char *pkg_depend_str(pkg_t *pkg, int index);
179 void buildDependedUponBy(pkg_t * pkg, abstract_pkg_t * ab_pkg);
180 int version_constraints_satisfied(depend_t * depends, pkg_t * pkg);
181 int pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t *depends, char *** unresolved);
182+pkg_vec_t * pkg_hash_fetch_satisfied_dependencies(pkg_t * pkg);
183 pkg_vec_t * pkg_hash_fetch_conflicts(pkg_t * pkg);
184 int pkg_dependence_satisfiable(depend_t *depend);
185 int pkg_dependence_satisfied(depend_t *depend);
186--
1871.7.12
188