]> git.saurik.com Git - apt.git/commitdiff
merged from lp:~donkult/apt/experimental/
authorMichael Vogt <michael.vogt@ubuntu.com>
Fri, 13 Jan 2012 16:35:44 +0000 (17:35 +0100)
committerMichael Vogt <michael.vogt@ubuntu.com>
Fri, 13 Jan 2012 16:35:44 +0000 (17:35 +0100)
apt-pkg/cacheiterators.h
apt-pkg/deb/dpkgpm.cc
apt-pkg/depcache.cc
apt-pkg/packagemanager.cc
apt-pkg/pkgcache.cc
debian/changelog
methods/rred.cc
test/integration/test-dpkg-assert-multi-arch [new file with mode: 0755]
test/integration/test-implicit-conflicts-real-not-virtual [new file with mode: 0755]

index 5382f3838a0475f77537326d36f147bfc78e7b3b..e6a0fddb0667baa32570000db18a5debebcc3852 100644 (file)
@@ -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;
index 7c0ed56398ce2f8b149f7919c1f30b0217cf742b..4dc0baa5049c552290bb8300c05c4d259dcccd92 100644 (file)
@@ -108,7 +108,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];
@@ -829,6 +829,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;
@@ -905,27 +939,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();)
@@ -965,14 +992,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);
 
@@ -1047,7 +1077,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);
index 031fca5c0dda3930100d8f5d6706e709f552d41b..0851597111cff81a8cb7ba9ee59075a26d53c162 100644 (file)
@@ -371,14 +371,11 @@ 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)
    {
-      /* 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 && Dep.IsNegative() == true)
+      if (Dep.IsIgnorable(P) == true)
         continue;
-      
+
       // Check if the provides is a hit
       if (Type == NowVersion)
       {
index 4f97627016009e5a4b3a2c19bde9367e482cac65..c9d7a3024c778750ba35d0849fdcb3d57c1132cf 100644 (file)
@@ -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)
index c854249e444d437fcc2341ba6c5849d40c022047..997c70768adb192ea89c5be5974b74ec7c1d5c19 100644 (file)
@@ -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     /*{{{*/
 // ---------------------------------------------------------------------
 /* */
index a1b93a98181d2bde3d94912b93ea751dbee37288..5eb4e593fd6233acfb3a044ff6b0d9cfb4f09638 100644 (file)
@@ -1,3 +1,17 @@
+apt (0.8.16~exp10) UNRELEASED; urgency=low
+
+  [ David Kalnischkies ]
+  * 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>  Fri, 13 Jan 2012 17:29:07 +0100
+
 apt (0.8.16~exp9) experimental; urgency=low
 
   [ Julian Andres Klode ]
index bf9294d96c328f7669df43e5a0fbb2bd716a481d..e37a12ed952ee6dd1427d0d4c3c3e0ac70324b88 100644 (file)
@@ -235,7 +235,9 @@ RredMethod::State RredMethod::patchMMap(FileFd &Patch, FileFd &From,                /*{{{*/
        MMap ed_cmds(Patch, MMap::ReadOnly);
        MMap in_file(From, MMap::ReadOnly);
 
-       if (ed_cmds.Size() == 0 || in_file.Size() == 0)
+       unsigned long long const ed_size = ed_cmds.Size();
+       unsigned long long const in_size = in_file.Size();
+       if (ed_size == 0 || in_size == 0)
                return MMAP_FAILED;
 
        EdCommand* commands = 0;
@@ -244,10 +246,10 @@ RredMethod::State RredMethod::patchMMap(FileFd &Patch, FileFd &From,              /*{{{*/
 
        const char* begin = (char*) ed_cmds.Data();
        const char* end = begin;
-       const char* ed_end = (char*) ed_cmds.Data() + ed_cmds.Size();
+       const char* ed_end = (char*) ed_cmds.Data() + ed_size;
 
        const char* input = (char*) in_file.Data();
-       const char* input_end = (char*) in_file.Data() + in_file.Size();
+       const char* input_end = (char*) in_file.Data() + in_size;
 
        size_t i;
 
diff --git a/test/integration/test-dpkg-assert-multi-arch b/test/integration/test-dpkg-assert-multi-arch
new file mode 100755 (executable)
index 0000000..b1ec73e
--- /dev/null
@@ -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
new file mode 100755 (executable)
index 0000000..c9fca4e
--- /dev/null
@@ -0,0 +1,56 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'amd64' 'i386'
+
+insertpackage 'unstable-mp' 'crda' 'i386,amd64' '1.1.1-1ubuntu4mp' 'Provides: wireless-crda
+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'
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  crda
+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
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  crda
+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
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  crda
+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