X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/514a25cbcd2babb2a9c4485fc7b9a4256b7f6ff3..b58e2c7c56b1416a343e81f9f80cb1f02c128e25:/apt-pkg/acquire.cc diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index fb1210750..29362fb40 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -351,8 +351,42 @@ string pkgAcquire::QueueName(string Uri,MethodConfig const *&Config) if (Config->SingleInstance == true || QueueMode == QueueAccess) return U.Access; - string AccessSchema = U.Access + ':', - FullQueueName = AccessSchema + U.Host; + string AccessSchema = U.Access + ':'; + string FullQueueName; + + if (U.Host.empty()) + { + long existing = 0; + // check how many queues exist already and reuse empty ones + for (Queue const *I = Queues; I != 0; I = I->Next) + if (I->Name.compare(0, AccessSchema.length(), AccessSchema) == 0) + { + if (I->Items == nullptr) + return I->Name; + ++existing; + } + +#ifdef _SC_NPROCESSORS_ONLN + long cpuCount = sysconf(_SC_NPROCESSORS_ONLN) * 2; +#else + long cpuCount = 10; +#endif + cpuCount = _config->FindI("Acquire::QueueHost::Limit", cpuCount); + + if (cpuCount <= 0 || existing < cpuCount) + strprintf(FullQueueName, "%s%ld", AccessSchema.c_str(), existing); + else + { + long const randomQueue = random() % cpuCount; + strprintf(FullQueueName, "%s%ld", AccessSchema.c_str(), randomQueue); + } + + if (Debug) + clog << "Chose random queue " << FullQueueName << " for " << Uri << endl; + } else + { + FullQueueName = AccessSchema + U.Host; + } unsigned int Instances = 0, SchemaLength = AccessSchema.length(); Queue *I = Queues; @@ -428,20 +462,30 @@ void pkgAcquire::SetFds(int &Fd,fd_set *RSet,fd_set *WSet) } } /*}}}*/ -// Acquire::RunFds - Deal with active FDs /*{{{*/ +// Acquire::RunFds - compatibility remove on next abi/api break /*{{{*/ +void pkgAcquire::RunFds(fd_set *RSet,fd_set *WSet) +{ + RunFdsSane(RSet, WSet); +} + /*}}}*/ +// Acquire::RunFdsSane - Deal with active FDs /*{{{*/ // --------------------------------------------------------------------- /* Dispatch active FDs over to the proper workers. It is very important that a worker never be erased while this is running! The queue class should never erase a worker except during shutdown processing. */ -void pkgAcquire::RunFds(fd_set *RSet,fd_set *WSet) +bool pkgAcquire::RunFdsSane(fd_set *RSet,fd_set *WSet) { + bool Res = true; + for (Worker *I = Workers; I != 0; I = I->NextAcquire) { if (I->InFd >= 0 && FD_ISSET(I->InFd,RSet) != 0) - I->InFdReady(); + Res &= I->InFdReady(); if (I->OutFd >= 0 && FD_ISSET(I->OutFd,WSet) != 0) - I->OutFdReady(); + Res &= I->OutFdReady(); } + + return Res; } /*}}}*/ // Acquire::Run - Run the fetch sequence /*{{{*/ @@ -497,7 +541,11 @@ static void CheckDropPrivsMustBeDisabled(pkgAcquire const &Fetcher) struct passwd const * const pw = getpwnam(SandboxUser.c_str()); if (pw == NULL) + { + _error->Warning(_("No sandbox user '%s' on the system, can not drop privileges"), SandboxUser.c_str()); + _config->Set("APT::Sandbox::User", ""); return; + } gid_t const old_euid = geteuid(); gid_t const old_egid = getegid(); @@ -525,7 +573,7 @@ static void CheckDropPrivsMustBeDisabled(pkgAcquire const &Fetcher) I != Fetcher.ItemsEnd(); ++I) { // no need to drop privileges for a complete file - if ((*I)->Complete == true) + if ((*I)->Complete == true || (*I)->Status != pkgAcquire::Item::StatIdle) continue; // if destination file is inaccessible all hope is lost for privilege dropping @@ -604,7 +652,8 @@ pkgAcquire::RunResult pkgAcquire::Run(int PulseIntervall) break; } - RunFds(&RFds,&WFds); + if(RunFdsSane(&RFds,&WFds) == false) + break; // Timeout, notify the log class if (Res == 0 || (Log != 0 && Log->Update == true)) @@ -688,6 +737,7 @@ bool pkgAcquire::Clean(string Dir) // Skip some files.. if (strcmp(Dir->d_name,"lock") == 0 || strcmp(Dir->d_name,"partial") == 0 || + strcmp(Dir->d_name,"lost+found") == 0 || strcmp(Dir->d_name,".") == 0 || strcmp(Dir->d_name,"..") == 0) continue; @@ -714,7 +764,7 @@ bool pkgAcquire::Clean(string Dir) /* This is the total number of bytes needed */ APT_PURE unsigned long long pkgAcquire::TotalNeeded() { - return std::accumulate(ItemsBegin(), ItemsEnd(), 0, + return std::accumulate(ItemsBegin(), ItemsEnd(), 0llu, [](unsigned long long const T, Item const * const I) { return T + I->FileSize; }); @@ -725,7 +775,7 @@ APT_PURE unsigned long long pkgAcquire::TotalNeeded() /* This is the number of bytes that is not local */ APT_PURE unsigned long long pkgAcquire::FetchNeeded() { - return std::accumulate(ItemsBegin(), ItemsEnd(), 0, + return std::accumulate(ItemsBegin(), ItemsEnd(), 0llu, [](unsigned long long const T, Item const * const I) { if (I->Local == false) return T + I->FileSize; @@ -739,7 +789,7 @@ APT_PURE unsigned long long pkgAcquire::FetchNeeded() /* This is the number of bytes that is not local */ APT_PURE unsigned long long pkgAcquire::PartialPresent() { - return std::accumulate(ItemsBegin(), ItemsEnd(), 0, + return std::accumulate(ItemsBegin(), ItemsEnd(), 0llu, [](unsigned long long const T, Item const * const I) { if (I->Local == false) return T + I->PartialSize; @@ -803,9 +853,8 @@ bool pkgAcquire::Queue::Enqueue(ItemDesc &Item) { QItem **I = &Items; // move to the end of the queue and check for duplicates here - HashStringList const hsl = Item.Owner->GetExpectedHashes(); for (; *I != 0; I = &(*I)->Next) - if (Item.URI == (*I)->URI || hsl == (*I)->Owner->GetExpectedHashes()) + if (Item.URI == (*I)->URI) { if (_config->FindB("Debug::pkgAcquire::Worker",false) == true) std::cerr << " @ Queue: Action combined for " << Item.URI << " and " << (*I)->URI << std::endl; @@ -1094,11 +1143,11 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) CurrentBytes = 0; TotalItems = 0; CurrentItems = 0; - + // Compute the total number of bytes to fetch unsigned int Unknown = 0; unsigned int Count = 0; - bool UnfetchedReleaseFiles = false; + bool ExpectAdditionalItems = false; for (pkgAcquire::ItemCIterator I = Owner->ItemsBegin(); I != Owner->ItemsEnd(); ++I, ++Count) @@ -1106,17 +1155,10 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) TotalItems++; if ((*I)->Status == pkgAcquire::Item::StatDone) ++CurrentItems; - - // Totally ignore local items - if ((*I)->Local == true) - continue; - - // see if the method tells us to expect more - TotalItems += (*I)->ExpectedAdditionalItems; - // check if there are unfetched Release files - if ((*I)->Complete == false && (*I)->ExpectedAdditionalItems > 0) - UnfetchedReleaseFiles = true; + // do we expect to acquire more files than we know of yet? + if ((*I)->ExpectedAdditionalItems > 0) + ExpectAdditionalItems = true; TotalBytes += (*I)->FileSize; if ((*I)->Complete == true) @@ -1124,7 +1166,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) if ((*I)->FileSize == 0 && (*I)->Complete == false) ++Unknown; } - + // Compute the current completion unsigned long long ResumeSize = 0; for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0; @@ -1152,12 +1194,6 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) if (CurrentBytes > TotalBytes) CurrentBytes = TotalBytes; - // debug - if (_config->FindB("Debug::acquire::progress", false) == true) - std::clog << " Bytes: " - << SizeToStr(CurrentBytes) << " / " << SizeToStr(TotalBytes) - << std::endl; - // Compute the CPS struct timeval NewTime; gettimeofday(&NewTime,0); @@ -1179,12 +1215,27 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) double const OldPercent = Percent; // calculate the percentage, if we have too little data assume 1% - if (TotalBytes > 0 && UnfetchedReleaseFiles) + if (ExpectAdditionalItems) Percent = 0; else // use both files and bytes because bytes can be unreliable Percent = (0.8 * (CurrentBytes/float(TotalBytes)*100.0) + 0.2 * (CurrentItems/float(TotalItems)*100.0)); + + // debug + if (_config->FindB("Debug::acquire::progress", false) == true) + { + std::clog + << "[" + << std::setw(5) << std::setprecision(4) << std::showpoint << Percent + << "]" + << " Bytes: " + << SizeToStr(CurrentBytes) << " / " << SizeToStr(TotalBytes) + << " # Files: " + << CurrentItems << " / " << TotalItems + << std::endl; + } + double const DiffPercent = Percent - OldPercent; if (DiffPercent < 0.001 && _config->FindB("Acquire::Progress::Diffpercent", false) == true) return true; @@ -1207,13 +1258,9 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) snprintf(msg,sizeof(msg), _("Retrieving file %li of %li"), i, TotalItems); // build the status str - status << "dlstatus:" << i - << ":" << std::setprecision(3) << Percent - << ":" << msg - << endl; - - std::string const dlstatus = status.str(); - FileFd::Write(fd, dlstatus.c_str(), dlstatus.size()); + std::string dlstatus; + strprintf(dlstatus, "dlstatus:%ld:%.4f:%s\n", i, Percent, msg); + FileFd::Write(fd, dlstatus.data(), dlstatus.size()); } return true;