[pacman-dev] [PATCH] don't use old packages to satisfy dependencies
Don't use packages which are updated during the current transaction as dependency providers, when computing needed dependencies in resolvedeps. This could lead to new dependencies not being pulled in, in situations like: foo-1 provides bar baz depends on bar foo-2 does not provide bar anymore baz still depends on bar bar is not pulled in because foo-1 is used to satisfy the dependency Signed-off-by: Henning Garus <henning.garus@gmail.com> --- This should fix the "phonon bug". I am not entirely happy with this, because I more or less copy the local db (once more) on every call to resolvedeps. Alternatively one could create a joined list from remove and trans->add and give it to checkdeps as remove parameter. This would do what we want (exclude packages which will be upgraded from the list used to compute already satisfied dependencies in checkdeps), but it feels wrong. lib/libalpm/deps.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index 46699ac..85d7e24 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -600,6 +600,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg, { alpm_list_t *i, *j; alpm_list_t *targ; + alpm_list_t *untouched = NULL; alpm_list_t *deps = NULL; alpm_list_t *packages_copy; @@ -620,11 +621,19 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg, on that list */ *packages = alpm_list_add(*packages, pkg); + /* Create a list of local packages which can be used to satisfy deps. + * Don't use packages which are updated in the current transaction */ + for(i = _alpm_db_get_pkgcache(local); i; i = i->next) { + if(!alpm_list_find(handle->trans->add, i->data, _alpm_pkg_cmp)) { + untouched = alpm_list_add(untouched, i->data); + } + } + _alpm_log(PM_LOG_DEBUG, "started resolving dependencies\n"); for(i = alpm_list_last(*packages); i; i = i->next) { pmpkg_t *tpkg = i->data; targ = alpm_list_add(NULL, tpkg); - deps = alpm_checkdeps(_alpm_db_get_pkgcache(local), 0, remove, targ); + deps = alpm_checkdeps(untouched, 0, remove, targ); alpm_list_free(targ); for(j = deps; j; j = j->next) { pmdepmissing_t *miss = j->data; @@ -666,6 +675,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg, alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free); alpm_list_free(deps); } + alpm_list_free(untouched); alpm_list_free(packages_copy); _alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n"); return(0); -- 1.6.6.1
Idézet Henning Garus <henning.garus@googlemail.com>:
Don't use packages which are updated during the current transaction as dependency providers, when computing needed dependencies in resolvedeps. This could lead to new dependencies not being pulled in, in situations like:
foo-1 provides bar baz depends on bar
foo-2 does not provide bar anymore baz still depends on bar bar is not pulled in because foo-1 is used to satisfy the dependency
Signed-off-by: Henning Garus <henning.garus@gmail.com> ---
This should fix the "phonon bug". I am not entirely happy with this, because I more or less copy the local db (once more) on every call to resolvedeps. Alternatively one could create a joined list from remove and trans->add and give it to checkdeps as remove parameter. This would do what we want (exclude packages which will be upgraded from the list used to compute already satisfied dependencies in checkdeps), but it feels wrong.
I start with a sidenote: We have an alpm_list_diff function for simplifying the required list operation. I am not completely satisfied with this solution. It can happen that qt is not an explicit target, and it will be pulled *later*, which can break an earlier satisfied phonon dependency. However, a "nice" fix for this "pulled qt case" is much more difficult. That's why I prefer a somewhat uglier solution: Since this issue haven't showed up until recently, we can agree that this is a rare issue. That's why I would not touch (slow down) resolvedeps code, but I would insert _after_ resolvedeps a loop like this (pseudo-code): while(checkdeps(targets)) {resolve_deps(missing_deps)}; Pros: -In the normal (usual) cases we have zero slowdown. (Even in the problematic cases, it is unlikely that more than 2 checkdeps is needed.) -This can handle the pulled qt case. Contras: -Uglier code than yours. -If we reaches the "resolve_deps(missing_deps)" part, we must turn off remove_unresolvable. I haven't figured out every details yet (and I may overlook something here), but I will propose a patch for this at the weeked. Bye ------------------------------------------------------ SZTE Egyetemi Konyvtar - http://www.bibl.u-szeged.hu This message was sent using IMP: http://horde.org/imp/
participants (2)
-
Henning Garus
-
Nagy Gabor