solver: fix pinning+cache to work
Mistakenly allowed masked out package to be installed if it was in cache.cute-signatures
parent
7e18398781
commit
3f27da2ade
|
@ -93,8 +93,6 @@ struct apk_installed_package {
|
||||||
unsigned broken_script : 1;
|
unsigned broken_script : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define APK_PKG_UNINSTALLABLE ((char*) -1)
|
|
||||||
|
|
||||||
struct apk_package {
|
struct apk_package {
|
||||||
apk_hash_node hash_node;
|
apk_hash_node hash_node;
|
||||||
union {
|
union {
|
||||||
|
@ -117,6 +115,7 @@ struct apk_package {
|
||||||
size_t installed_size, size;
|
size_t installed_size, size;
|
||||||
time_t build_time;
|
time_t build_time;
|
||||||
unsigned marked : 1;
|
unsigned marked : 1;
|
||||||
|
unsigned uninstallable : 1;
|
||||||
unsigned repos : APK_MAX_REPOS;
|
unsigned repos : APK_MAX_REPOS;
|
||||||
struct apk_checksum csum;
|
struct apk_checksum csum;
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,9 +50,10 @@ struct apk_solver_package_state {
|
||||||
unsigned solver_flags : 4;
|
unsigned solver_flags : 4;
|
||||||
unsigned solver_flags_inheritable : 4;
|
unsigned solver_flags_inheritable : 4;
|
||||||
unsigned seen : 1;
|
unsigned seen : 1;
|
||||||
|
unsigned pkg_available : 1;
|
||||||
|
unsigned pkg_selectable : 1;
|
||||||
unsigned tag_ok : 1;
|
unsigned tag_ok : 1;
|
||||||
unsigned tag_preferred : 1;
|
unsigned tag_preferred : 1;
|
||||||
unsigned available : 1;
|
|
||||||
unsigned dependencies_used : 1;
|
unsigned dependencies_used : 1;
|
||||||
unsigned dependencies_merged : 1;
|
unsigned dependencies_merged : 1;
|
||||||
unsigned in_changeset : 1;
|
unsigned in_changeset : 1;
|
||||||
|
|
|
@ -1452,8 +1452,6 @@ static void apk_db_setup_repositories(struct apk_database *db)
|
||||||
db->local_repos |= BIT(APK_REPOSITORY_CACHED);
|
db->local_repos |= BIT(APK_REPOSITORY_CACHED);
|
||||||
db->available_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;
|
db->num_repo_tags = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -802,7 +802,7 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
|
||||||
default:
|
default:
|
||||||
/* lower case index entries are safe to be ignored */
|
/* lower case index entries are safe to be ignored */
|
||||||
if (!islower(field)) {
|
if (!islower(field)) {
|
||||||
pkg->filename = APK_PKG_UNINSTALLABLE;
|
pkg->uninstallable = 1;
|
||||||
db->compat_notinstallable = 1;
|
db->compat_notinstallable = 1;
|
||||||
}
|
}
|
||||||
db->compat_newfeatures = 1;
|
db->compat_newfeatures = 1;
|
||||||
|
@ -914,8 +914,7 @@ int apk_pkg_read(struct apk_database *db, const char *file,
|
||||||
tar->close(tar);
|
tar->close(tar);
|
||||||
if (r < 0 && r != -ECANCELED)
|
if (r < 0 && r != -ECANCELED)
|
||||||
goto err;
|
goto err;
|
||||||
if (ctx.pkg->name == NULL ||
|
if (ctx.pkg->name == NULL || ctx.pkg->uninstallable) {
|
||||||
ctx.pkg->filename == APK_PKG_UNINSTALLABLE) {
|
|
||||||
r = -ENOTSUP;
|
r = -ENOTSUP;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
43
src/solver.c
43
src/solver.c
|
@ -164,7 +164,7 @@ static void disqualify_package(struct apk_solver_state *ss, struct apk_package *
|
||||||
struct apk_dependency *p;
|
struct apk_dependency *p;
|
||||||
|
|
||||||
dbg_printf("disqualify_package: " PKG_VER_FMT " (%s)\n", PKG_VER_PRINTF(pkg), reason);
|
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);
|
reevaluate_reverse_deps(ss, pkg->name);
|
||||||
foreach_array_item(p, pkg->provides)
|
foreach_array_item(p, pkg->provides)
|
||||||
reevaluate_reverse_deps(ss, p->name);
|
reevaluate_reverse_deps(ss, p->name);
|
||||||
|
@ -183,7 +183,7 @@ static int dependency_satisfiable(struct apk_solver_state *ss, struct apk_depend
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
foreach_array_item(p, name->providers)
|
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 TRUE;
|
||||||
|
|
||||||
return FALSE;
|
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;
|
struct apk_package *pkg = p->pkg;
|
||||||
if (pkg->ss.seen)
|
if (pkg->ss.seen)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pkg->ss.seen = 1;
|
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_allowed = APK_DEFAULT_PINNING_MASK;
|
||||||
pkg->ss.pinning_preferred = 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);
|
repos = get_pkg_repos(db, pkg);
|
||||||
pkg->ss.tag_ok = !!(repos & ss->default_repos);
|
pkg->ss.tag_preferred =
|
||||||
pkg->ss.tag_preferred = !!(repos & ss->default_repos);
|
(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) {
|
foreach_array_item(dep, pkg->depends) {
|
||||||
discover_name(ss, dep->name);
|
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);
|
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_VER_PRINTF(pkg),
|
||||||
pkg->ss.tag_ok,
|
pkg->ss.tag_ok,
|
||||||
pkg->ss.tag_preferred,
|
pkg->ss.tag_preferred,
|
||||||
pkg->ss.max_dep_chain,
|
pkg->ss.max_dep_chain,
|
||||||
pkg->ss.available);
|
pkg->ss.pkg_selectable);
|
||||||
}
|
}
|
||||||
foreach_array_item(pname0, name->rinstall_if)
|
foreach_array_item(pname0, name->rinstall_if)
|
||||||
discover_name(ss, *pname0);
|
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->name->name, BLOB_PRINTF(*p0->version), is_provided);
|
||||||
|
|
||||||
pkg0->ss.conflicts += !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");
|
disqualify_package(ss, pkg0, "conflicting dependency");
|
||||||
|
|
||||||
if (is_provided) {
|
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_provider *p;
|
||||||
struct apk_dependency *d;
|
struct apk_dependency *d;
|
||||||
|
|
||||||
|
if (name == must_provide)
|
||||||
|
return;
|
||||||
|
|
||||||
dbg_printf("%s must provide %s\n", name->name, must_provide->name);
|
dbg_printf("%s must provide %s\n", name->name, must_provide->name);
|
||||||
|
|
||||||
foreach_array_item(p, name->providers) {
|
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 = p->pkg;
|
||||||
pkg->ss.dependencies_merged = 0;
|
pkg->ss.dependencies_merged = 0;
|
||||||
if (reevaluate_deps) {
|
if (reevaluate_deps) {
|
||||||
if (!pkg->ss.available)
|
if (!pkg->ss.pkg_selectable)
|
||||||
continue;
|
continue;
|
||||||
foreach_array_item(dep, pkg->depends) {
|
foreach_array_item(dep, pkg->depends) {
|
||||||
if (!dependency_satisfiable(ss, dep)) {
|
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;
|
continue;
|
||||||
|
|
||||||
if (reevaluate_iif) {
|
if (reevaluate_iif) {
|
||||||
|
@ -469,13 +480,13 @@ static int compare_providers(struct apk_solver_state *ss,
|
||||||
|
|
||||||
/* Prefer available */
|
/* Prefer available */
|
||||||
if (solver_flags & (APK_SOLVERF_AVAILABLE | APK_SOLVERF_REINSTALL)) {
|
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)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Prefer without errors */
|
/* 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)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -501,7 +512,7 @@ static int compare_providers(struct apk_solver_state *ss,
|
||||||
|
|
||||||
/* Prefer available */
|
/* Prefer available */
|
||||||
if (solver_flags & (APK_SOLVERF_AVAILABLE | APK_SOLVERF_REINSTALL)) {
|
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)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -617,11 +628,11 @@ static void select_package(struct apk_solver_state *ss, struct apk_name *name)
|
||||||
|
|
||||||
pkg = chosen.pkg;
|
pkg = chosen.pkg;
|
||||||
if (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 */
|
/* Selecting broken or unallowed package */
|
||||||
mark_error(ss, pkg);
|
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));
|
assign_name(ss, pkg->name, APK_PROVIDER_FROM_PACKAGE(pkg));
|
||||||
foreach_array_item(d, pkg->provides)
|
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)
|
foreach_array_item(d, pkg->depends)
|
||||||
cset_gen_dep(ss, pkg, d);
|
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);
|
record_change(ss, opkg, pkg);
|
||||||
|
|
||||||
foreach_array_item(pname, pkg->name->rinstall_if)
|
foreach_array_item(pname, pkg->name->rinstall_if)
|
||||||
|
|
Loading…
Reference in New Issue