summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/acquire-item.cc8
-rw-r--r--apt-pkg/acquire-worker.cc115
-rwxr-xr-xtest/integration/test-pdiff-usage32
3 files changed, 102 insertions, 53 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index d820756ca..b2e578629 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -281,6 +281,12 @@ bool pkgAcquire::Item::QueueURI(pkgAcquire::ItemDesc &Item)
for a hashsum mismatch to happen which helps nobody) */
bool pkgAcqTransactionItem::QueueURI(pkgAcquire::ItemDesc &Item)
{
+ if (TransactionManager->State != TransactionStarted)
+ {
+ if (_config->FindB("Debug::Acquire::Transaction", false))
+ std::clog << "Skip " << Target.URI << " as transaction was already dealt with!" << std::endl;
+ return false;
+ }
std::string const FinalFile = GetFinalFilename();
if (TransactionManager != NULL && TransactionManager->IMSHit == true &&
FileExists(FinalFile) == true)
@@ -866,6 +872,8 @@ void pkgAcqMetaBase::AbortTransaction()
for (std::vector<pkgAcqTransactionItem*>::iterator I = Transaction.begin();
I != Transaction.end(); ++I)
{
+ if ((*I)->Status != pkgAcquire::Item::StatFetching)
+ Owner->Dequeue(*I);
(*I)->TransactionState(TransactionAbort);
}
Transaction.clear();
diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc
index f901847f7..ca1fd4836 100644
--- a/apt-pkg/acquire-worker.cc
+++ b/apt-pkg/acquire-worker.cc
@@ -172,6 +172,25 @@ bool pkgAcquire::Worker::ReadMessages()
// ---------------------------------------------------------------------
/* This takes the messages from the message queue and runs them through
the parsers in order. */
+enum class APT_HIDDEN MessageType {
+ CAPABILITIES = 100,
+ LOG = 101,
+ STATUS = 102,
+ REDIRECT = 103,
+ WARNING = 104,
+ URI_START = 200,
+ URI_DONE = 201,
+ URI_FAILURE = 400,
+ GENERAL_FAILURE = 401,
+ MEDIA_CHANGE = 403
+};
+static bool isDoomedItem(pkgAcquire::Item const * const Itm)
+{
+ auto const TransItm = dynamic_cast<pkgAcqTransactionItem const * const>(Itm);
+ if (TransItm == nullptr)
+ return false;
+ return TransItm->TransactionManager->State != pkgAcqTransactionItem::TransactionStarted;
+}
bool pkgAcquire::Worker::RunMessages()
{
while (MessageQueue.empty() == false)
@@ -184,7 +203,7 @@ bool pkgAcquire::Worker::RunMessages()
// Fetch the message number
char *End;
- int Number = strtol(Message.c_str(),&End,10);
+ MessageType const Number = static_cast<MessageType>(strtoul(Message.c_str(),&End,10));
if (End == Message.c_str())
return _error->Error("Invalid message from method %s: %s",Access.c_str(),Message.c_str());
@@ -210,27 +229,23 @@ bool pkgAcquire::Worker::RunMessages()
// Determine the message number and dispatch
switch (Number)
{
- // 100 Capabilities
- case 100:
+ case MessageType::CAPABILITIES:
if (Capabilities(Message) == false)
return _error->Error("Unable to process Capabilities message from %s",Access.c_str());
break;
- // 101 Log
- case 101:
+ case MessageType::LOG:
if (Debug == true)
clog << " <- (log) " << LookupTag(Message,"Message") << endl;
break;
- // 102 Status
- case 102:
+ case MessageType::STATUS:
Status = LookupTag(Message,"Message");
break;
- // 103 Redirect
- case 103:
+ case MessageType::REDIRECT:
{
- if (Itm == 0)
+ if (Itm == nullptr)
{
_error->Error("Method gave invalid 103 Redirect message");
break;
@@ -248,11 +263,13 @@ bool pkgAcquire::Worker::RunMessages()
// and then put it in the main queue again
std::vector<Item*> const ItmOwners = Itm->Owners;
OwnerQ->ItemDone(Itm);
- Itm = NULL;
- for (pkgAcquire::Queue::QItem::owner_iterator O = ItmOwners.begin(); O != ItmOwners.end(); ++O)
+ Itm = nullptr;
+ for (auto const &Owner: ItmOwners)
{
- pkgAcquire::Item *Owner = *O;
pkgAcquire::ItemDesc &desc = Owner->GetItemDesc();
+ if (Log != nullptr)
+ Log->Done(desc);
+
// if we change site, treat it as a mirror change
if (URI::SiteOnly(NewURI) != URI::SiteOnly(desc.URI))
{
@@ -270,22 +287,19 @@ bool pkgAcquire::Worker::RunMessages()
}
}
desc.URI = NewURI;
- OwnerQ->Owner->Enqueue(desc);
-
- if (Log != 0)
- Log->Done(desc);
+ if (isDoomedItem(Owner) == false)
+ OwnerQ->Owner->Enqueue(desc);
}
break;
}
- // 104 Warning
- case 104:
+
+ case MessageType::WARNING:
_error->Warning("%s: %s", Itm->Owner->DescURI().c_str(), LookupTag(Message,"Message").c_str());
break;
- // 200 URI Start
- case 200:
+ case MessageType::URI_START:
{
- if (Itm == 0)
+ if (Itm == nullptr)
{
_error->Error("Method gave invalid 200 URI Start message");
break;
@@ -295,26 +309,24 @@ bool pkgAcquire::Worker::RunMessages()
CurrentSize = 0;
TotalSize = strtoull(LookupTag(Message,"Size","0").c_str(), NULL, 10);
ResumePoint = strtoull(LookupTag(Message,"Resume-Point","0").c_str(), NULL, 10);
- for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
+ for (auto const Owner: Itm->Owners)
{
- (*O)->Start(Message, TotalSize);
-
+ Owner->Start(Message, TotalSize);
// Display update before completion
- if (Log != 0)
+ if (Log != nullptr)
{
if (Log->MorePulses == true)
- Log->Pulse((*O)->GetOwner());
- Log->Fetch((*O)->GetItemDesc());
+ Log->Pulse(Owner->GetOwner());
+ Log->Fetch(Owner->GetItemDesc());
}
}
break;
}
- // 201 URI Done
- case 201:
+ case MessageType::URI_DONE:
{
- if (Itm == 0)
+ if (Itm == nullptr)
{
_error->Error("Method gave invalid 201 URI Done message");
break;
@@ -363,9 +375,8 @@ bool pkgAcquire::Worker::RunMessages()
bool const isIMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false) ||
StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false);
- for (pkgAcquire::Queue::QItem::owner_iterator O = ItmOwners.begin(); O != ItmOwners.end(); ++O)
+ for (auto const Owner: ItmOwners)
{
- pkgAcquire::Item * const Owner = *O;
HashStringList const ExpectedHashes = Owner->GetExpectedHashes();
if(_config->FindB("Debug::pkgAcquire::Auth", false) == true)
{
@@ -412,10 +423,12 @@ bool pkgAcquire::Worker::RunMessages()
else // hashsum mismatch
Owner->Status = pkgAcquire::Item::StatAuthError;
+
if (consideredOkay == true)
{
- Owner->Done(Message, ReceivedHashes, Config);
- if (Log != 0)
+ if (isDoomedItem(Owner) == false)
+ Owner->Done(Message, ReceivedHashes, Config);
+ if (Log != nullptr)
{
if (isIMSHit)
Log->IMSHit(Owner->GetItemDesc());
@@ -425,8 +438,9 @@ bool pkgAcquire::Worker::RunMessages()
}
else
{
- Owner->Failed(Message,Config);
- if (Log != 0)
+ if (isDoomedItem(Owner) == false)
+ Owner->Failed(Message,Config);
+ if (Log != nullptr)
Log->Fail(Owner->GetItemDesc());
}
}
@@ -434,10 +448,9 @@ bool pkgAcquire::Worker::RunMessages()
break;
}
- // 400 URI Failure
- case 400:
+ case MessageType::URI_FAILURE:
{
- if (Itm == 0)
+ if (Itm == nullptr)
{
std::string const msg = LookupTag(Message,"Message");
_error->Error("Method gave invalid 400 URI Failure message: %s", msg.c_str());
@@ -447,13 +460,13 @@ bool pkgAcquire::Worker::RunMessages()
PrepareFiles("400::URIFailure", Itm);
// Display update before completion
- if (Log != 0 && Log->MorePulses == true)
+ if (Log != nullptr && Log->MorePulses == true)
for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O)
Log->Pulse((*O)->GetOwner());
std::vector<Item*> const ItmOwners = Itm->Owners;
OwnerQ->ItemDone(Itm);
- Itm = NULL;
+ Itm = nullptr;
bool errTransient;
{
@@ -463,27 +476,25 @@ bool pkgAcquire::Worker::RunMessages()
errTransient = std::find(std::begin(reasons), std::end(reasons), failReason) != std::end(reasons);
}
- for (pkgAcquire::Queue::QItem::owner_iterator O = ItmOwners.begin(); O != ItmOwners.end(); ++O)
+ for (auto const Owner: ItmOwners)
{
if (errTransient)
- (*O)->Status = pkgAcquire::Item::StatTransientNetworkError;
- (*O)->Failed(Message,Config);
-
- if (Log != 0)
- Log->Fail((*O)->GetItemDesc());
+ Owner->Status = pkgAcquire::Item::StatTransientNetworkError;
+ if (isDoomedItem(Owner) == false)
+ Owner->Failed(Message,Config);
+ if (Log != nullptr)
+ Log->Fail(Owner->GetItemDesc());
}
ItemDone();
break;
}
- // 401 General Failure
- case 401:
+ case MessageType::GENERAL_FAILURE:
_error->Error("Method %s General failure: %s",Access.c_str(),LookupTag(Message,"Message").c_str());
break;
- // 403 Media Change
- case 403:
+ case MessageType::MEDIA_CHANGE:
MediaChange(Message);
break;
}
diff --git a/test/integration/test-pdiff-usage b/test/integration/test-pdiff-usage
index 11c8c4cc1..4e2d1f182 100755
--- a/test/integration/test-pdiff-usage
+++ b/test/integration/test-pdiff-usage
@@ -10,9 +10,24 @@ LOWCOSTEXT='lz4'
buildaptarchive
setupflataptarchive
-changetowebserver -o aptwebserver::support::modified-since=false
+changetowebserver
+
+cat >rootdir/etc/apt/apt.conf.d/contents.conf <<EOF
+Acquire::IndexTargets::deb::Contents {
+ MetaKey "\$(COMPONENT)/Contents-\$(ARCHITECTURE)";
+ ShortDescription "Contents";
+ Description "\$(RELEASE)/\$(COMPONENT) \$(ARCHITECTURE) Contents";
+ MetaKey "\$(COMPONENT)/Contents-\$(ARCHITECTURE)";
+ flatMetaKey "Contents-\$(ARCHITECTURE)";
+ flatDescription "\$(RELEASE) \$(ARCHITECTURE) Contents";
+};
+EOF
PKGFILE="${TESTDIR}/$(echo "$(basename $0)" | sed 's#^test-#Packages-#')"
+echo 'contents for stuff' > aptarchive/Contents-i386
+compressfile aptarchive/Contents-i386
+echo 'hacked' > aptarchive/hacked-i386
+compressfile aptarchive/hacked-i386
wasmergeused() {
testsuccess apt update "$@"
@@ -193,6 +208,21 @@ SHA256-Download:
" aptcache show apt newstuff futurestuff
# we reuse the archive state of the previous test here
+ msgmsg "Testcase: pdiff handling is stopped if transaction fails $*"
+ rm -rf rootdir/var/lib/apt/lists
+ cp -a rootdir/var/lib/apt/lists-bak rootdir/var/lib/apt/lists
+ cp Packages-future aptarchive/Packages
+ rm -f rootdir/var/lib/apt/lists/*_Contents-*
+ webserverconfig 'aptwebserver::overwrite::.*Contents-.*::filename' '/hacked-i386.gz'
+ testfailure apt update "$@" -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::http=1
+ webserverconfig 'aptwebserver::overwrite::.*Contents-.*::filename' '/Contents-i386.gz'
+ cp rootdir/tmp/testfailure.output patchdownload.output
+ testfailure grep 'rred:600' patchdownload.output
+ testnopackage newstuff futurestuff
+ testsuccessequal "$(cat "${PKGFILE}")
+" aptcache show apt oldstuff
+
+ # we reuse the archive state of the previous test here
msgmsg "Testcase: downloading a patch fails, but successful fallback: $*"
rm -rf rootdir/var/lib/apt/lists
cp -a rootdir/var/lib/apt/lists-bak rootdir/var/lib/apt/lists