if (!allow_all && !solv->dupmap_all && solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))
addduppackages(solv, s, &qs);
+#ifdef ENABLE_LINKED_PKGS
+ if (solv->instbuddy && solv->instbuddy[s - pool->solvables - solv->installed->start])
+ {
+ const char *name = pool_id2str(pool, s->name);
+ if (strncmp(name, "pattern:", 8) == 0 || strncmp(name, "application:", 12) == 0)
+ {
+ /* a linked pseudo package. As it is linked, we do not need an update rule */
+ /* nevertheless we set specialupdaters so we can update */
+ solver_addrule(solv, 0, 0);
+ if (!allow_all && qs.count)
+ {
+ if (p != -SYSTEMSOLVABLE)
+ queue_unshift(&qs, p);
+ if (!solv->specialupdaters)
+ solv->specialupdaters = solv_calloc(solv->installed->end - solv->installed->start, sizeof(Id));
+ solv->specialupdaters[s - pool->solvables - solv->installed->start] = pool_queuetowhatprovides(pool, &qs);
+ }
+ queue_free(&qs);
+ return;
+ }
+ }
+#endif
+
if (!allow_all && qs.count && solv->multiversion.size)
{
int i, j;
if (d && solv->installed && s->repo == solv->installed &&
(solv->updatemap_all || (solv->updatemap.size && MAPTST(&solv->updatemap, s - pool->solvables - solv->installed->start))))
{
- if (!solv->multiversionupdaters)
- solv->multiversionupdaters = solv_calloc(solv->installed->end - solv->installed->start, sizeof(Id));
- solv->multiversionupdaters[s - pool->solvables - solv->installed->start] = d;
+ if (!solv->specialupdaters)
+ solv->specialupdaters = solv_calloc(solv->installed->end - solv->installed->start, sizeof(Id));
+ solv->specialupdaters[s - pool->solvables - solv->installed->start] = d;
}
if (j == 0 && p == -SYSTEMSOLVABLE && solv->dupmap_all)
{
if (pool->solvables[p].repo == installed)
{
queue_push2(q, DISABLE_UPDATE, p);
+#ifdef ENABLE_LINKED_PKGS
if (solv->instbuddy && solv->instbuddy[p - installed->start] > 1)
queue_push2(q, DISABLE_UPDATE, solv->instbuddy[p - installed->start]);
+#endif
}
return;
default:
if (!r->p) /* identical to update rule? */
r = solv->rules + solv->updaterules + (p - installed->start);
}
- if (solv->multiversionupdaters && (d = solv->multiversionupdaters[p - installed->start]) != 0 && r == solv->rules + solv->updaterules + (p - installed->start))
+ if (solv->specialupdaters && (d = solv->specialupdaters[p - installed->start]) != 0 && r == solv->rules + solv->updaterules + (p - installed->start))
{
- /* need to check multiversionupdaters */
+ /* need to check specialupdaters */
if (r->p == p) /* be careful with the dup case */
queue_push(&q, p);
while ((p2 = pool->whatprovidesdata[d++]) != 0)
solv_free(solv->watches);
solv_free(solv->obsoletes);
solv_free(solv->obsoletes_data);
- solv_free(solv->multiversionupdaters);
+ solv_free(solv->specialupdaters);
solv_free(solv->choicerules_ref);
solv_free(solv->bestrules_pkg);
solv_free(solv->instbuddy);
for (pass = solv->updatemap.size ? 0 : 1; pass < 2; pass++)
{
int passlevel = level;
- Id *multiversionupdaters = solv->multiversion.size ? solv->multiversionupdaters : 0;
+ Id *specialupdaters = solv->specialupdaters;
if (pass == 1 && !solv->decisioncnt_keep)
solv->decisioncnt_keep = solv->decisionq.count;
/* start with installedpos, the position that gave us problems the last time */
if (s->repo != installed)
continue;
- if (solv->decisionmap[i] > 0 && (!multiversionupdaters || !multiversionupdaters[i - installed->start]))
+ if (solv->decisionmap[i] > 0 && (!specialupdaters || !specialupdaters[i - installed->start]))
continue; /* already decided */
if (!pass && solv->updatemap.size && !MAPTST(&solv->updatemap, i - installed->start))
continue; /* updates first */
rr -= solv->installed->end - solv->installed->start;
if (!rr->p) /* identical to update rule? */
rr = r;
- if (!rr->p)
+ if (!rr->p && (!specialupdaters || !specialupdaters[i - installed->start]))
continue; /* orpaned package */
/* check if we should update this package to the latest version
* noupdate is set for erase jobs, in that case we want to deinstall
- * the installed package and not replace it with a newer version */
+ * the installed package and not replace it with a newer version
+ * rr->p != i is for dup jobs where the installed package cannot be kept */
queue_empty(&dq);
- if (!MAPTST(&solv->noupdate, i - installed->start) && (solv->decisionmap[i] < 0 || solv->updatemap_all || (solv->updatemap.size && MAPTST(&solv->updatemap, i - installed->start)) || rr->p != i))
+ if (!MAPTST(&solv->noupdate, i - installed->start) && (solv->decisionmap[i] < 0 || solv->updatemap_all || (solv->updatemap.size && MAPTST(&solv->updatemap, i - installed->start)) || (rr->p && rr->p != i)))
{
- if (multiversionupdaters && (d = multiversionupdaters[i - installed->start]) != 0)
+ if (specialupdaters && (d = specialupdaters[i - installed->start]) != 0)
{
/* special multiversion handling, make sure best version is chosen */
if (rr->p == i && solv->decisionmap[i] >= 0)
queue_push(&dq, p);
if (dq.count && solv->update_targets && solv->update_targets->elements[i - installed->start])
prune_to_update_targets(solv, solv->update_targets->elements + solv->update_targets->elements[i - installed->start], &dq);
- if (dq.count)
+ if (dq.count && rr->p)
{
policy_filter_unwanted(solv, &dq, POLICY_MODE_CHOOSE);
p = dq.elements[0];
continue; /* start over */
}
- /* at this point we have a consistent system. now do the extras... */
-
- /* first decide leftover cleandeps packages */
+ /* decide leftover cleandeps packages */
if (solv->cleandepsmap.size && solv->installed)
{
for (p = solv->installed->start; p < solv->installed->end; p++)
continue;
}
+ /* at this point we have a consistent system. now do the extras... */
+
if (!solv->decisioncnt_weak)
solv->decisioncnt_weak = solv->decisionq.count;
if (doweak)
}
}
- if (solv->installed && solv->cleandepsmap.size)
+ /* one final pass to make sure we decided all installed packages */
+ if (solv->installed)
+ {
+ for (p = solv->installed->start; p < solv->installed->end; p++)
+ {
+ if (solv->decisionmap[p])
+ continue; /* already decided */
+ s = pool->solvables + p;
+ if (s->repo != solv->installed)
+ continue;
+ POOL_DEBUG(SOLV_DEBUG_SOLVER, "removing unwanted %s\n", pool_solvid2str(pool, p));
+ olevel = level;
+ level = setpropagatelearn(solv, level, -p, 0, 0);
+ if (level < olevel)
+ break;
+ }
+ }
+
+ if (solv->installed && solv->cleandepsmap.size)
{
if (cleandeps_check_mistakes(solv, level))
{
}
}
- if (solv->solution_callback)
+ if (solv->solution_callback)
{
solv->solution_callback(solv, solv->solution_callback_data);
if (solv->branches.count)
}
/* auto-minimization step */
- if (solv->branches.count)
+ if (solv->branches.count)
{
int l = 0, lasti = -1, lastl = -1;
Id why;
map_empty(&solv->suggestsmap);
solv->recommends_index = 0;
}
- solv->multiversionupdaters = solv_free(solv->multiversionupdaters);
+ solv->specialupdaters = solv_free(solv->specialupdaters);
/*
queue_push(&solv->orphaned, i);
if (!r->p)
{
- assert(solv->dupmap_all && !sr->p);
+ /* assert(solv->dupmap_all && !sr->p); */
continue;
}
if (!solver_rulecmp(solv, r, sr))