diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-09-10 15:37:46 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-09-10 15:37:46 +0900 |
commit | 0e46e80434781d1acbc4f5716827bf8688450a30 (patch) | |
tree | bd75ab938e88eb1e111c3bcb099d7a6793bd4364 | |
parent | e679b515eddb3dd340fb25620de0160211f40fdc (diff) | |
download | libsolv-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-- | NEWS | 12 | ||||
-rw-r--r-- | VERSION.cmake | 2 | ||||
-rw-r--r-- | doc/rpmdb2solv.txt | 3 | ||||
-rw-r--r-- | examples/solv/fastestmirror.c | 6 | ||||
-rw-r--r-- | examples/solv/repoinfo_system_rpm.c | 6 | ||||
-rw-r--r-- | ext/repo_autopattern.c | 4 | ||||
-rw-r--r-- | ext/repo_repomdxml.c | 2 | ||||
-rw-r--r-- | ext/repo_rpmdb.c | 18 | ||||
-rw-r--r-- | ext/testcase.c | 34 | ||||
-rw-r--r-- | package/libsolv.changes | 18 | ||||
-rw-r--r-- | package/libsolv.spec.in | 2 | ||||
-rw-r--r-- | src/cleandeps.c | 2 | ||||
-rw-r--r-- | src/policy.c | 14 | ||||
-rw-r--r-- | src/pool.c | 3 | ||||
-rw-r--r-- | src/pool.h | 1 | ||||
-rw-r--r-- | src/problems.c | 17 | ||||
-rw-r--r-- | src/rules.c | 32 | ||||
-rw-r--r-- | src/selection.c | 2 | ||||
-rw-r--r-- | src/solver.c | 109 | ||||
-rw-r--r-- | src/strpool.c | 6 | ||||
-rw-r--r-- | test/testcases/allowuninstall/conflict.t | 14 | ||||
-rw-r--r-- | test/testcases/allowuninstall/forcebest.t | 19 | ||||
-rw-r--r-- | test/testcases/cleandeps/cleandeps_up3.t | 23 | ||||
-rw-r--r-- | tools/repo2solv.c | 7 | ||||
-rw-r--r-- | tools/rpmdb2solv.c | 17 | ||||
-rw-r--r-- | tools/susetags2solv.c | 2 |
26 files changed, 318 insertions, 57 deletions
@@ -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); } } @@ -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; } @@ -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); |