summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vogt <michael.vogt@ubuntu.com>2012-01-16 08:44:39 +0100
committerMichael Vogt <michael.vogt@ubuntu.com>2012-01-16 08:44:39 +0100
commite08e66ca82147b72454964fdd624002f9b23290e (patch)
treee9b455bb8ddaa4f89939661dc02ea9baef4845d5
parent6bfb4a2b25b576220e0c8bad1ba9479637667e19 (diff)
parent85e1885525977809ff6a3b70abb84d3a63e41817 (diff)
merged from donkult
-rw-r--r--apt-pkg/cacheiterators.h2
-rw-r--r--apt-pkg/deb/dpkgpm.cc73
-rw-r--r--apt-pkg/depcache.cc13
-rw-r--r--apt-pkg/packagemanager.cc2
-rw-r--r--apt-pkg/pkgcache.cc44
-rw-r--r--debian/changelog7
-rwxr-xr-xtest/integration/test-dpkg-assert-multi-arch53
-rwxr-xr-xtest/integration/test-implicit-conflicts-real-not-virtual22
8 files changed, 170 insertions, 46 deletions
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
index 5382f3838..e6a0fddb0 100644
--- a/apt-pkg/cacheiterators.h
+++ b/apt-pkg/cacheiterators.h
@@ -283,6 +283,8 @@ class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
inline bool Reverse() const {return Type == DepRev;};
bool IsCritical() const;
bool IsNegative() const;
+ bool IsIgnorable(PrvIterator const &Prv) const;
+ bool IsIgnorable(PkgIterator const &Pkg) const;
void GlobOr(DepIterator &Start,DepIterator &End);
Version **AllTargets() const;
bool SmartTargetPkg(PkgIterator &Result) const;
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index 4a1bf42d5..c08f52c25 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -107,7 +107,7 @@ ionice(int PID)
{
if (!FileExists("/usr/bin/ionice"))
return false;
- pid_t Process = ExecFork();
+ pid_t Process = ExecFork();
if (Process == 0)
{
char buf[32];
@@ -828,6 +828,40 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds,
*/
bool pkgDPkgPM::Go(int OutStatusFd)
{
+ // Generate the base argument list for dpkg
+ std::vector<const char *> Args;
+ unsigned long StartSize = 0;
+ string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
+ Args.push_back(Tmp.c_str());
+ StartSize += Tmp.length();
+
+ // Stick in any custom dpkg options
+ Configuration::Item const *Opts = _config->Tree("DPkg::Options");
+ if (Opts != 0)
+ {
+ Opts = Opts->Child;
+ for (; Opts != 0; Opts = Opts->Next)
+ {
+ if (Opts->Value.empty() == true)
+ continue;
+ Args.push_back(Opts->Value.c_str());
+ StartSize += Opts->Value.length();
+ }
+ }
+
+ size_t const BaseArgs = Args.size();
+ // we need to detect if we can qualify packages with the architecture or not
+ Args.push_back("--assert-multi-arch");
+ Args.push_back(NULL);
+
+ pid_t dpkgAssertMultiArch = ExecFork();
+ if (dpkgAssertMultiArch == 0)
+ {
+ execv(Args[0], (char**) &Args[0]);
+ _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!");
+ _exit(2);
+ }
+
fd_set rfds;
struct timespec tv;
sigset_t sigmask;
@@ -904,27 +938,20 @@ bool pkgDPkgPM::Go(int OutStatusFd)
// create log
OpenLog();
- // Generate the base argument list for dpkg
- std::vector<const char *> Args;
- unsigned long StartSize = 0;
- string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
- Args.push_back(Tmp.c_str());
- StartSize += Tmp.length();
-
- // Stick in any custom dpkg options
- Configuration::Item const *Opts = _config->Tree("DPkg::Options");
- if (Opts != 0)
+ bool dpkgMultiArch = false;
+ if (dpkgAssertMultiArch > 0)
{
- Opts = Opts->Child;
- for (; Opts != 0; Opts = Opts->Next)
+ int Status = 0;
+ while (waitpid(dpkgAssertMultiArch, &Status, 0) != dpkgAssertMultiArch)
{
- if (Opts->Value.empty() == true)
+ if (errno == EINTR)
continue;
- Args.push_back(Opts->Value.c_str());
- StartSize += Opts->Value.length();
+ _error->WarningE("dpkgGo", _("Waited for %s but it wasn't there"), "dpkg --assert-multi-arch");
+ break;
}
+ if (WIFEXITED(Status) == true && WEXITSTATUS(Status) == 0)
+ dpkgMultiArch = true;
}
- size_t const BaseArgs = Args.size();
// this loop is runs once per operation
for (vector<Item>::const_iterator I = List.begin(); I != List.end();)
@@ -964,14 +991,17 @@ bool pkgDPkgPM::Go(int OutStatusFd)
if (J - I > (signed)MaxArgs)
{
J = I + MaxArgs;
- Args.reserve(MaxArgs + 10);
+ unsigned long const size = MaxArgs + 10;
+ Args.reserve(size);
+ Packages.reserve(size);
}
else
{
- Args.reserve((J - I) + 10);
+ unsigned long const size = (J - I) + 10;
+ Args.reserve(size);
+ Packages.reserve(size);
}
-
int fd[2];
pipe(fd);
@@ -1046,7 +1076,8 @@ bool pkgDPkgPM::Go(int OutStatusFd)
continue;
if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end())
continue;
- if (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all"))
+ // We keep this here to allow "smooth" transitions from e.g. multiarch dpkg/ubuntu to dpkg/debian
+ if (dpkgMultiArch == false && (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all")))
{
char const * const name = I->Pkg.Name();
ADDARG(name);
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index 0f4715fad..7aaf1c61b 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -371,19 +371,10 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
// Check the providing packages
PrvIterator P = Dep.TargetPkg().ProvidesList();
- PkgIterator Pkg = Dep.ParentPkg();
for (; P.end() != true; ++P)
{
- if (Dep.IsNegative() == true)
- {
- /* Provides may never be applied against the same package (or group)
- if it is a conflicts. See the comment above. */
- if (P.OwnerPkg()->Group == Pkg->Group)
- continue;
- // Implicit group-conflicts should not be applied on providers of other groups
- if (Pkg->Group == Dep.TargetPkg()->Group && P.OwnerPkg()->Group != Pkg->Group)
- continue;
- }
+ if (Dep.IsIgnorable(P) == true)
+ continue;
// Check if the provides is a hit
if (Type == NowVersion)
diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc
index 4f9762701..c9d7a3024 100644
--- a/apt-pkg/packagemanager.cc
+++ b/apt-pkg/packagemanager.cc
@@ -250,7 +250,7 @@ bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D,
continue;
// Ignore self conflicts, ignore conflicts from irrelevent versions
- if (D.ParentPkg() == Pkg || D.ParentVer() != D.ParentPkg().CurrentVer())
+ if (D.IsIgnorable(Pkg) || D.ParentVer() != D.ParentPkg().CurrentVer())
continue;
if (Cache.VS().CheckDep(Ver,D->CompareOp,D.TargetVer()) == false)
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index c854249e4..997c70768 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -619,13 +619,12 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets() const
// Walk along the actual package providing versions
for (VerIterator I = DPkg.VersionList(); I.end() == false; ++I)
{
- if (Owner->VS->CheckDep(I.VerStr(),S->CompareOp,TargetVer()) == false)
+ if (IsIgnorable(I.ParentPkg()) == true)
continue;
- if (IsNegative() == true &&
- ParentPkg() == I.ParentPkg())
+ if (Owner->VS->CheckDep(I.VerStr(),S->CompareOp,TargetVer()) == false)
continue;
-
+
Size++;
if (Res != 0)
*End++ = I;
@@ -634,13 +633,12 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets() const
// Follow all provides
for (PrvIterator I = DPkg.ProvidesList(); I.end() == false; ++I)
{
- if (Owner->VS->CheckDep(I.ProvideVersion(),S->CompareOp,TargetVer()) == false)
+ if (IsIgnorable(I) == true)
continue;
-
- if (IsNegative() == true &&
- ParentPkg()->Group == I.OwnerPkg()->Group)
+
+ if (Owner->VS->CheckDep(I.ProvideVersion(),S->CompareOp,TargetVer()) == false)
continue;
-
+
Size++;
if (Res != 0)
*End++ = I.OwnerVer();
@@ -682,6 +680,34 @@ void pkgCache::DepIterator::GlobOr(DepIterator &Start,DepIterator &End)
}
}
/*}}}*/
+// DepIterator::IsIgnorable - should this packag/providr be ignored? /*{{{*/
+// ---------------------------------------------------------------------
+/* Deps like self-conflicts should be ignored as well as implicit conflicts
+ on virtual packages. */
+bool pkgCache::DepIterator::IsIgnorable(PkgIterator const &Pkg) const
+{
+ if (ParentPkg() == TargetPkg())
+ return IsNegative();
+
+ return false;
+}
+bool pkgCache::DepIterator::IsIgnorable(PrvIterator const &Prv) const
+{
+ if (IsNegative() == false)
+ return false;
+
+ PkgIterator const Pkg = ParentPkg();
+ /* Provides may never be applied against the same package (or group)
+ if it is a conflicts. See the comment above. */
+ if (Prv.OwnerPkg()->Group == Pkg->Group)
+ return true;
+ // Implicit group-conflicts should not be applied on providers of other groups
+ if (Pkg->Group == TargetPkg()->Group && Prv.OwnerPkg()->Group != Pkg->Group)
+ return true;
+
+ return false;
+}
+ /*}}}*/
// ostream operator to handle string representation of a dependecy /*{{{*/
// ---------------------------------------------------------------------
/* */
diff --git a/debian/changelog b/debian/changelog
index 7ed580d3f..e524081c8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,8 +4,13 @@ apt (0.8.16~exp10) UNRELEASED; urgency=low
* apt-pkg/depcache.cc:
- implicit conflicts (for multiarch) are supposed to conflict
only with real packages, not with virtual providers
+ * apt-pkg/pkgcache.cc:
+ - ignore implicit conflicts on providers in AllTarget, too
+ * apt-pkg/deb/dpkgpm.cc:
+ - check if dpkg supports multiarch with --assert-multi-arch
+ and if it does be always explicit about the architecture
- -- David Kalnischkies <kalnischkies@gmail.com> Wed, 11 Jan 2012 17:59:33 +0100
+ -- David Kalnischkies <kalnischkies@gmail.com> Fri, 13 Jan 2012 17:29:07 +0100
apt (0.8.16~exp9ubuntu1) UNRELEASED; urgency=low
diff --git a/test/integration/test-dpkg-assert-multi-arch b/test/integration/test-dpkg-assert-multi-arch
new file mode 100755
index 000000000..b1ec73e18
--- /dev/null
+++ b/test/integration/test-dpkg-assert-multi-arch
@@ -0,0 +1,53 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'amd64' 'i386'
+
+buildsimplenativepackage 'native-pkg' 'amd64' '1.0' 'stable'
+buildsimplenativepackage 'foreign-pkg' 'i386' '0.5' 'stable' 'Multi-Arch: foreign'
+buildsimplenativepackage 'same-lib' 'amd64,i386' '0.5' 'stable' 'Multi-Arch: same'
+
+setupaptarchive
+
+testqualifier() {
+ msgtest 'Test for correct qualifier mode' $2
+ GIVEN="$(aptget install $1 -qq -o Debug::pkgDPkgPM=1 2>&1 | grep -- '--configure' | sed -e 's/^.*--configure \([^ ]*\).*$/\1/')"
+ test "$GIVEN" = "$2" && msgpass || msgfail
+}
+
+# non-multiarch or "ubuntus" old multiarchified dpkg
+echo 'Dir::Bin::dpkg "./dpkg-wrapper";' > rootdir/etc/apt/apt.conf.d/99dpkgwrapper
+echo '#! /bin/sh
+if echo "$*" | grep -q -- "--assert-multi-arch"; then
+ return 2;
+fi
+return $*' > ./dpkg-wrapper
+chmod +x ./dpkg-wrapper
+
+testqualifier 'native-pkg' 'native-pkg'
+testqualifier 'native-pkg:amd64' 'native-pkg'
+testqualifier 'foreign-pkg' 'foreign-pkg:i386'
+testqualifier 'foreign-pkg:i386' 'foreign-pkg:i386'
+testqualifier 'same-lib' 'same-lib'
+testqualifier 'same-lib:amd64' 'same-lib'
+testqualifier 'same-lib:i386' 'same-lib:i386'
+
+# multiarch dpkg (new interface version)
+
+echo 'Dir::Bin::dpkg "./dpkg-wrapper";' > rootdir/etc/apt/apt.conf.d/99dpkgwrapper
+echo '#! /bin/sh
+if echo "$*" | grep -q -- "--assert-multi-arch"; then
+ return 0;
+fi
+return $*' > ./dpkg-wrapper
+
+testqualifier 'native-pkg' 'native-pkg:amd64'
+testqualifier 'native-pkg:amd64' 'native-pkg:amd64'
+testqualifier 'foreign-pkg' 'foreign-pkg:i386'
+testqualifier 'foreign-pkg:i386' 'foreign-pkg:i386'
+testqualifier 'same-lib' 'same-lib:amd64'
+testqualifier 'same-lib:amd64' 'same-lib:amd64'
+testqualifier 'same-lib:i386' 'same-lib:i386'
diff --git a/test/integration/test-implicit-conflicts-real-not-virtual b/test/integration/test-implicit-conflicts-real-not-virtual
index 9d13e1709..c9fca4edf 100755
--- a/test/integration/test-implicit-conflicts-real-not-virtual
+++ b/test/integration/test-implicit-conflicts-real-not-virtual
@@ -10,6 +10,8 @@ insertpackage 'unstable-mp' 'crda' 'i386,amd64' '1.1.1-1ubuntu4mp' 'Provides: wi
Multi-Arch: foreign'
insertpackage 'unstable-m' 'crda' 'i386,amd64' '1.1.1-1ubuntu4m' 'Multi-Arch: foreign'
insertpackage 'unstable-p' 'crda' 'i386,amd64' '1.1.1-1ubuntu4p' 'Provides: wireless-crda'
+insertpackage 'unstable' 'wireless-crda' 'i386,amd64' '1.16'
+
insertinstalledpackage 'wireless-crda' 'amd64' '1.14'
@@ -19,7 +21,7 @@ testequal 'Reading package lists...
Building dependency tree...
The following NEW packages will be installed:
crda
-0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Inst crda (1.1.1-1ubuntu4m unstable-m [amd64])
Conf crda (1.1.1-1ubuntu4m unstable-m [amd64])' aptget install crda -s -t unstable-m
@@ -27,7 +29,7 @@ testequal 'Reading package lists...
Building dependency tree...
The following NEW packages will be installed:
crda
-0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Inst crda (1.1.1-1ubuntu4p unstable-p [amd64])
Conf crda (1.1.1-1ubuntu4p unstable-p [amd64])' aptget install crda -s -t unstable-p
@@ -35,6 +37,20 @@ testequal 'Reading package lists...
Building dependency tree...
The following NEW packages will be installed:
crda
-0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Inst crda (1.1.1-1ubuntu4mp unstable-mp [amd64])
Conf crda (1.1.1-1ubuntu4mp unstable-mp [amd64])' aptget install crda -s -t unstable-mp
+
+rm rootdir/var/lib/dpkg/status
+insertinstalledpackage 'crda' 'amd64' '1.1.1-1ubuntu4mp' 'Provides: wireless-crda
+Conflicts: wireless-crda (<< 1.15)
+Replaces: wireless-crda ( << 1.15)
+Multi-arch: foreign'
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+ wireless-crda
+0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
+Inst wireless-crda (1.16 unstable [amd64])
+Conf wireless-crda (1.16 unstable [amd64])' aptget install wireless-crda -s -t unstable