summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2019-09-10 15:37:46 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2019-09-10 15:37:46 +0900
commit0e46e80434781d1acbc4f5716827bf8688450a30 (patch)
treebd75ab938e88eb1e111c3bcb099d7a6793bd4364
parente679b515eddb3dd340fb25620de0160211f40fdc (diff)
downloadlibsolv-upstream/0.6.36.tar.gz
libsolv-upstream/0.6.36.tar.bz2
libsolv-upstream/0.6.36.zip
Imported Upstream version 0.6.36upstream/0.6.36
-rw-r--r--NEWS12
-rw-r--r--VERSION.cmake2
-rw-r--r--doc/rpmdb2solv.txt3
-rw-r--r--examples/solv/fastestmirror.c6
-rw-r--r--examples/solv/repoinfo_system_rpm.c6
-rw-r--r--ext/repo_autopattern.c4
-rw-r--r--ext/repo_repomdxml.c2
-rw-r--r--ext/repo_rpmdb.c18
-rw-r--r--ext/testcase.c34
-rw-r--r--package/libsolv.changes18
-rw-r--r--package/libsolv.spec.in2
-rw-r--r--src/cleandeps.c2
-rw-r--r--src/policy.c14
-rw-r--r--src/pool.c3
-rw-r--r--src/pool.h1
-rw-r--r--src/problems.c17
-rw-r--r--src/rules.c32
-rw-r--r--src/selection.c2
-rw-r--r--src/solver.c109
-rw-r--r--src/strpool.c6
-rw-r--r--test/testcases/allowuninstall/conflict.t14
-rw-r--r--test/testcases/allowuninstall/forcebest.t19
-rw-r--r--test/testcases/cleandeps/cleandeps_up3.t23
-rw-r--r--tools/repo2solv.c7
-rw-r--r--tools/rpmdb2solv.c17
-rw-r--r--tools/susetags2solv.c2
26 files changed, 318 insertions, 57 deletions
diff --git a/NEWS b/NEWS
index abb211f..5b1a2af 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,18 @@
This file contains the major changes between
libsolv versions:
+Version 0.6.36
+- bug fixes:
+ * do not autouninstall packages because of forcebest updates
+ * fixed a couple of null pointer derefs and potential memory
+ leaks
+ * no longer disable infarch rules when they don't conflict with
+ the job
+ * fix cleandeps updates not updating all packages
+ * fix SOLVER_FLAG_FOCUS_BEST updateing packages without reason
+ * be more correct with multiversion packages that obsolete their
+ own name
+
Version 0.6.35
- new configuration options:
* ENABLE_ZSTD_COMPRESSION: support zstd compression
diff --git a/VERSION.cmake b/VERSION.cmake
index 991c920..d866276 100644
--- a/VERSION.cmake
+++ b/VERSION.cmake
@@ -49,5 +49,5 @@ SET(LIBSOLVEXT_SOVERSION "0")
SET(LIBSOLV_MAJOR "0")
SET(LIBSOLV_MINOR "6")
-SET(LIBSOLV_PATCH "35")
+SET(LIBSOLV_PATCH "36")
diff --git a/doc/rpmdb2solv.txt b/doc/rpmdb2solv.txt
index ad8314f..128e179 100644
--- a/doc/rpmdb2solv.txt
+++ b/doc/rpmdb2solv.txt
@@ -47,6 +47,9 @@ standard directory is */etc/products.d*.
Do not read any packages from the rpm database. This is useful
together with *-p* to only convert SUSE products.
+*-C*::
+Include the package changelog in the generated solv file.
+
*-X*::
Autoexpand SUSE pattern and product provides into packages.
diff --git a/examples/solv/fastestmirror.c b/examples/solv/fastestmirror.c
index d2ebd97..0ee4e73 100644
--- a/examples/solv/fastestmirror.c
+++ b/examples/solv/fastestmirror.c
@@ -68,7 +68,11 @@ findfastest(char **urls, int nurls)
socks[i] = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (socks[i] >= 0)
{
- fcntl(socks[i], F_SETFL, O_NONBLOCK);
+ if (fcntl(socks[i], F_SETFL, O_NONBLOCK) == -1)
+ {
+ close(socks[i]);
+ socks[i] = -1;
+ }
if (connect(socks[i], result->ai_addr, result->ai_addrlen) == -1)
{
if (errno != EINPROGRESS)
diff --git a/examples/solv/repoinfo_system_rpm.c b/examples/solv/repoinfo_system_rpm.c
index 4926ecd..b556afc 100644
--- a/examples/solv/repoinfo_system_rpm.c
+++ b/examples/solv/repoinfo_system_rpm.c
@@ -17,6 +17,9 @@
#if defined(ENABLE_APPDATA)
#include "repo_appdata.h"
#endif
+#ifdef SUSE
+#include "repo_autopattern.h"
+#endif
#include "transaction.h"
#include "repoinfo.h"
@@ -118,6 +121,9 @@ read_installed_rpm(struct repoinfo *cinfo)
if (ofp)
fclose(ofp);
repo_internalize(repo);
+#ifdef SUSE
+ repo_add_autopattern(repo, 0);
+#endif
writecachedrepo(cinfo, 0, 0);
return 1;
}
diff --git a/ext/repo_autopattern.c b/ext/repo_autopattern.c
index f6e1004..7cef78c 100644
--- a/ext/repo_autopattern.c
+++ b/ext/repo_autopattern.c
@@ -103,8 +103,8 @@ repo_add_autopattern(Repo *repo, int flags)
if (repo == pool->installed)
flags |= ADD_NO_AUTOPRODUCTS; /* no auto products for installed repos */
- pattern_id = pool_str2id(pool, "pattern()", 9);
- product_id = pool_str2id(pool, "product()", 9);
+ pattern_id = pool_str2id(pool, "pattern()", 1);
+ product_id = pool_str2id(pool, "product()", 1);
FOR_REPO_SOLVABLES(repo, p, s)
{
const char *n = pool_id2str(pool, s->name);
diff --git a/ext/repo_repomdxml.c b/ext/repo_repomdxml.c
index 760d481..b2a5b8d 100644
--- a/ext/repo_repomdxml.c
+++ b/ext/repo_repomdxml.c
@@ -181,7 +181,7 @@ startElement(struct solv_xmlparser *xmlp, int state, const char *name, const cha
while (value)
{
char *p = strchr(value, ',');
- if (*p)
+ if (p)
*p++ = 0;
if (*value)
repodata_add_poolstr_array(pd->data, SOLVID_META, REPOSITORY_UPDATES, value);
diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c
index 75bb678..daf22e9 100644
--- a/ext/repo_rpmdb.c
+++ b/ext/repo_rpmdb.c
@@ -1000,7 +1000,7 @@ addchangelog(Repodata *data, Id handle, RpmHead *rpmhead)
char **cn;
char **cx;
uint32_t *ct;
- int i, cnc, cxc, ctc;
+ int i, cnc, cxc, ctc = 0;
Queue hq;
ct = headint32array(rpmhead, TAG_CHANGELOGTIME, &ctc);
@@ -1939,6 +1939,8 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
if (fread(lead, 96 + 16, 1, fp) != 1 || getu32(lead) != 0xedabeedb)
{
pool_error(pool, -1, "%s: not a rpm", rpm);
+ solv_chksum_free(leadsigchksumh, 0);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
@@ -1951,12 +1953,16 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
if (lead[78] != 0 || lead[79] != 5)
{
pool_error(pool, -1, "%s: not a rpm v5 header", rpm);
+ solv_chksum_free(leadsigchksumh, 0);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
if (getu32(lead + 96) != 0x8eade801)
{
pool_error(pool, -1, "%s: bad signature header", rpm);
+ solv_chksum_free(leadsigchksumh, 0);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
@@ -1965,6 +1971,8 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
if (sigcnt >= MAX_SIG_CNT || sigdsize >= MAX_SIG_DSIZE)
{
pool_error(pool, -1, "%s: bad signature header", rpm);
+ solv_chksum_free(leadsigchksumh, 0);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
@@ -1975,6 +1983,8 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
{
if (!headfromfp(&state, rpm, fp, lead + 96, sigcnt, sigdsize, sigpad, chksumh, leadsigchksumh))
{
+ solv_chksum_free(leadsigchksumh, 0);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
@@ -2014,6 +2024,8 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
if (fread(lead, l, 1, fp) != 1)
{
pool_error(pool, -1, "%s: unexpected EOF", rpm);
+ solv_chksum_free(leadsigchksumh, 0);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
@@ -2034,6 +2046,7 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
if (fread(lead, 16, 1, fp) != 1)
{
pool_error(pool, -1, "%s: unexpected EOF", rpm);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
@@ -2042,6 +2055,7 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
if (getu32(lead) != 0x8eade801)
{
pool_error(pool, -1, "%s: bad header", rpm);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
@@ -2050,6 +2064,7 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
if (sigcnt >= MAX_HDR_CNT || sigdsize >= MAX_HDR_DSIZE)
{
pool_error(pool, -1, "%s: bad header", rpm);
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
@@ -2057,6 +2072,7 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
if (!headfromfp(&state, rpm, fp, lead, sigcnt, sigdsize, 0, chksumh, 0))
{
+ solv_chksum_free(chksumh, 0);
fclose(fp);
return 0;
}
diff --git a/ext/testcase.c b/ext/testcase.c
index aa72a8d..0bac26b 100644
--- a/ext/testcase.c
+++ b/ext/testcase.c
@@ -571,6 +571,8 @@ testcase_str2dep_complex(Pool *pool, const char **sp, int relop)
Id flags, id, id2, namespaceid = 0;
struct oplist *op;
+ if (!s)
+ return 0;
while (*s == ' ' || *s == '\t')
s++;
if (!strncmp(s, "namespace:", 10))
@@ -1068,7 +1070,7 @@ testcase_str2job(Pool *pool, const char *str, Id *whatp)
Queue q;
job |= SOLVER_SOLVABLE_ONE_OF;
queue_init(&q);
- if (npieces > 3 && strcmp(pieces[2], "nothing") != 0)
+ if (npieces > 2 && strcmp(pieces[2], "nothing") != 0)
{
for (i = 2; i < npieces; i++)
{
@@ -2013,7 +2015,7 @@ testcase_solverresult(Solver *solv, int resultflags)
if ((rtype & SOLVER_RULE_TYPEMASK) == SOLVER_RULE_JOB)
{
const char *js = testcase_job2str(pool, rq.elements[i + 2], rq.elements[i + 3]);
- char *s = pool_tmpjoin(pool, altprefix, num, " job ");
+ char *s = pool_tmpjoin(pool, altprefix, num, "job ");
s = pool_tmpappend(pool, s, js, 0);
strqueue_push(&sq, s);
}
@@ -2023,6 +2025,13 @@ testcase_solverresult(Solver *solv, int resultflags)
s = pool_tmpappend(pool, s, " requires ", testcase_dep2str(pool, rq.elements[i + 3]));
strqueue_push(&sq, s);
}
+ else if (rtype == SOLVER_RULE_UPDATE || rtype == SOLVER_RULE_FEATURE)
+ {
+ const char *js = testcase_solvid2str(pool, rq.elements[i + 1]);
+ char *s = pool_tmpjoin(pool, altprefix, num, "update ");
+ s = pool_tmpappend(pool, s, js, 0);
+ strqueue_push(&sq, s);
+ }
}
}
for (i = 0; i < q.count; i++)
@@ -2170,7 +2179,7 @@ testcase_write_mangled(Solver *solv, const char *dir, int resultflags, const cha
Id lowscore;
FILE *fp;
Strqueue sq;
- char *cmd, *out;
+ char *cmd, *out, *result;
const char *s;
if (!testcasename)
@@ -2305,7 +2314,6 @@ testcase_write_mangled(Solver *solv, const char *dir, int resultflags, const cha
if ((resultflags & ~TESTCASE_RESULT_REUSE_SOLVER) != 0)
{
- char *result;
cmd = 0;
for (i = 0; resultflags2str[i].str; i++)
if ((resultflags & resultflags2str[i].flag) != 0)
@@ -2316,7 +2324,6 @@ testcase_write_mangled(Solver *solv, const char *dir, int resultflags, const cha
result = testcase_solverresult(solv, resultflags);
if (!strcmp(resultname, "<inline>"))
{
- int i;
Strqueue rsq;
strqueue_init(&rsq);
strqueue_split(&rsq, result);
@@ -2348,6 +2355,7 @@ testcase_write_mangled(Solver *solv, const char *dir, int resultflags, const cha
if (fclose(fp))
{
pool_error(solv->pool, 0, "testcase_write: write error");
+ solv_free(result);
strqueue_free(&sq);
return 0;
}
@@ -2355,29 +2363,29 @@ testcase_write_mangled(Solver *solv, const char *dir, int resultflags, const cha
solv_free(result);
}
- cmd = strqueue_join(&sq);
+ result = strqueue_join(&sq);
+ strqueue_free(&sq);
out = pool_tmpjoin(pool, dir, "/", testcasename);
if (!(fp = fopen(out, "w")))
{
pool_error(solv->pool, 0, "testcase_write: could not open '%s' for writing", out);
- strqueue_free(&sq);
+ solv_free(result);
return 0;
}
- if (*cmd && fwrite(cmd, strlen(cmd), 1, fp) != 1)
+ if (*result && fwrite(result, strlen(result), 1, fp) != 1)
{
pool_error(solv->pool, 0, "testcase_write: write error");
- strqueue_free(&sq);
+ solv_free(result);
fclose(fp);
return 0;
}
if (fclose(fp))
{
pool_error(solv->pool, 0, "testcase_write: write error");
- strqueue_free(&sq);
+ solv_free(result);
return 0;
}
- solv_free(cmd);
- strqueue_free(&sq);
+ solv_free(result);
return 1;
}
@@ -2766,7 +2774,7 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res
{
int i = strlen(pieces[1]);
s = strchr(pieces[1], '(');
- if (!s && pieces[1][i - 1] != ')')
+ if (!s || pieces[1][i - 1] != ')')
{
pool_error(pool, 0, "testcase_read: bad namespace '%s'", pieces[1]);
}
diff --git a/package/libsolv.changes b/package/libsolv.changes
index 430e479..dcdbabd 100644
--- a/package/libsolv.changes
+++ b/package/libsolv.changes
@@ -1,4 +1,22 @@
-------------------------------------------------------------------
+Thu Jun 27 16:36:00 CEST 2019 - mls@suse.de
+
+- make cleandeps jobs on patterns work [bnc#1137977]
+- fix SOLVER_FLAG_FOCUS_BEST updateing packages without reason
+- be more correct with multiversion packages that obsolete their
+ own name [bnc#1127155]
+- always prefer to stay with the same package name if there are
+ multiple alternatives [bnc#1131823]
+- fix cleandeps updates not updating all packages
+- fixed a couple of null pointer derefs
+ [bnc#1120629] [bnc#1120630] [bnc#1120631]
+ [CVE-2018-20532] [CVE-2018-20533] [CVE-2018-20534]
+- no longer disable infarch rules when they don't conflict with
+ the job
+- do not autouninstall packages because of forcebest updates
+- bump version to 0.6.36
+
+-------------------------------------------------------------------
Thu Aug 9 17:09:41 CEST 2018 - mls@suse.de
- refactor arch handling
diff --git a/package/libsolv.spec.in b/package/libsolv.spec.in
index ca649e8..63d8f38 100644
--- a/package/libsolv.spec.in
+++ b/package/libsolv.spec.in
@@ -24,7 +24,7 @@
%bcond_with bz2
%bcond_with xz
%endif
-%if 0%{?sle_version} >= 150000 || 0%{?suse_version} >= 1500
+%if 0%{?is_opensuse} && ( 0%{?sle_version} >= 150000 || 0%{?suse_version} >= 1500 )
%bcond_without zstd
%else
%bcond_with zstd
diff --git a/src/cleandeps.c b/src/cleandeps.c
index 1da28f6..ef9a528 100644
--- a/src/cleandeps.c
+++ b/src/cleandeps.c
@@ -837,7 +837,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
if (MAPTST(&solv->multiversion, p))
break;
if (p)
- continue;
+ continue; /* found a multiversion package that will not obsolate anything */
}
om.size = 0;
diff --git a/src/policy.c b/src/policy.c
index a38dea0..e1682f2 100644
--- a/src/policy.c
+++ b/src/policy.c
@@ -866,6 +866,8 @@ move_installed_to_front(Pool *pool, Queue *plist)
Solvable *s;
Id p, pp;
+ if (!pool->installed)
+ return;
for (i = j = 0; i < plist->count; i++)
{
s = pool->solvables + plist->elements[i];
@@ -924,9 +926,9 @@ prune_to_best_version(Pool *pool, Queue *plist)
{
s = pool->solvables + plist->elements[i];
- POOL_DEBUG(SOLV_DEBUG_POLICY, "- %s[%s]\n",
- pool_solvable2str(pool, s),
- (pool->installed && s->repo == pool->installed) ? "installed" : "not installed");
+ POOL_DEBUG(SOLV_DEBUG_POLICY, "- %s [%d]%s\n",
+ pool_solvable2str(pool, s), plist->elements[i],
+ (pool->installed && s->repo == pool->installed) ? "I" : "");
if (!best) /* if no best yet, the current is best */
{
@@ -961,8 +963,6 @@ prune_to_best_version(Pool *pool, Queue *plist)
else
prune_obsoleted(pool, plist);
}
- if (plist->count > 1 && pool->installed)
- move_installed_to_front(pool, plist);
}
@@ -1236,7 +1236,7 @@ urpm_reorder(Solver *solv, Queue *plist)
{
char kn[256];
Id p, pp, knid;
- memcpy(kn, "kernel", 8);
+ memcpy(kn, "kernel", 7);
memcpy(kn + 6, flavor, release - flavor + 1);
memcpy(kn + 6 + (release - flavor) + 1, sn, flavor - sn);
strcpy(kn + 6 + (release + 1 - sn), release);
@@ -1343,6 +1343,7 @@ policy_filter_unwanted(Solver *solv, Queue *plist, int mode)
#endif
dislike_old_versions(pool, plist);
sort_by_common_dep(pool, plist);
+ move_installed_to_front(pool, plist);
if (solv->urpmreorder)
urpm_reorder(solv, plist);
prefer_suggested(solv, plist);
@@ -1364,6 +1365,7 @@ pool_best_solvables(Pool *pool, Queue *plist, int flags)
{
dislike_old_versions(pool, plist);
sort_by_common_dep(pool, plist);
+ move_installed_to_front(pool, plist);
}
}
diff --git a/src/pool.c b/src/pool.c
index 60cc0f4..279359a 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -1505,6 +1505,7 @@ pool_debug(Pool *pool, int type, const char *format, ...)
vprintf(format, args);
else
vfprintf(stderr, format, args);
+ va_end(args);
return;
}
vsnprintf(buf, sizeof(buf), format, args);
@@ -1566,7 +1567,7 @@ pool_setdebuglevel(Pool *pool, int level)
if (level > 2)
mask |= SOLV_DEBUG_PROPAGATE;
if (level > 3)
- mask |= SOLV_DEBUG_RULE_CREATION;
+ mask |= SOLV_DEBUG_RULE_CREATION | SOLV_DEBUG_WATCHES;
mask |= pool->debugmask & SOLV_DEBUG_TO_STDERR; /* keep bit */
pool->debugmask = mask;
}
diff --git a/src/pool.h b/src/pool.h
index e6d1700..40e3777 100644
--- a/src/pool.h
+++ b/src/pool.h
@@ -188,6 +188,7 @@ struct _Pool {
#define SOLV_DEBUG_JOB (1<<11)
#define SOLV_DEBUG_SOLVER (1<<12)
#define SOLV_DEBUG_TRANSACTION (1<<13)
+#define SOLV_DEBUG_WATCHES (1<<14)
#define SOLV_DEBUG_TO_STDERR (1<<30)
diff --git a/src/problems.c b/src/problems.c
index df751c4..2b5cefd 100644
--- a/src/problems.c
+++ b/src/problems.c
@@ -247,8 +247,23 @@ solver_autouninstall(Solver *solv, int start)
if (v >= solv->updaterules && v < solv->updaterules_end)
{
Rule *r;
+ Id p = solv->installed->start + (v - solv->updaterules);
if (m && !MAPTST(m, v - solv->updaterules))
continue;
+ if (pool->considered && !MAPTST(pool->considered, p))
+ continue; /* do not uninstalled disabled packages */
+ if (solv->bestrules_pkg && solv->bestrules_end > solv->bestrules)
+ {
+ int j;
+ for (j = start + 1; j < solv->problems.count - 1; j++)
+ {
+ Id vv = solv->problems.elements[j];
+ if (vv >= solv->bestrules && vv < solv->bestrules_end && solv->bestrules_pkg[vv - solv->bestrules] == p)
+ break;
+ }
+ if (j < solv->problems.count - 1)
+ continue; /* best rule involved, do not uninstall */
+ }
/* check if identical to feature rule, we don't like that (except for orphans) */
r = solv->rules + solv->featurerules + (v - solv->updaterules);
if (!r->p)
@@ -260,7 +275,7 @@ solver_autouninstall(Solver *solv, int start)
if (solv->keep_orphans)
{
r = solv->rules + v;
- if (!r->d && !r->w2 && r->p == (solv->installed->start + (v - solv->updaterules)))
+ if (!r->d && !r->w2 && r->p == p)
{
lastfeature = v;
lastupdate = 0;
diff --git a/src/rules.c b/src/rules.c
index df32341..5901145 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -1328,6 +1328,31 @@ solver_addfeaturerule(Solver *solv, Solvable *s)
}
}
+/* check if multiversion solvable s2 has an obsoletes for installed solvable s */
+static int
+is_multiversion_obsoleteed(Pool *pool, Solvable *s, Solvable *s2)
+{
+ Id *wp, obs, *obsp;
+
+ if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2))
+ return 0;
+ obsp = s2->repo->idarraydata + s2->obsoletes;
+ if (!pool->obsoleteusesprovides)
+ {
+ while ((obs = *obsp++) != 0)
+ if (pool_match_nevr(pool, s, obs))
+ return 1;
+ }
+ else
+ {
+ while ((obs = *obsp++) != 0)
+ for (wp = pool_whatprovides_ptr(pool, obs); *wp; wp++)
+ if (pool->solvables + *wp == s)
+ return 1;
+ }
+ return 0;
+}
+
/*-------------------------------------------------------------------
*
* add rule for update
@@ -1389,9 +1414,8 @@ solver_addupdaterule(Solver *solv, Solvable *s)
if (MAPTST(&solv->multiversion, qs.elements[i]))
{
Solvable *ps = pool->solvables + qs.elements[i];
- /* if keepexplicitobsoletes is set and the name is different,
- * we assume that there is an obsoletes. XXX: not 100% correct */
- if (solv->keepexplicitobsoletes && ps->name != s->name)
+ /* check if there is an explicit obsoletes */
+ if (solv->keepexplicitobsoletes && ps->obsoletes && is_multiversion_obsoleteed(pool, s, ps))
{
qs.elements[j++] = qs.elements[i];
continue;
@@ -2175,7 +2199,7 @@ jobtodisablelist(Solver *solv, Id how, Id what, Queue *q)
if (pool->solvables[p].repo == installed)
return;
if (solv->multiversion.size && MAPTST(&solv->multiversion, p) && !solv->keepexplicitobsoletes)
- return;
+ return; /* will not obsolete anything, so just return */
}
omap.size = 0;
qstart = q->count;
diff --git a/src/selection.c b/src/selection.c
index d44c482..0b36ea8 100644
--- a/src/selection.c
+++ b/src/selection.c
@@ -1468,7 +1468,7 @@ selection_make_matchdeps_common_limited(Pool *pool, Queue *selection, const char
revr = pool_str2id(pool, r, 1);
ret |= SELECTION_REL;
}
- if ((flags & SELECTION_GLOB) != 0 && !strpbrk(rname, "[*?") != 0)
+ if ((flags & SELECTION_GLOB) != 0 && strpbrk(rname, "[*?") == 0)
flags &= ~SELECTION_GLOB;
if ((flags & SELECTION_GLOB) == 0 && (flags & SELECTION_NOCASE) == 0 && (flags & SELECTION_MATCH_DEPSTR) == 0)
diff --git a/src/solver.c b/src/solver.c
index 6405f4a..102d814 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -431,7 +431,7 @@ propagate(Solver *solv, int level)
Id *decisionmap = solv->decisionmap;
Id *watches = solv->watches + pool->nsolvables; /* place ptr in middle */
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate -----\n");
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate level %d -----\n", level);
/* foreach non-propagated decision */
while (solv->propagate_index < solv->decisionq.count)
@@ -444,7 +444,7 @@ propagate(Solver *solv, int level)
IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE)
{
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "propagate for decision %d level %d\n", -pkg, level);
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "propagate decision %d:", -pkg);
solver_printruleelement(solv, SOLV_DEBUG_PROPAGATE, 0, -pkg);
}
@@ -462,10 +462,10 @@ propagate(Solver *solv, int level)
continue;
}
- IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE)
+ IF_POOLDEBUG (SOLV_DEBUG_WATCHES)
{
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE," watch triggered ");
- solver_printrule(solv, SOLV_DEBUG_PROPAGATE, r);
+ POOL_DEBUG(SOLV_DEBUG_WATCHES, " watch triggered ");
+ solver_printrule(solv, SOLV_DEBUG_WATCHES, r);
}
/*
@@ -532,12 +532,12 @@ propagate(Solver *solv, int level)
* if we found some p that is UNDEF or TRUE, move
* watch to it
*/
- IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE)
+ IF_POOLDEBUG (SOLV_DEBUG_WATCHES)
{
if (p > 0)
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, " -> move w%d to %s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, p));
+ POOL_DEBUG(SOLV_DEBUG_WATCHES, " -> move w%d to %s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, p));
else
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, " -> move w%d to !%s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, -p));
+ POOL_DEBUG(SOLV_DEBUG_WATCHES, " -> move w%d to !%s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, -p));
}
*rp = *next_rp;
@@ -593,7 +593,7 @@ propagate(Solver *solv, int level)
} /* while we have non-decided decisions */
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate end-----\n");
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate end -----\n");
return 0; /* all is well */
}
@@ -1790,6 +1790,69 @@ resolve_installed(Solver *solv, int level, int disablerules, Queue *dq)
return level;
}
+/* one or more installed cleandeps packages in dq that are to be updated */
+/* we need to emulate the code in resolve_installed */
+static void
+do_cleandeps_update_filter(Solver *solv, Queue *dq)
+{
+ Pool *pool = solv->pool;
+ Repo *installed = solv->installed;
+ Id *specialupdaters = solv->specialupdaters;
+ Id p, p2, pp, d;
+ Queue q;
+ int i, j, k;
+
+ queue_init(&q);
+ for (i = 0; i < dq->count; i++)
+ {
+ Id p = dq->elements[i];
+ if (p < 0)
+ p = -p;
+ if (pool->solvables[p].repo != installed || !MAPTST(&solv->cleandepsmap, p - installed->start))
+ continue;
+ queue_empty(&q);
+ /* find updaters */
+ if (specialupdaters && (d = specialupdaters[p - installed->start]) != 0)
+ {
+ while ((p2 = pool->whatprovidesdata[d++]) != 0)
+ if (solv->decisionmap[p2] >= 0)
+ queue_push(&q, p2);
+ }
+ else
+ {
+ Rule *r = solv->rules + solv->updaterules + (p - installed->start);
+ if (r->p)
+ {
+ FOR_RULELITERALS(p2, pp, r)
+ if (solv->decisionmap[p2] >= 0)
+ queue_push(&q, p2);
+ }
+ }
+ if (q.count && solv->update_targets && solv->update_targets->elements[p - installed->start])
+ prune_to_update_targets(solv, solv->update_targets->elements + solv->update_targets->elements[p - installed->start], &q);
+ /* mark all elements in dq that are in the updaters list */
+ dq->elements[i] = -p;
+ for (j = 0; j < dq->count; j++)
+ {
+ p = dq->elements[j];
+ if (p < 0)
+ continue;
+ for (k = 0; k < q.count; k++)
+ if (q.elements[k] == p)
+ {
+ dq->elements[j] = -p;
+ break;
+ }
+ }
+ }
+ /* now prune to marked elements */
+ for (i = j = 0; i < dq->count; i++)
+ if ((p = dq->elements[i]) < 0)
+ dq->elements[j++] = -p;
+ dq->count = j;
+ queue_free(&q);
+}
+
static int
resolve_dependencies(Solver *solv, int level, int disablerules, Queue *dq)
{
@@ -1817,6 +1880,8 @@ resolve_dependencies(Solver *solv, int level, int disablerules, Queue *dq)
}
if (i == solv->nrules)
i = 1;
+ if (solv->focus_best && solv->do_extra_reordering && i >= solv->featurerules)
+ continue;
r = solv->rules + i;
if (r->d < 0) /* ignore disabled rules */
continue;
@@ -1885,15 +1950,25 @@ resolve_dependencies(Solver *solv, int level, int disablerules, Queue *dq)
/* prune to cleandeps packages */
if (solv->cleandepsmap.size && solv->installed)
{
+ int cleandeps_update = 0;
Repo *installed = solv->installed;
for (j = 0; j < dq->count; j++)
if (pool->solvables[dq->elements[j]].repo == installed && MAPTST(&solv->cleandepsmap, dq->elements[j] - installed->start))
- break;
+ {
+ if (solv->updatemap_all || (solv->updatemap.size && MAPTST(&solv->updatemap, dq->elements[j] - installed->start)))
+ {
+ cleandeps_update = 1; /* cleandeps package is marked for update */
+ continue;
+ }
+ break;
+ }
if (j < dq->count)
{
dq->elements[0] = dq->elements[j];
queue_truncate(dq, 1);
}
+ else if (cleandeps_update)
+ do_cleandeps_update_filter(solv, dq); /* special update filter */
}
if (dq->count > 1 && postponed >= 0)
@@ -3233,6 +3308,7 @@ solver_solve(Solver *solv, Queue *job)
POOL_DEBUG(SOLV_DEBUG_STATS, "solver started\n");
POOL_DEBUG(SOLV_DEBUG_STATS, "dosplitprovides=%d, noupdateprovide=%d, noinfarchcheck=%d\n", solv->dosplitprovides, solv->noupdateprovide, solv->noinfarchcheck);
POOL_DEBUG(SOLV_DEBUG_STATS, "allowuninstall=%d, allowdowngrade=%d, allownamechange=%d, allowarchchange=%d, allowvendorchange=%d\n", solv->allowuninstall, solv->allowdowngrade, solv->allownamechange, solv->allowarchchange, solv->allowvendorchange);
+ POOL_DEBUG(SOLV_DEBUG_STATS, "dupallowdowngrade=%d, dupallownamechange=%d, dupallowarchchange=%d, dupallowvendorchange=%d\n", solv->dup_allowdowngrade, solv->dup_allownamechange, solv->dup_allowarchchange, solv->dup_allowvendorchange);
POOL_DEBUG(SOLV_DEBUG_STATS, "promoteepoch=%d, forbidselfconflicts=%d\n", pool->promoteepoch, pool->forbidselfconflicts);
POOL_DEBUG(SOLV_DEBUG_STATS, "obsoleteusesprovides=%d, implicitobsoleteusesprovides=%d, obsoleteusescolors=%d, implicitobsoleteusescolors=%d\n", pool->obsoleteusesprovides, pool->implicitobsoleteusesprovides, pool->obsoleteusescolors, pool->implicitobsoleteusescolors);
POOL_DEBUG(SOLV_DEBUG_STATS, "dontinstallrecommended=%d, addalreadyrecommended=%d\n", solv->dontinstallrecommended, solv->addalreadyrecommended);
@@ -3736,6 +3812,10 @@ solver_solve(Solver *solv, Queue *job)
name_s = s;
}
solver_addjobrule(solv, -p, 0, 0, i, weak);
+#ifdef ENABLE_LINKED_PKGS
+ if (solv->instbuddy && installed && s->repo == installed && solv->instbuddy[p - installed->start] > 1)
+ solver_addjobrule(solv, -solv->instbuddy[p - installed->start], 0, 0, i, weak);
+#endif
}
/* special case for "erase a specific solvable": we also
* erase all other solvables with that name, so that they
@@ -3803,7 +3883,14 @@ solver_solve(Solver *solv, Queue *job)
}
}
FOR_JOB_SELECT(p, pp, select, what)
- solver_addjobrule(solv, installed && pool->solvables[p].repo == installed ? p : -p, 0, 0, i, weak);
+ {
+ s = pool->solvables + p;
+ solver_addjobrule(solv, installed && s->repo == installed ? p : -p, 0, 0, i, weak);
+#ifdef ENABLE_LINKED_PKGS
+ if (solv->instbuddy && installed && s->repo == installed && solv->instbuddy[p - installed->start] > 1)
+ solver_addjobrule(solv, solv->instbuddy[p - installed->start], 0, 0, i, weak);
+#endif
+ }
break;
case SOLVER_DISTUPGRADE:
POOL_DEBUG(SOLV_DEBUG_JOB, "job: distupgrade %s\n", solver_select2str(pool, select, what));
diff --git a/src/strpool.c b/src/strpool.c
index 5e87918..b4a09a5 100644
--- a/src/strpool.c
+++ b/src/strpool.c
@@ -56,11 +56,7 @@ stringpool_freehash(Stringpool *ss)
void
stringpool_init_empty(Stringpool *ss)
{
- const char *emptystrs[] = {
- "<NULL>",
- "",
- 0,
- };
+ static const char *emptystrs[] = { "<NULL>", "", 0 };
stringpool_init(ss, emptystrs);
}
diff --git a/test/testcases/allowuninstall/conflict.t b/test/testcases/allowuninstall/conflict.t
new file mode 100644
index 0000000..a66d322
--- /dev/null
+++ b/test/testcases/allowuninstall/conflict.t
@@ -0,0 +1,14 @@
+repo system 0 testtags <inline>
+#>=Pkg: a 1 1 noarch
+#>=Con: b
+repo available 0 testtags <inline>
+#>=Pkg: b 1 1 noarch
+
+system x86_64 rpm system
+solverflags allowuninstall
+disable pkg a-1-1.noarch@system
+job install name b
+result transaction,problems <inline>
+#>problem a658cbaf info package a-1-1.noarch conflicts with b provided by b-1-1.noarch
+#>problem a658cbaf solution 567aa15d erase a-1-1.noarch@system
+#>problem a658cbaf solution e98e1a37 deljob install name b
diff --git a/test/testcases/allowuninstall/forcebest.t b/test/testcases/allowuninstall/forcebest.t
new file mode 100644
index 0000000..38ade6f
--- /dev/null
+++ b/test/testcases/allowuninstall/forcebest.t
@@ -0,0 +1,19 @@
+repo system 0 testtags <inline>
+#>=Pkg: a 1 1 noarch
+#>=Req: b = 1-1
+#>=Pkg: b 1 1 noarch
+repo available 0 testtags <inline>
+#>=Pkg: a 2 1 noarch
+#>=Req: b = 2-1
+#>=Pkg: b 2 1 noarch
+
+system x86_64 rpm system
+disable pkg b-1-1.noarch@system
+disable pkg b-2-1.noarch@available
+job allowuninstall pkg a-1-1.noarch@system
+job allowuninstall pkg b-1-1.noarch@system
+job update name a [forcebest]
+result transaction,problems <inline>
+#>problem e6d3911d info nothing provides b = 2-1 needed by a-2-1.noarch
+#>problem e6d3911d solution 0011b04f allow a-1-1.noarch@system
+#>problem e6d3911d solution 44d189a0 erase a-1-1.noarch@system
diff --git a/test/testcases/cleandeps/cleandeps_up3.t b/test/testcases/cleandeps/cleandeps_up3.t
new file mode 100644
index 0000000..7a4bfbc
--- /dev/null
+++ b/test/testcases/cleandeps/cleandeps_up3.t
@@ -0,0 +1,23 @@
+repo system 0 testtags <inline>
+#>=Pkg: a 1 1 x86_64
+#>=Req: b
+#>=Pkg: b 1 1 x86_64
+repo available 0 testtags <inline>
+#>=Pkg: a 2 1 x86_64
+#>=Req: b
+#>=Pkg: b 2 1 x86_64
+#>=Pkg: c 2 1 x86_64
+#>=Prv: b = 4
+repo available2 0 testtags <inline>
+#>=Pkg: b 3 1 x86_64
+system x86_64 rpm system
+
+job update all packages [cleandeps]
+result transaction,problems <inline>
+#>upgrade a-1-1.x86_64@system a-2-1.x86_64@available
+#>upgrade b-1-1.x86_64@system b-3-1.x86_64@available2
+nextjob
+job update repo available [cleandeps]
+result transaction,problems <inline>
+#>upgrade a-1-1.x86_64@system a-2-1.x86_64@available
+#>upgrade b-1-1.x86_64@system b-2-1.x86_64@available
diff --git a/tools/repo2solv.c b/tools/repo2solv.c
index e055e40..ece4225 100644
--- a/tools/repo2solv.c
+++ b/tools/repo2solv.c
@@ -169,9 +169,9 @@ read_plaindir_repo(Repo *repo, const char *dir)
close(fds[1]);
}
if (recursive)
- execl("/usr/bin/find", ".", "-name", ".", "-o", "-name", ".*", "-prune", "-o", "-name", "*.delta.rpm", "-o", "-name", "*.patch.rpm", "-o", "-name", "*.rpm", "-a", "-type", "f", "-print0", (char *)0);
+ execl("/usr/bin/find", "/usr/bin/find", ".", "-name", ".", "-o", "-name", ".*", "-prune", "-o", "-name", "*.delta.rpm", "-o", "-name", "*.patch.rpm", "-o", "-name", "*.rpm", "-a", "-type", "f", "-print0", (char *)0);
else
- execl("/usr/bin/find", ".", "-maxdepth", "1", "-name", ".", "-o", "-name", ".*", "-prune", "-o", "-name", "*.delta.rpm", "-o", "-name", "*.patch.rpm", "-o", "-name", "*.rpm", "-a", "-type", "f", "-print0", (char *)0);
+ execl("/usr/bin/find", "/usr/bin/find", ".", "-maxdepth", "1", "-name", ".", "-o", "-name", ".*", "-prune", "-o", "-name", "*.delta.rpm", "-o", "-name", "*.patch.rpm", "-o", "-name", "*.rpm", "-a", "-type", "f", "-print0", (char *)0);
perror("/usr/bin/find");
_exit(1);
}
@@ -208,6 +208,7 @@ read_plaindir_repo(Repo *repo, const char *dir)
repodata_set_location(data, p, 0, 0, bp[0] == '.' && bp[1] == '/' ? bp + 2 : bp);
solv_free(rpm);
}
+ solv_free(buf);
fclose(fp);
while (waitpid(pid, &wstatus, 0) == -1)
{
@@ -404,7 +405,7 @@ read_susetags_repo(Repo *repo, const char *dir)
filename = susetags_find(files, nfiles, "packages");
if (filename && (fp = susetags_open(ddir, filename, &tmp, 1)) != 0)
{
- if (repo_add_susetags(repo, fp, defvendor, 0, REPO_NO_INTERNALIZE|SUSETAGS_RECORD_SHARES))
+ if (repo_add_susetags(repo, fp, defvendor, 0, SUSETAGS_RECORD_SHARES))
{
fprintf(stderr, "%s: %s\n", tmp, pool_errstr(pool));
exit(1);
diff --git a/tools/rpmdb2solv.c b/tools/rpmdb2solv.c
index aa978d8..9fa8580 100644
--- a/tools/rpmdb2solv.c
+++ b/tools/rpmdb2solv.c
@@ -41,12 +41,14 @@ static void
usage(int status)
{
fprintf(stderr, "\nUsage:\n"
- "rpmdb2solv [-n] [-b <basefile>] [-p <productsdir>] [-r <root>]\n"
+ "rpmdb2solv [-P] [-C] [-n] [-b <basefile>] [-p <productsdir>] [-r <root>]\n"
" -n : No packages, do not read rpmdb, useful to only parse products\n"
" -b <basefile> : Write .solv to <basefile>.solv instead of stdout\n"
" -p <productsdir> : Scan <productsdir> for .prod files, representing installed products\n"
" -r <root> : Prefix rpmdb path and <productsdir> with <root>\n"
" -o <solv> : Write .solv to file instead of stdout\n"
+ " -P : print percentage done\n"
+ " -C : include the changelog\n"
);
exit(status);
}
@@ -61,6 +63,7 @@ main(int argc, char **argv)
Repodata *data;
int c, percent = 0;
int nopacks = 0;
+ int add_changelog = 0;
const char *root = 0;
const char *basefile = 0;
const char *refname = 0;
@@ -82,7 +85,7 @@ main(int argc, char **argv)
* parse arguments
*/
- while ((c = getopt(argc, argv, "APhnkxXb:r:p:o:")) >= 0)
+ while ((c = getopt(argc, argv, "ACPhnkxXb:r:p:o:")) >= 0)
switch (c)
{
case 'h':
@@ -126,6 +129,9 @@ main(int argc, char **argv)
pubkeys = 1;
break;
#endif
+ case 'C':
+ add_changelog = 1;
+ break;
default:
usage(1);
}
@@ -165,7 +171,12 @@ main(int argc, char **argv)
if (!nopacks)
{
- if (repo_add_rpmdb_reffp(repo, reffp, REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | (percent ? RPMDB_REPORT_PROGRESS : 0)))
+ int flags = REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE;
+ if (percent)
+ flags |= RPMDB_REPORT_PROGRESS;
+ if (add_changelog)
+ flags |= RPM_ADD_WITH_CHANGELOG;
+ if (repo_add_rpmdb_reffp(repo, reffp, flags))
{
fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool));
exit(1);
diff --git a/tools/susetags2solv.c b/tools/susetags2solv.c
index 19278db..ced614b 100644
--- a/tools/susetags2solv.c
+++ b/tools/susetags2solv.c
@@ -197,7 +197,7 @@ main(int argc, char **argv)
perror(fn);
exit(1);
}
- if (repo_add_susetags(repo, fp, defvendor, 0, flags | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE))
+ if (repo_add_susetags(repo, fp, defvendor, 0, flags | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | SUSETAGS_RECORD_SHARES))
{
fprintf(stderr, "susetags2solv: %s: %s\n", fnp, pool_errstr(pool));
exit(1);