Commit 1074c4d3 authored by Timo Teräs's avatar Timo Teräs
Browse files

solver: have most inherited things per-package and clean ups

Required for provides support as package might be pulled in via
non-primary package name. This allows relatively easily to pass
through inherited flags via the provided names. ref #574.
parent f0f2029e
......@@ -86,38 +86,40 @@ struct apk_decision {
};
struct apk_package_state {
/* set on startup */
unsigned int topology_soft;
unsigned short allowed_pinning_maybe;
/* dynamic */
unsigned short allowed_pinning;
unsigned short inherited_pinning[APK_MAX_TAGS];
unsigned short inherited_upgrade;
unsigned short inherited_reinstall;
unsigned short conflicts;
unsigned char preference;
unsigned handle_install_if : 1;
unsigned locked : 1;
unsigned solver_flags_maybe : 4;
};
#define CHOSEN_NONE (struct apk_provider) { .pkg = NULL, .version = NULL }
struct apk_name_state {
/* dynamic */
struct list_head unsolved_list;
struct apk_name *name;
struct apk_provider chosen;
unsigned int last_touched_decision;
unsigned short requirers;
unsigned short install_ifs;
/* set on startup */
unsigned short preferred_pinning;
unsigned short maybe_pinning;
/* dynamic */
unsigned int last_touched_decision;
unsigned short allowed_pinning;
unsigned short inherited_pinning[APK_MAX_TAGS];
unsigned short inherited_upgrade;
unsigned short inherited_reinstall;
/* one time prepare/finish flags */
unsigned solver_flags_local : 4;
unsigned solver_flags_local_mask : 4;
unsigned solver_flags_maybe : 4;
unsigned solver_flags_inheritable : 4;
unsigned decision_counted : 1;
unsigned originally_installed : 1;
......@@ -173,6 +175,7 @@ static void addscore(struct apk_score *a, struct apk_score *b)
a->score += b->score;
ASSERT(a->conflicts >= orig.conflicts, "Conflict overflow");
ASSERT(a->non_preferred_actions >= orig.non_preferred_actions, "Preferred action overflow");
ASSERT(a->non_preferred_pinnings >= orig.non_preferred_pinnings, "Preferred pinning overflow");
ASSERT(a->preference >= orig.preference, "Preference overflow");
}
......@@ -182,6 +185,7 @@ static void subscore(struct apk_score *a, struct apk_score *b)
a->score -= b->score;
ASSERT(a->conflicts <= orig.conflicts, "Conflict underflow");
ASSERT(a->non_preferred_actions <= orig.non_preferred_actions, "Preferred action underflow");
ASSERT(a->non_preferred_pinnings <= orig.non_preferred_pinnings, "Preferred pinning overflow");
ASSERT(a->preference <= orig.preference, "Preference underflow");
}
#else
......@@ -231,6 +235,13 @@ static struct apk_package_state *pkg_to_ps(struct apk_package *pkg)
return (struct apk_package_state*) pkg->state_ptr;
}
static struct apk_package_state *pkg_to_ps_alloc(struct apk_package *pkg)
{
if (pkg->state_ptr == NULL)
pkg->state_ptr = calloc(1, sizeof(struct apk_package_state));
return pkg_to_ps(pkg);
}
static struct apk_name_state *name_to_ns(struct apk_name *name)
{
return (struct apk_name_state*) name->state_ptr;
......@@ -272,8 +283,8 @@ static inline int pkg_available(struct apk_database *db, struct apk_package *pkg
}
static void foreach_dependency_pkg(
struct apk_solver_state *ss, struct apk_dependency_array *depends,
void (*cb)(struct apk_solver_state *ss, struct apk_package *dependency))
struct apk_solver_state *ss, struct apk_package *parent_package, struct apk_dependency_array *depends,
void (*cb)(struct apk_solver_state *ss, struct apk_package *dependency, struct apk_package *parent_package))
{
int i, j;
......@@ -289,14 +300,14 @@ static void foreach_dependency_pkg(
if (!apk_dep_is_provided(dep, p0))
continue;
cb(ss, p0->pkg);
cb(ss, p0->pkg, parent_package);
}
}
}
static void foreach_rinstall_if_pkg(
struct apk_solver_state *ss, struct apk_package *pkg,
void (*cb)(struct apk_solver_state *ss, struct apk_package *rinstall_if))
void (*cb)(struct apk_solver_state *ss, struct apk_package *rinstall_if, struct apk_package *parent_pkg))
{
struct apk_name *name = pkg->name;
int i, j, k;
......@@ -321,7 +332,7 @@ static void foreach_rinstall_if_pkg(
continue;
/* pkg depends (via install_if) on pkg0 */
cb(ss, p0->pkg);
cb(ss, p0->pkg, pkg);
}
}
}
......@@ -362,17 +373,17 @@ static int get_topology_score(
/* available preferred */
if ((pkg->repos == 0) && ns->has_available_pkgs)
score.non_preferred_actions++;
} else if (ns->inherited_reinstall ||
} else if (ps->inherited_reinstall ||
(((ns->solver_flags_local|ss->solver_flags) & APK_SOLVERF_REINSTALL))) {
/* reinstall requested, but not available */
if (!pkg_available(ss->db, pkg))
score.non_preferred_actions++;
} else if (ns->inherited_upgrade ||
} else if (ps->inherited_upgrade ||
((ns->solver_flags_local|ss->solver_flags) & APK_SOLVERF_UPGRADE)) {
/* upgrading - score is just locked here */
} else if ((ns->inherited_upgrade == 0) &&
} else if ((ps->inherited_upgrade == 0) &&
((ns->solver_flags_local|ss->solver_flags) & APK_SOLVERF_UPGRADE) == 0 &&
((ns->solver_flags_maybe & APK_SOLVERF_UPGRADE) == 0 || (ps->locked))) {
((ps->solver_flags_maybe & APK_SOLVERF_UPGRADE) == 0 || (ps->locked))) {
/* not upgrading: it is not preferred to change package */
if (pkg->ipkg == NULL && ns->originally_installed)
score.non_preferred_actions++;
......@@ -389,8 +400,8 @@ static int get_topology_score(
if (!(repos & preferred_repos))
score.non_preferred_pinnings++;
if (ps->locked || (ns->allowed_pinning | ns->maybe_pinning) == ns->allowed_pinning) {
allowed_pinning = ns->allowed_pinning | preferred_pinning | APK_DEFAULT_PINNING_MASK;
if (ps->locked || (ps->allowed_pinning | ps->allowed_pinning_maybe) == ps->allowed_pinning) {
allowed_pinning = ps->allowed_pinning | preferred_pinning | APK_DEFAULT_PINNING_MASK;
allowed_repos = get_pinning_mask_repos(ss->db, allowed_pinning);
if (!(repos & allowed_repos)) {
if (sticky_installed)
......@@ -493,24 +504,24 @@ static void count_name(struct apk_solver_state *ss, struct apk_name *name)
}
}
static void sort_hard_dependencies(struct apk_solver_state *ss, struct apk_package *pkg)
static void sort_hard_dependencies(struct apk_solver_state *ss,
struct apk_package *pkg,
struct apk_package *parent_pkg)
{
struct apk_package_state *ps;
int i;
if (pkg->state_ptr == NULL)
pkg->state_ptr = calloc(1, sizeof(struct apk_package_state));
ps = pkg_to_ps(pkg);
ps = pkg_to_ps_alloc(pkg);
if (ps->topology_soft)
return;
pkg->topology_hard = -1;
ps->topology_soft = -1;
calculate_pkg_preference(pkg);
/* Consider hard dependencies only */
foreach_dependency_pkg(ss, pkg->depends, sort_hard_dependencies);
foreach_dependency_pkg(ss, pkg->install_if, sort_hard_dependencies);
foreach_dependency_pkg(ss, pkg, pkg->depends, sort_hard_dependencies);
foreach_dependency_pkg(ss, pkg, pkg->install_if, sort_hard_dependencies);
ss->max_decisions++;
count_name(ss, pkg->name);
......@@ -522,20 +533,28 @@ static void sort_hard_dependencies(struct apk_solver_state *ss, struct apk_packa
PKG_VER_PRINTF(pkg), pkg->topology_hard);
}
static void sort_soft_dependencies(struct apk_solver_state *ss, struct apk_package *pkg)
static void sort_soft_dependencies(struct apk_solver_state *ss,
struct apk_package *pkg,
struct apk_package *parent_pkg)
{
struct apk_package_state *ps;
struct apk_package_state *parent_ps;
sort_hard_dependencies(ss, pkg);
sort_hard_dependencies(ss, pkg, parent_pkg);
ps = pkg_to_ps(pkg);
if (ps->topology_soft != pkg->topology_hard)
return;
ps->topology_soft = -1;
/* Update state */
parent_ps = pkg_to_ps(parent_pkg);
ps->allowed_pinning_maybe |= parent_ps->allowed_pinning_maybe;
ps->solver_flags_maybe |= parent_ps->solver_flags_maybe;
/* Soft reverse dependencies aka. install_if */
foreach_rinstall_if_pkg(ss, pkg, sort_hard_dependencies);
foreach_dependency_pkg(ss, pkg->depends, sort_soft_dependencies);
foreach_dependency_pkg(ss, pkg, pkg->depends, sort_soft_dependencies);
/* Assign a topology sorting order */
ps->topology_soft = ++ss->num_topology_positions;
......@@ -543,54 +562,33 @@ static void sort_soft_dependencies(struct apk_solver_state *ss, struct apk_packa
PKG_VER_PRINTF(pkg), ps->topology_soft);
}
static void recalculate_maybe(struct apk_solver_state *ss, struct apk_name *name,
unsigned short flags, unsigned short pinning)
static void sort_name(struct apk_solver_state *ss, struct apk_name *name)
{
struct apk_name_state *ns = name_to_ns_alloc(name);
int propagate = FALSE;
int i, j;
if ((ns->maybe_pinning & pinning) != pinning) {
ns->maybe_pinning |= pinning;
propagate = TRUE;
}
if ((ns->solver_flags_maybe & flags) != flags) {
ns->solver_flags_maybe |= flags;
propagate = TRUE;
}
if (!propagate)
return;
count_name(ss, name);
for (i = 0; i < name->providers->num; i++) {
struct apk_package *pkg = name->providers->item[i].pkg;
struct apk_package_state *ps = pkg_to_ps_alloc(pkg);
unsigned short allowed_pinning;
for (j = 0; j < pkg->depends->num; j++) {
struct apk_dependency *dep = &pkg->depends->item[j];
struct apk_name *name0 = dep->name;
recalculate_maybe(ss, name0, flags, pinning);
ps->allowed_pinning |= ns->preferred_pinning;
ps->allowed_pinning_maybe |= ns->preferred_pinning;
allowed_pinning = ps->allowed_pinning;
for (j = 0; allowed_pinning; j++) {
if (!(allowed_pinning & BIT(j)))
continue;
allowed_pinning &= ~BIT(j);
ps->inherited_pinning[j]++;
}
}
for (i = 0; i < name->rinstall_if->num; i++) {
struct apk_name *name0 = name->rinstall_if->item[i];
recalculate_maybe(ss, name0, flags, pinning);
sort_soft_dependencies(ss, name->providers->item[i].pkg, pkg);
}
}
static void sort_name(struct apk_solver_state *ss, struct apk_name *name)
{
struct apk_name_state *ns = name_to_ns_alloc(name);
int i;
for (i = 0; i < name->providers->num; i++)
sort_soft_dependencies(ss, name->providers->item[i].pkg);
count_name(ss, name);
recalculate_maybe(ss, name,
ns->solver_flags_local & ns->solver_flags_local_mask,
ns->maybe_pinning);
}
static void foreach_dependency(struct apk_solver_state *ss, struct apk_dependency_array *deps,
void (*func)(struct apk_solver_state *ss, struct apk_dependency *dep))
{
......@@ -668,80 +666,94 @@ static void demote_name(struct apk_solver_state *ss, struct apk_name *name)
}
}
static void inherit_name_state(struct apk_database *db, struct apk_name *to, struct apk_name *from)
static int inherit_package_state(struct apk_database *db, struct apk_package *to, struct apk_package *from)
{
struct apk_name_state *tns = name_to_ns(to);
struct apk_name_state *fns = name_to_ns(from);
int i;
struct apk_package_state *tps = pkg_to_ps(to);
struct apk_name_state *fns = name_to_ns(from->name);
struct apk_package_state *fps = pkg_to_ps(from);
int i, changed = 0;
if ((fns->solver_flags_local & fns->solver_flags_local_mask & APK_SOLVERF_REINSTALL) ||
fns->inherited_reinstall)
tns->inherited_reinstall++;
if ((fns->solver_flags_inheritable & APK_SOLVERF_REINSTALL) ||
fps->inherited_reinstall) {
tps->inherited_reinstall++;
changed = 1;
}
if ((fns->solver_flags_local & fns->solver_flags_local_mask & APK_SOLVERF_UPGRADE) ||
fns->inherited_upgrade)
tns->inherited_upgrade++;
if ((fns->solver_flags_inheritable & APK_SOLVERF_UPGRADE) ||
fps->inherited_upgrade) {
tps->inherited_upgrade++;
changed = 1;
}
if (fns->allowed_pinning) {
for (i = 0; i < db->num_repo_tags; i++) {
if (!(fns->allowed_pinning & BIT(i)))
if (fps->allowed_pinning) {
unsigned short allowed_pinning = fps->allowed_pinning;
for (i = 0; allowed_pinning && i < db->num_repo_tags; i++) {
if (!(allowed_pinning & BIT(i)))
continue;
if (tns->inherited_pinning[i]++ == 0)
tns->allowed_pinning |= BIT(i);
allowed_pinning &= ~BIT(i);
if (tps->inherited_pinning[i]++ == 0) {
tps->allowed_pinning |= BIT(i);
changed = 1;
}
}
}
return changed;
}
static void uninherit_name_state(struct apk_database *db, struct apk_name *to, struct apk_name *from)
static void uninherit_package_state(struct apk_database *db, struct apk_package *to, struct apk_package *from)
{
struct apk_name_state *tns = name_to_ns(to);
struct apk_name_state *fns = name_to_ns(from);
struct apk_package_state *tps = pkg_to_ps(to);
struct apk_name_state *fns = name_to_ns(from->name);
struct apk_package_state *fps = pkg_to_ps(from);
int i;
if ((fns->solver_flags_local & fns->solver_flags_local_mask & APK_SOLVERF_REINSTALL) ||
fns->inherited_reinstall)
tns->inherited_reinstall--;
if ((fns->solver_flags_inheritable & APK_SOLVERF_REINSTALL) ||
fps->inherited_reinstall)
tps->inherited_reinstall--;
if ((fns->solver_flags_local & fns->solver_flags_local_mask & APK_SOLVERF_UPGRADE) ||
fns->inherited_upgrade)
tns->inherited_upgrade--;
if ((fns->solver_flags_inheritable & APK_SOLVERF_UPGRADE) ||
fps->inherited_upgrade)
tps->inherited_upgrade--;
if (fns->allowed_pinning) {
for (i = 0; i < db->num_repo_tags; i++) {
if (!(fns->allowed_pinning & BIT(i)))
if (fps->allowed_pinning) {
unsigned short allowed_pinning = fps->allowed_pinning;
for (i = 0; allowed_pinning && i < db->num_repo_tags; i++) {
if (!(allowed_pinning & BIT(i)))
continue;
if (--tns->inherited_pinning[i] == 0)
tns->allowed_pinning &= ~BIT(i);
allowed_pinning &= ~BIT(i);
if (--tps->inherited_pinning[i] == 0)
tps->allowed_pinning &= ~BIT(i);
}
}
}
static void trigger_install_if(struct apk_solver_state *ss,
struct apk_package *pkg)
struct apk_package *pkg,
struct apk_package *parent_pkg)
{
if (install_if_missing(ss, pkg) == 0) {
struct apk_name *name0 = decision_to_name(&ss->decisions[ss->num_decisions]);
struct apk_name_state *ns = name_to_ns(pkg->name);
dbg_printf("trigger_install_if: " PKG_VER_FMT " triggered\n",
PKG_VER_PRINTF(pkg));
ns->install_ifs++;
inherit_name_state(ss->db, pkg->name, name0);
inherit_package_state(ss->db, pkg, parent_pkg);
promote_name(ss, pkg->name);
}
}
static void untrigger_install_if(struct apk_solver_state *ss,
struct apk_package *pkg)
struct apk_package *pkg,
struct apk_package *parent_pkg)
{
if (install_if_missing(ss, pkg) != 1) {
struct apk_name *name0 = decision_to_name(&ss->decisions[ss->num_decisions]);
struct apk_name_state *ns = name_to_ns(pkg->name);
dbg_printf("untrigger_install_if: " PKG_VER_FMT " no longer triggered\n",
PKG_VER_PRINTF(pkg));
ns->install_ifs--;
uninherit_name_state(ss->db, pkg->name, name0);
uninherit_package_state(ss->db, pkg, parent_pkg);
demote_name(ss, pkg->name);
}
}
......@@ -983,14 +995,16 @@ static int next_branch(struct apk_solver_state *ss)
static void apply_constraint(struct apk_solver_state *ss, struct apk_dependency *dep)
{
struct apk_name *name = dep->name;
struct apk_name_state *ns = name_to_ns(name);
int i, strength;
struct apk_package *requirer_pkg = NULL;
struct apk_name *name = dep->name, *requirer_name = NULL;
struct apk_name_state *ns = name_to_ns(name), *requirer_ns = NULL;
int i, strength, changed = 0;
if (ss->num_decisions > 0) {
struct apk_name *name0 = decision_to_name(&ss->decisions[ss->num_decisions]);
struct apk_name_state *ns0 = name_to_ns(name0);
strength = ns0->requirers ?: 1;
requirer_name = decision_to_name(&ss->decisions[ss->num_decisions]);
requirer_pkg = decision_to_pkg(&ss->decisions[ss->num_decisions]);
requirer_ns = name_to_ns(requirer_name);
strength = requirer_ns->requirers ?: 1;
} else {
strength = 1;
}
......@@ -1006,29 +1020,13 @@ static void apply_constraint(struct apk_solver_state *ss, struct apk_dependency
ss->score.conflicts += strength;
return;
}
if (name->providers->num == 0) {
if (!dep->optional)
ss->score.conflicts += strength;
return;
}
if (dep->repository_tag) {
dbg_printf("%s: adding pinnings %d\n",
dep->name->name, dep->repository_tag);
ns->preferred_pinning = BIT(dep->repository_tag);
ns->allowed_pinning |= BIT(dep->repository_tag);
ns->inherited_pinning[dep->repository_tag]++;
recalculate_maybe(ss, name, 0, ns->allowed_pinning);
}
if (ss->num_decisions > 0) {
struct apk_name *name0 = decision_to_name(&ss->decisions[ss->num_decisions]);
dbg_printf("%s: inheriting flags and pinning from %s\n",
name->name, name0->name);
inherit_name_state(ss->db, name, name0);
ns->last_touched_decision = ss->num_decisions;
}
for (i = 0; i < name->providers->num; i++) {
struct apk_provider *p0 = &name->providers->item[i];
struct apk_package *pkg0 = p0->pkg;
......@@ -1043,9 +1041,17 @@ static void apply_constraint(struct apk_solver_state *ss, struct apk_dependency
dbg_printf(PKG_VER_FMT ": conflicts++ -> %d\n",
PKG_VER_PRINTF(pkg0),
ps0->conflicts);
changed |= 1;
} else if (requirer_pkg != NULL) {
dbg_printf("%s: inheriting flags and pinning from %s\n",
name->name, name0->name);
changed |= inherit_package_state(ss->db, pkg0, requirer_pkg);
}
}
if (changed)
ns->last_touched_decision = ss->num_decisions;
if (!dep->optional)
ns->requirers += strength;
......@@ -1054,14 +1060,16 @@ static void apply_constraint(struct apk_solver_state *ss, struct apk_dependency
static void undo_constraint(struct apk_solver_state *ss, struct apk_dependency *dep)
{
struct apk_name *name = dep->name;
struct apk_name_state *ns = name_to_ns(name);
struct apk_name *name = dep->name, *requirer_name = NULL;
struct apk_name_state *ns = name_to_ns(name), *requirer_ns = NULL;
struct apk_package *requirer_pkg = NULL;
int i, strength;
if (ss->num_decisions > 0) {
struct apk_name *name0 = decision_to_name(&ss->decisions[ss->num_decisions]);
struct apk_name_state *ns0 = name_to_ns(name0);
strength = ns0->requirers ?: 1;
requirer_name = decision_to_name(&ss->decisions[ss->num_decisions]);
requirer_pkg = decision_to_pkg(&ss->decisions[ss->num_decisions]);
requirer_ns = name_to_ns(requirer_name);
strength = requirer_ns->requirers ?: 1;
} else {
strength = 1;
}
......@@ -1084,19 +1092,6 @@ static void undo_constraint(struct apk_solver_state *ss, struct apk_dependency *
return;
}
if (ss->num_decisions > 0) {
struct apk_name *name0 = decision_to_name(&ss->decisions[ss->num_decisions]);
dbg_printf("%s: uninheriting flags and pinning from %s\n",
name->name, name0->name);
uninherit_name_state(ss->db, name, name0);
/* note: for perfection, we should revert here to the
* *previous* value, but that'd require keeping track
* of it which would require dynamic memory allocations.
* in practice this is good enough. */
if (ns->last_touched_decision > ss->num_decisions)
ns->last_touched_decision = ss->num_decisions;
}
for (i = 0; i < name->providers->num; i++) {
struct apk_provider *p0 = &name->providers->item[i];
struct apk_package *pkg0 = p0->pkg;
......@@ -1111,9 +1106,20 @@ static void undo_constraint(struct apk_solver_state *ss, struct apk_dependency *
dbg_printf(PKG_VER_FMT ": conflicts-- -> %d\n",
PKG_VER_PRINTF(pkg0),
ps0->conflicts);
} else if (requirer_pkg != NULL) {
dbg_printf("%s: uninheriting flags and pinning from %s\n",
name->name, name0->name);
uninherit_package_state(ss->db, pkg0, requirer_pkg);
}
}
/* note: for perfection, we should revert here to the
* *previous* value, but that'd require keeping track
* of it which would require dynamic memory allocations.
* in practice this is good enough. */
if (ns->last_touched_decision > ss->num_decisions)
ns->last_touched_decision = ss->num_decisions;
if (!dep->optional)
ns->requirers -= strength;
......@@ -1193,6 +1199,7 @@ static int expand_branch(struct apk_solver_state *ss)
struct apk_name *name;
struct apk_name_state *ns;
struct apk_package *pkg0 = NULL;
struct apk_package_state *ps0;
unsigned int r, topology0 = 0;
unsigned short allowed_pinning, preferred_pinning;
unsigned int allowed_repos;
......@@ -1222,6 +1229,7 @@ static int expand_branch(struct apk_solver_state *ss)
/* someone needs to provide this name -- find next eligible
* provider candidate */
ps0 = pkg_to_ps(pkg0);
name = pkg0->name;
ns = name_to_ns(name);
......@@ -1241,7 +1249,7 @@ static int expand_branch(struct apk_solver_state *ss)
SCORE_PRINTF(&ss->best_score));
preferred_pinning = ns->preferred_pinning ?: APK_DEFAULT_PINNING_MASK;
allowed_pinning = ns->allowed_pinning | preferred_pinning | APK_DEFAULT_PINNING_MASK;
allowed_pinning = ps0->allowed_pinning | preferred_pinning | APK_DEFAULT_PINNING_MASK;
allowed_repos = get_pinning_mask_repos(ss->db, allowed_pinning);
if ((pkg0->repos != 0) && !(pkg0->repos & allowed_repos)) {
......@@ -1295,6 +1303,7 @@ static void record_solution(struct apk_solver_state *ss)
for (i = ss->num_decisions; i > 0; i--) {
struct apk_decision *d = &ss->decisions[i];
struct apk_package *pkg = decision_to_pkg(d);
struct apk_package_state *ps;
unsigned short pinning;
unsigned int repos;
......@@ -1314,13 +1323,14 @@ static void record_solution(struct apk_solver_state *ss)
continue;
ns = name_to_ns(pkg->name);
pinning = ns->allowed_pinning | ns->preferred_pinning | APK_DEFAULT_PINNING_MASK;
ps = pkg_to_ps(pkg);
pinning = ps->allowed_pinning | ns->preferred_pinning | APK_DEFAULT_PINNING_MASK;
repos = pkg->repos | (pkg->ipkg ? db->repo_tags[pkg->ipkg->repository_tag].allowed_repos : 0);
ASSERT(n < ss->assigned_names, "Name assignment overflow\n");
ss->best_solution->item[n++] = (struct apk_solution_entry){
.pkg = pkg,
.reinstall = ns->inherited_reinstall ||
.reinstall = ps->inherited_reinstall ||
((ns->solver_flags_local | ss->solver_flags) & APK_SOLVERF_REINSTALL),
.repository_tag = get_tag(db, pinning, repos),
};
......@@ -1453,7 +1463,7 @@ void apk_solver_set_name_flags(struct apk_name *name,
{
struct apk_name_state *ns = name_to_ns_alloc(name);
ns->solver_flags_local = solver_flags;
ns->solver_flags_local_mask = solver_flags_inheritable;
ns->solver_flags_inheritable = solver_flags & solver_flags_inheritable;
}
static void apk_solver_free(struct apk_database *db)
......@@ -1481,19 +1491,21 @@ int apk_solver_solve(struct apk_database *db,
list_init(&ss->unsolved_list_head);
for (i = 0; i < world->num; i++) {
sort_name(ss, world->item[i].name);
name_to_ns(world->item[i].name)->in_world_dependency = 1;
struct apk_dependency *dep = &world->item[i];
struct apk_name *name = dep->name;
struct apk_name_state *ns = name_to_ns_alloc(name);
ns->in_world_dependency = 1;
dbg_printf("%s: adding pinnings %d\n", name->name, dep->repository_tag);
ns->preferred_pinning = BIT(dep->repository_tag);
sort_name(ss, name);
}
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
sort_name(ss, ipkg->pkg->name);