summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2013-06-20 14:08:16 +0300
committerTimo Teräs <timo.teras@iki.fi>2013-06-20 14:08:16 +0300
commit3f27da2adec968b1d8f83149b2b321e1050b4acb (patch)
treefe66fec31a9eb8a6541075ef3f8e307d2e99d957
parent7e18398781b056f858ef60200e24b0f8ab394cfe (diff)
solver: fix pinning+cache to work
Mistakenly allowed masked out package to be installed if it was in cache.
-rw-r--r--src/apk_package.h3
-rw-r--r--src/apk_solver_data.h3
-rw-r--r--src/database.c2
-rw-r--r--src/package.c5
-rw-r--r--src/solver.c43
5 files changed, 32 insertions, 24 deletions
diff --git a/src/apk_package.h b/src/apk_package.h
index f743c3e..8945cd8 100644
--- a/src/apk_package.h
+++ b/src/apk_package.h
@@ -93,8 +93,6 @@ struct apk_installed_package {
unsigned broken_script : 1;
};
-#define APK_PKG_UNINSTALLABLE ((char*) -1)
-
struct apk_package {
apk_hash_node hash_node;
union {
@@ -117,6 +115,7 @@ struct apk_package {
size_t installed_size, size;
time_t build_time;
unsigned marked : 1;
+ unsigned uninstallable : 1;
unsigned repos : APK_MAX_REPOS;
struct apk_checksum csum;
};
diff --git a/src/apk_solver_data.h b/src/apk_solver_data.h
index 7853af5..0cff7b4 100644
--- a/src/apk_solver_data.h
+++ b/src/apk_solver_data.h
@@ -50,9 +50,10 @@ struct apk_solver_package_state {
unsigned solver_flags : 4;
unsigned solver_flags_inheritable : 4;
unsigned seen : 1;
+ unsigned pkg_available : 1;
+ unsigned pkg_selectable : 1;
unsigned tag_ok : 1;
unsigned tag_preferred : 1;
- unsigned available : 1;
unsigned dependencies_used : 1;
unsigned dependencies_merged : 1;
unsigned in_changeset : 1;
diff --git a/src/database.c b/src/database.c
index ba13620..919335c 100644
--- a/src/database.c
+++ b/src/database.c
@@ -1452,8 +1452,6 @@ static void apk_db_setup_repositories(struct apk_database *db)
db->local_repos |= BIT(APK_REPOSITORY_CACHED);
db->available_repos |= BIT(APK_REPOSITORY_CACHED);
- /* Get first repository tag (the NULL tag) */
- db->repo_tags[APK_DEFAULT_REPOSITORY_TAG].allowed_repos |= BIT(APK_REPOSITORY_CACHED);
db->num_repo_tags = 1;
}
diff --git a/src/package.c b/src/package.c
index 6723de6..e211b63 100644
--- a/src/package.c
+++ b/src/package.c
@@ -802,7 +802,7 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
default:
/* lower case index entries are safe to be ignored */
if (!islower(field)) {
- pkg->filename = APK_PKG_UNINSTALLABLE;
+ pkg->uninstallable = 1;
db->compat_notinstallable = 1;
}
db->compat_newfeatures = 1;
@@ -914,8 +914,7 @@ int apk_pkg_read(struct apk_database *db, const char *file,
tar->close(tar);
if (r < 0 && r != -ECANCELED)
goto err;
- if (ctx.pkg->name == NULL ||
- ctx.pkg->filename == APK_PKG_UNINSTALLABLE) {
+ if (ctx.pkg->name == NULL || ctx.pkg->uninstallable) {
r = -ENOTSUP;
goto err;
}
diff --git a/src/solver.c b/src/solver.c
index 889cffd..e84a09a 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -164,7 +164,7 @@ static void disqualify_package(struct apk_solver_state *ss, struct apk_package *
struct apk_dependency *p;
dbg_printf("disqualify_package: " PKG_VER_FMT " (%s)\n", PKG_VER_PRINTF(pkg), reason);
- pkg->ss.available = 0;
+ pkg->ss.pkg_selectable = 0;
reevaluate_reverse_deps(ss, pkg->name);
foreach_array_item(p, pkg->provides)
reevaluate_reverse_deps(ss, p->name);
@@ -183,7 +183,7 @@ static int dependency_satisfiable(struct apk_solver_state *ss, struct apk_depend
return TRUE;
foreach_array_item(p, name->providers)
- if (p->pkg->ss.available && apk_dep_is_provided(dep, p))
+ if (p->pkg->ss.pkg_selectable && apk_dep_is_provided(dep, p))
return TRUE;
return FALSE;
@@ -205,14 +205,22 @@ static void discover_name(struct apk_solver_state *ss, struct apk_name *name)
struct apk_package *pkg = p->pkg;
if (pkg->ss.seen)
continue;
+
pkg->ss.seen = 1;
- pkg->ss.available = pkg->ipkg || (pkg->repos & db->available_repos);
pkg->ss.pinning_allowed = APK_DEFAULT_PINNING_MASK;
pkg->ss.pinning_preferred = APK_DEFAULT_PINNING_MASK;
+ pkg->ss.pkg_available =
+ (pkg->filename != NULL) ||
+ (pkg->installed_size == 0) ||
+ (pkg->repos & db->available_repos);
+ pkg->ss.pkg_selectable = pkg->ss.pkg_available || pkg->ipkg;
repos = get_pkg_repos(db, pkg);
- pkg->ss.tag_ok = !!(repos & ss->default_repos);
- pkg->ss.tag_preferred = !!(repos & ss->default_repos);
+ pkg->ss.tag_preferred =
+ (pkg->filename != NULL) ||
+ (pkg->installed_size == 0) ||
+ !!(repos & ss->default_repos);
+ pkg->ss.tag_ok = pkg->ss.tag_preferred || pkg->ipkg;
foreach_array_item(dep, pkg->depends) {
discover_name(ss, dep->name);
@@ -221,12 +229,12 @@ static void discover_name(struct apk_solver_state *ss, struct apk_name *name)
}
name->ss.max_dep_chain = max(name->ss.max_dep_chain, pkg->ss.max_dep_chain);
- dbg_printf("discover " PKG_VER_FMT ": tag_ok=%d, tag_pref=%d max_dep_chain=%d available=%d\n",
+ dbg_printf("discover " PKG_VER_FMT ": tag_ok=%d, tag_pref=%d max_dep_chain=%d selectable=%d\n",
PKG_VER_PRINTF(pkg),
pkg->ss.tag_ok,
pkg->ss.tag_preferred,
pkg->ss.max_dep_chain,
- pkg->ss.available);
+ pkg->ss.pkg_selectable);
}
foreach_array_item(pname0, name->rinstall_if)
discover_name(ss, *pname0);
@@ -277,7 +285,7 @@ static void apply_constraint(struct apk_solver_state *ss, struct apk_package *pp
pkg0->name->name, BLOB_PRINTF(*p0->version), is_provided);
pkg0->ss.conflicts += !is_provided;
- if (unlikely(pkg0->ss.available && pkg0->ss.conflicts))
+ if (unlikely(pkg0->ss.pkg_selectable && pkg0->ss.conflicts))
disqualify_package(ss, pkg0, "conflicting dependency");
if (is_provided) {
@@ -298,6 +306,9 @@ static void exclude_non_providers(struct apk_solver_state *ss, struct apk_name *
struct apk_provider *p;
struct apk_dependency *d;
+ if (name == must_provide)
+ return;
+
dbg_printf("%s must provide %s\n", name->name, must_provide->name);
foreach_array_item(p, name->providers) {
@@ -350,7 +361,7 @@ static void reconsider_name(struct apk_solver_state *ss, struct apk_name *name)
pkg = p->pkg;
pkg->ss.dependencies_merged = 0;
if (reevaluate_deps) {
- if (!pkg->ss.available)
+ if (!pkg->ss.pkg_selectable)
continue;
foreach_array_item(dep, pkg->depends) {
if (!dependency_satisfiable(ss, dep)) {
@@ -359,7 +370,7 @@ static void reconsider_name(struct apk_solver_state *ss, struct apk_name *name)
}
}
}
- if (!pkg->ss.available)
+ if (!pkg->ss.pkg_selectable)
continue;
if (reevaluate_iif) {
@@ -469,13 +480,13 @@ static int compare_providers(struct apk_solver_state *ss,
/* Prefer available */
if (solver_flags & (APK_SOLVERF_AVAILABLE | APK_SOLVERF_REINSTALL)) {
- r = !!(pkgA->repos & db->available_repos) - !!(pkgB->repos & db->available_repos);
+ r = (int)pkgA->ss.pkg_available - (int)pkgB->ss.pkg_available;
if (r)
return r;
}
} else {
/* Prefer without errors */
- r = (int)pkgA->ss.available - (int)pkgB->ss.available;
+ r = (int)pkgA->ss.pkg_selectable - (int)pkgB->ss.pkg_selectable;
if (r)
return r;
@@ -501,7 +512,7 @@ static int compare_providers(struct apk_solver_state *ss,
/* Prefer available */
if (solver_flags & (APK_SOLVERF_AVAILABLE | APK_SOLVERF_REINSTALL)) {
- r = !!(pkgA->repos & db->available_repos) - !!(pkgB->repos & db->available_repos);
+ r = (int)pkgA->ss.pkg_available - (int)pkgB->ss.pkg_available;
if (r)
return r;
}
@@ -617,11 +628,11 @@ static void select_package(struct apk_solver_state *ss, struct apk_name *name)
pkg = chosen.pkg;
if (pkg) {
- if (!pkg->ss.available || !pkg->ss.tag_ok) {
+ if (!pkg->ss.pkg_selectable || !pkg->ss.tag_ok) {
/* Selecting broken or unallowed package */
mark_error(ss, pkg);
}
- dbg_printf("selecting: " PKG_VER_FMT ", available: %d\n", PKG_VER_PRINTF(pkg), pkg->ss.available);
+ dbg_printf("selecting: " PKG_VER_FMT ", available: %d\n", PKG_VER_PRINTF(pkg), pkg->ss.pkg_selectable);
assign_name(ss, pkg->name, APK_PROVIDER_FROM_PACKAGE(pkg));
foreach_array_item(d, pkg->provides)
@@ -754,7 +765,7 @@ static void cset_gen_name_change(struct apk_solver_state *ss, struct apk_name *n
foreach_array_item(d, pkg->depends)
cset_gen_dep(ss, pkg, d);
- dbg_printf("Selecting: "PKG_VER_FMT"%s\n", PKG_VER_PRINTF(pkg), pkg->ss.available ? "" : " [NOT AVAILABLE]");
+ dbg_printf("Selecting: "PKG_VER_FMT"%s\n", PKG_VER_PRINTF(pkg), pkg->ss.pkg_selectable ? "" : " [NOT SELECTABLE]");
record_change(ss, opkg, pkg);
foreach_array_item(pname, pkg->name->rinstall_if)