From 2d11135a1b8e8ee0a21c7932d7ce08a89b354784 Mon Sep 17 00:00:00 2001 From: Arch Librarian Date: Mon, 20 Sep 2004 16:53:34 +0000 Subject: Support for memory-only caching Author: jgg Date: 1999-04-18 06:36:36 GMT Support for memory-only caching --- apt-pkg/cachefile.cc | 96 +++++++++++++++++++ apt-pkg/cachefile.h | 48 ++++++++++ apt-pkg/contrib/mmap.cc | 67 ++++++++++---- apt-pkg/contrib/mmap.h | 15 +-- apt-pkg/deb/dpkginit.cc | 6 +- apt-pkg/makefile | 4 +- apt-pkg/pkgcachegen.cc | 242 +++++++++++++++++++++++++++++++++++++----------- apt-pkg/pkgcachegen.h | 4 +- cmdline/apt-get.cc | 84 +++++------------ 9 files changed, 421 insertions(+), 145 deletions(-) create mode 100644 apt-pkg/cachefile.cc create mode 100644 apt-pkg/cachefile.h diff --git a/apt-pkg/cachefile.cc b/apt-pkg/cachefile.cc new file mode 100644 index 000000000..285eb310f --- /dev/null +++ b/apt-pkg/cachefile.cc @@ -0,0 +1,96 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cachefile.cc,v 1.1 1999/04/18 06:36:36 jgg Exp $ +/* ###################################################################### + + CacheFile - Simple wrapper class for opening, generating and whatnot + + This class implements a simple 2 line mechanism to open various sorts + of caches. It can operate as root, as not root, show progress and so on, + it transparently handles everything necessary. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/cachefile.h" +#endif + +#include +#include +#include +#include +#include + /*}}}*/ + +// CacheFile::CacheFile - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgCacheFile::pkgCacheFile() : Map(0), Cache(0), Lock() +{ +} + /*}}}*/ +// CacheFile::~CacheFile - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgCacheFile::~pkgCacheFile() +{ + delete Cache; + delete Map; + delete Lock; +} + /*}}}*/ +// CacheFile::Open - Open the cache files, creating if necessary /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCacheFile::Open(OpProgress &Progress,bool WithLock) +{ + if (WithLock == true) + Lock = new pkgDpkgLock; + + if (_error->PendingError() == true) + return false; + + // Read the source list + pkgSourceList List; + if (List.ReadMainList() == false) + return _error->Error("The list of sources could not be read."); + + /* Build all of the caches, using the cache files if we are locking + (ie as root) */ + if (WithLock == true) + { + pkgMakeStatusCache(List,Progress); + Progress.Done(); + if (_error->PendingError() == true) + return _error->Error("The package lists or status file could not be parsed or opened."); + if (_error->empty() == false) + _error->Warning("You may want to run apt-get update to correct theses missing files"); + + // Open the cache file + FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly); + if (_error->PendingError() == true) + return false; + + Map = new MMap(File,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true) + return false; + } + else + { + Map = pkgMakeStatusCacheMem(List,Progress); + Progress.Done(); + if (Map == 0) + return false; + } + + // Create the dependency cache + Cache = new pkgDepCache(*Map,Progress); + if (_error->PendingError() == true) + return false; + + Progress.Done(); + + return true; +} + /*}}}*/ diff --git a/apt-pkg/cachefile.h b/apt-pkg/cachefile.h new file mode 100644 index 000000000..23bd4008b --- /dev/null +++ b/apt-pkg/cachefile.h @@ -0,0 +1,48 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cachefile.h,v 1.1 1999/04/18 06:36:36 jgg Exp $ +/* ###################################################################### + + CacheFile - Simple wrapper class for opening, generating and whatnot + + This class implements a simple 2 line mechanism to open various sorts + of caches. It can operate as root, as not root, show progress and so on, + it transparently handles everything necessary. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_CACHEFILE_H +#define PKGLIB_CACHEFILE_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/cachefile.h" +#endif + +#include +#include + +class pkgCacheFile +{ + protected: + + MMap *Map; + pkgDepCache *Cache; + pkgDpkgLock *Lock; + + public: + + // We look pretty much exactly like a pointer to a dep cache + inline operator pkgDepCache &() {return *Cache;}; + inline pkgDepCache *operator ->() {return Cache;}; + inline pkgDepCache &operator *() {return *Cache;}; + + // Release the dpkg status lock + inline void ReleaseLock() {Lock->Close();}; + + bool Open(OpProgress &Progress,bool WithLock = true); + + pkgCacheFile(); + ~pkgCacheFile(); +}; + +#endif diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index 7a5065ffb..098c61ca6 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: mmap.cc,v 1.14 1999/03/18 04:32:46 jgg Exp $ +// $Id: mmap.cc,v 1.15 1999/04/18 06:36:36 jgg Exp $ /* ###################################################################### MMap Class - Provides 'real' mmap or a faked mmap using read(). @@ -38,11 +38,19 @@ // MMap::MMap - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -MMap::MMap(FileFd &F,unsigned long Flags) : Fd(F), Flags(Flags), iSize(0), +MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0), Base(0) { if ((Flags & NoImmMap) != NoImmMap) - Map(); + Map(F); +} + /*}}}*/ +// MMap::MMap - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +MMap::MMap(unsigned long Flags) : Flags(Flags), iSize(0), + Base(0) +{ } /*}}}*/ // MMap::~MMap - Destructor /*{{{*/ @@ -50,13 +58,13 @@ MMap::MMap(FileFd &F,unsigned long Flags) : Fd(F), Flags(Flags), iSize(0), /* */ MMap::~MMap() { - Close(true); + Close(); } /*}}}*/ // MMap::Map - Perform the mapping /*{{{*/ // --------------------------------------------------------------------- /* */ -bool MMap::Map() +bool MMap::Map(FileFd &Fd) { iSize = Fd.Size(); @@ -82,11 +90,11 @@ bool MMap::Map() // MMap::Close - Close the map /*{{{*/ // --------------------------------------------------------------------- /* */ -bool MMap::Close(bool DoClose, bool DoSync) +bool MMap::Close(bool DoSync) { - if (Fd.IsOpen() == false) + if ((Flags & UnMapped) == UnMapped || Base == 0 || iSize == 0) return true; - + if (DoSync == true) Sync(); @@ -94,8 +102,6 @@ bool MMap::Close(bool DoClose, bool DoSync) _error->Warning("Unable to munmap"); iSize = 0; - if (DoClose == true) - Fd.Close(); return true; } /*}}}*/ @@ -105,6 +111,9 @@ bool MMap::Close(bool DoClose, bool DoSync) not return till all IO is complete */ bool MMap::Sync() { + if ((Flags & UnMapped) == UnMapped) + return true; + #ifdef _POSIX_SYNCHRONIZED_IO if ((Flags & ReadOnly) != ReadOnly) if (msync((char *)Base,iSize,MS_SYNC) != 0) @@ -118,6 +127,9 @@ bool MMap::Sync() /* */ bool MMap::Sync(unsigned long Start,unsigned long Stop) { + if ((Flags & UnMapped) == UnMapped) + return true; + #ifdef _POSIX_SYNCHRONIZED_IO unsigned long PSize = sysconf(_SC_PAGESIZE); if ((Flags & ReadOnly) != ReadOnly) @@ -132,30 +144,49 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop) // --------------------------------------------------------------------- /* */ DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) : - MMap(F,Flags | NoImmMap), WorkSpace(WorkSpace) + MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(WorkSpace) { if (_error->PendingError() == true) return; - unsigned long EndOfFile = Fd.Size(); - Fd.Seek(WorkSpace); + unsigned long EndOfFile = Fd->Size(); + Fd->Seek(WorkSpace); char C = 0; - Fd.Write(&C,sizeof(C)); - Map(); + Fd->Write(&C,sizeof(C)); + Map(F); iSize = EndOfFile; } /*}}}*/ +// DynamicMMap::DynamicMMap - Constructor for a non-file backed map /*{{{*/ +// --------------------------------------------------------------------- +/* This is just a fancy malloc really.. */ +DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long WorkSpace) : + MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace) +{ + if (_error->PendingError() == true) + return; + + Base = new unsigned char[WorkSpace]; + iSize = 0; +} + /*}}}*/ // DynamicMMap::~DynamicMMap - Destructor /*{{{*/ // --------------------------------------------------------------------- /* We truncate the file to the size of the memory data set */ DynamicMMap::~DynamicMMap() { + if (Fd == 0) + { + delete [] (unsigned char *)Base; + return; + } + unsigned long EndOfFile = iSize; Sync(); iSize = WorkSpace; - Close(false,false); - ftruncate(Fd.Fd(),EndOfFile); - Fd.Close(); + Close(false); + ftruncate(Fd->Fd(),EndOfFile); + Fd->Close(); } /*}}}*/ // DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space /*{{{*/ diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h index 3cb6c6468..0c11d3202 100644 --- a/apt-pkg/contrib/mmap.h +++ b/apt-pkg/contrib/mmap.h @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: mmap.h,v 1.8 1999/01/18 06:20:08 jgg Exp $ +// $Id: mmap.h,v 1.9 1999/04/18 06:36:36 jgg Exp $ /* ###################################################################### MMap Class - Provides 'real' mmap or a faked mmap using read(). @@ -36,17 +36,17 @@ class MMap { protected: - FileFd &Fd; - unsigned long Flags; + unsigned long Flags; unsigned long iSize; void *Base; - bool Map(); - bool Close(bool DoClose = true,bool DoSync = true); + bool Map(FileFd &Fd); + bool Close(bool DoSync = true); public: - enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2)}; + enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2), + UnMapped = (1<<3)}; // Simple accessors inline operator void *() {return Base;}; @@ -58,6 +58,7 @@ class MMap bool Sync(unsigned long Start,unsigned long Stop); MMap(FileFd &F,unsigned long Flags); + MMap(unsigned long Flags); virtual ~MMap(); }; @@ -75,6 +76,7 @@ class DynamicMMap : public MMap protected: + FileFd *Fd; unsigned long WorkSpace; Pool *Pools; unsigned int PoolCount; @@ -89,6 +91,7 @@ class DynamicMMap : public MMap void UsePools(Pool &P,unsigned int Count) {Pools = &P; PoolCount = Count;}; DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace = 2*1024*1024); + DynamicMMap(unsigned long Flags,unsigned long WorkSpace = 2*1024*1024); virtual ~DynamicMMap(); }; diff --git a/apt-pkg/deb/dpkginit.cc b/apt-pkg/deb/dpkginit.cc index 095156d0d..518d18f59 100644 --- a/apt-pkg/deb/dpkginit.cc +++ b/apt-pkg/deb/dpkginit.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: dpkginit.cc,v 1.1 1998/11/23 07:03:10 jgg Exp $ +// $Id: dpkginit.cc,v 1.2 1999/04/18 06:36:36 jgg Exp $ /* ###################################################################### DPKG init - Initialize the dpkg stuff @@ -54,8 +54,8 @@ bool pkgDpkgLock::GetLock() string AdminDir = flNotFile(_config->Find("Dir::State::status")); LockFD = ::GetLock(AdminDir + "lock"); if (LockFD == -1) - return _error->Errno("Open","Unable to lock the administration directory " - "%s, are you root?",AdminDir.c_str()); + return _error->Error("Unable to lock the administration directory, " + "are you root?"); // Check for updates.. (dirty) string File = AdminDir + "updates/"; diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 14ed1dea5..80bfbdcf3 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -25,7 +25,7 @@ SOURCE+= pkgcache.cc version.cc fileutl.cc pkgcachegen.cc depcache.cc \ orderlist.cc tagfile.cc sourcelist.cc packagemanager.cc \ pkgrecords.cc algorithms.cc acquire.cc acquire-item.cc \ acquire-worker.cc acquire-method.cc init.cc clean.cc \ - srcrecords.cc + srcrecords.cc cachefile.cc # Source code for the debian specific components SOURCE+= deb/deblistparser.cc deb/debrecords.cc deb/dpkgpm.cc deb/dpkginit.cc \ @@ -38,7 +38,7 @@ HEADERS = algorithms.h depcache.h mmap.h pkgcachegen.h cacheiterators.h \ version.h progress.h pkgrecords.h debrecords.h cmndline.h \ acquire.h acquire-worker.h acquire-item.h acquire-method.h md5.h \ dpkgpm.h dpkginit.h cdromutl.h strutl.h clean.h srcrecords.h \ - debsrcrecords.h + debsrcrecords.h cachefile.h HEADERS := $(addprefix apt-pkg/,$(HEADERS)) diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index d7e830df5..ee65c94d1 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: pkgcachegen.cc,v 1.34 1999/04/04 01:33:09 jgg Exp $ +// $Id: pkgcachegen.cc,v 1.35 1999/04/18 06:36:36 jgg Exp $ /* ###################################################################### Package Cache Generator - Generator for the cache structure. @@ -615,6 +615,70 @@ static bool pkgMergeStatus(OpProgress &Progress,pkgCacheGenerator &Gen, Progress.Progress(Pkg.Size()); } + return true; +} + /*}}}*/ +// GenerateSrcCache - Write the source package lists to the map /*{{{*/ +// --------------------------------------------------------------------- +/* This puts the source package cache into the given generator. */ +bool pkgGenerateSrcCache(pkgSourceList &List,OpProgress &Progress, + pkgCacheGenerator &Gen, + unsigned long &CurrentSize,unsigned long TotalSize) +{ + string ListDir = _config->FindDir("Dir::State::lists"); + + // Prepare the progress indicator + TotalSize = 0; + struct stat Buf; + for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) + { + string File = ListDir + URItoFileName(I->PackagesURI()); + if (stat(File.c_str(),&Buf) != 0) + continue; + TotalSize += Buf.st_size; + } + + if (pkgAddSourcesSize(TotalSize) == false) + return false; + + // Generate the pkg source cache + CurrentSize = 0; + for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) + { + // Only cache deb source types. + if (I->Type != pkgSourceList::Item::Deb) + continue; + + string File = ListDir + URItoFileName(I->PackagesURI()); + + if (FileExists(File) == false) + continue; + + FileFd Pkg(File,FileFd::ReadOnly); + debListParser Parser(Pkg); + Progress.OverallProgress(CurrentSize,TotalSize,Pkg.Size(),"Reading Package Lists"); + if (_error->PendingError() == true) + return _error->Error("Problem opening %s",File.c_str()); + CurrentSize += Pkg.Size(); + + Progress.SubProgress(0,I->PackagesInfo()); + if (Gen.SelectFile(File) == false) + return _error->Error("Problem with SelectFile %s",File.c_str()); + + if (Gen.MergeList(Parser) == false) + return _error->Error("Problem with MergeList %s",File.c_str()); + + // Check the release file + string RFile = ListDir + URItoFileName(I->ReleaseURI()); + if (FileExists(RFile) == true) + { + FileFd Rel(RFile,FileFd::ReadOnly); + if (_error->PendingError() == true) + return false; + Parser.LoadReleaseInfo(Gen.GetCurFile(),Rel); + } + } + return true; } /*}}}*/ @@ -634,67 +698,18 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress) if (SrcOk == false) { string SCacheFile = _config->FindFile("Dir::Cache::srcpkgcache"); - string ListDir = _config->FindDir("Dir::State::lists"); FileFd SCacheF(SCacheFile,FileFd::WriteEmpty); FileFd CacheF(CacheFile,FileFd::WriteEmpty); DynamicMMap Map(CacheF,MMap::Public); if (_error->PendingError() == true) return false; - + pkgCacheGenerator Gen(Map,Progress); - - // Prepare the progress indicator + unsigned long CurrentSize = 0; unsigned long TotalSize = 0; - struct stat Buf; - for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) - { - string File = ListDir + URItoFileName(I->PackagesURI()); - if (stat(File.c_str(),&Buf) != 0) - continue; - TotalSize += Buf.st_size; - } - - if (pkgAddSourcesSize(TotalSize) == false) + if (pkgGenerateSrcCache(List,Progress,Gen,CurrentSize,TotalSize) == false) return false; - // Generate the pkg source cache - unsigned long CurrentSize = 0; - for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) - { - // Only cache deb source types. - if (I->Type != pkgSourceList::Item::Deb) - continue; - - string File = ListDir + URItoFileName(I->PackagesURI()); - - if (FileExists(File) == false) - continue; - - FileFd Pkg(File,FileFd::ReadOnly); - debListParser Parser(Pkg); - Progress.OverallProgress(CurrentSize,TotalSize,Pkg.Size(),"Reading Package Lists"); - if (_error->PendingError() == true) - return _error->Error("Problem opening %s",File.c_str()); - CurrentSize += Pkg.Size(); - - Progress.SubProgress(0,I->PackagesInfo()); - if (Gen.SelectFile(File) == false) - return _error->Error("Problem with SelectFile %s",File.c_str()); - - if (Gen.MergeList(Parser) == false) - return _error->Error("Problem with MergeList %s",File.c_str()); - - // Check the release file - string RFile = ListDir + URItoFileName(I->ReleaseURI()); - if (FileExists(RFile) == true) - { - FileFd Rel(RFile,FileFd::ReadOnly); - if (_error->PendingError() == true) - return false; - Parser.LoadReleaseInfo(Gen.GetCurFile(),Rel); - } - } - // Write the src cache Gen.GetCache().HeaderP->Dirty = false; if (SCacheF.Write(Map.Data(),Map.Size()) == false) @@ -736,3 +751,124 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress) return pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize); } /*}}}*/ +// MakeStatusCacheMem - Returns a map for the status cache /*{{{*/ +// --------------------------------------------------------------------- +/* This creates a map object for the status cache. If the process has write + access to the caches then it is the same as MakeStatusCache, otherwise it + creates a memory block and puts the cache in there. */ +MMap *pkgMakeStatusCacheMem(pkgSourceList &List,OpProgress &Progress) +{ + /* If the cache file is writeable this is just a wrapper for + MakeStatusCache */ + string CacheFile = _config->FindFile("Dir::Cache::pkgcache"); + bool Writeable = access(CacheFile.c_str(),W_OK) == 0; + if (Writeable == true) + { + if (pkgMakeStatusCache(List,Progress) == false) + return 0; + + // Open the cache file + FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly); + if (_error->PendingError() == true) + return 0; + + MMap *Map = new MMap(File,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true) + { + delete Map; + return 0; + } + return Map; + } + + // Mostly from MakeStatusCache.. + Progress.OverallProgress(0,1,1,"Reading Package Lists"); + + bool SrcOk = pkgSrcCacheCheck(List); + bool PkgOk = SrcOk && pkgPkgCacheCheck(CacheFile); + + // Rebuild the source and package caches + if (SrcOk == false) + { + DynamicMMap *Map = new DynamicMMap(MMap::Public); + if (_error->PendingError() == true) + { + delete Map; + return 0; + } + + pkgCacheGenerator Gen(*Map,Progress); + unsigned long CurrentSize = 0; + unsigned long TotalSize = 0; + if (pkgGenerateSrcCache(List,Progress,Gen,CurrentSize,TotalSize) == false) + { + delete Map; + return 0; + } + + // Merge in the source caches + if (pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize) == false) + { + delete Map; + return 0; + } + + return Map; + } + + if (PkgOk == true) + { + Progress.OverallProgress(1,1,1,"Reading Package Lists"); + + // Open the cache file + FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly); + if (_error->PendingError() == true) + return 0; + + MMap *Map = new MMap(File,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true) + { + delete Map; + return 0; + } + return Map; + } + + // We use the source cache to generate the package cache + string SCacheFile = _config->FindFile("Dir::Cache::srcpkgcache"); + FileFd SCacheF(SCacheFile,FileFd::ReadOnly); + DynamicMMap *Map = new DynamicMMap(MMap::Public); + if (_error->PendingError() == true) + { + delete Map; + return 0; + } + + // Preload the map with the source cache + if (SCacheF.Read((unsigned char *)Map->Data() + Map->RawAllocate(SCacheF.Size()), + SCacheF.Size()) == false) + { + delete Map; + return 0; + } + + pkgCacheGenerator Gen(*Map,Progress); + + // Compute the progress + unsigned long TotalSize = 0; + if (pkgAddSourcesSize(TotalSize) == false) + { + delete Map; + return 0; + } + + unsigned long CurrentSize = 0; + if (pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize) == false) + { + delete Map; + return 0; + } + + return Map; +} + /*}}}*/ diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index 8ffb277c6..66a991371 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: pkgcachegen.h,v 1.12 1999/02/23 06:46:24 jgg Exp $ +// $Id: pkgcachegen.h,v 1.13 1999/04/18 06:36:36 jgg Exp $ /* ###################################################################### Package Cache Generator - Generator for the cache structure. @@ -28,6 +28,7 @@ class pkgSourceList; class OpProgress; +class MMap; class pkgCacheGenerator { @@ -71,6 +72,7 @@ class pkgCacheGenerator bool pkgSrcCacheCheck(pkgSourceList &List); bool pkgPkgCacheCheck(string CacheFile); bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress); +MMap *pkgMakeStatusCacheMem(pkgSourceList &List,OpProgress &Progress); // This is the abstract package list parser class. class pkgCacheGenerator::ListParser diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index a2c013206..07ba19f18 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: apt-get.cc,v 1.51 1999/04/12 02:25:25 jgg Exp $ +// $Id: apt-get.cc,v 1.52 1999/04/18 06:36:36 jgg Exp $ /* ###################################################################### apt-get - Cover for dpkg @@ -30,15 +30,14 @@ #include #include #include -#include #include #include #include -#include #include #include #include #include +#include #include @@ -372,70 +371,27 @@ void Stats(ostream &out,pkgDepCache &Dep) // class CacheFile - Cover class for some dependency cache functions /*{{{*/ // --------------------------------------------------------------------- /* */ -class CacheFile +class CacheFile : public pkgCacheFile { public: - FileFd *File; - MMap *Map; - pkgDepCache *Cache; - pkgDpkgLock Lock; - - inline operator pkgDepCache &() {return *Cache;}; - inline pkgDepCache *operator ->() {return Cache;}; - inline pkgDepCache &operator *() {return *Cache;}; - - bool Open(bool AllowBroken = false); - CacheFile() : File(0), Map(0), Cache(0) {}; - ~CacheFile() + bool CheckDeps(bool AllowBroken = false); + bool Open(bool WithLock = true) { - delete Cache; - delete Map; - delete File; - } + OpTextProgress Prog(*_config); + return pkgCacheFile::Open(Prog,WithLock); + }; }; /*}}}*/ // CacheFile::Open - Open the cache file /*{{{*/ // --------------------------------------------------------------------- /* This routine generates the caches and then opens the dependency cache and verifies that the system is OK. */ -bool CacheFile::Open(bool AllowBroken) +bool CacheFile::CheckDeps(bool AllowBroken) { if (_error->PendingError() == true) return false; - - // Create a progress class - OpTextProgress Progress(*_config); - - // Read the source list - pkgSourceList List; - if (List.ReadMainList() == false) - return _error->Error("The list of sources could not be read."); - - // Build all of the caches - pkgMakeStatusCache(List,Progress); - if (_error->PendingError() == true) - return _error->Error("The package lists or status file could not be parsed or opened."); - if (_error->empty() == false) - _error->Warning("You may want to run apt-get update to correct theses missing files"); - - Progress.Done(); - - // Open the cache file - File = new FileFd(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly); - if (_error->PendingError() == true) - return false; - - Map = new MMap(*File,MMap::Public | MMap::ReadOnly); - if (_error->PendingError() == true) - return false; - - Cache = new pkgDepCache(*Map,Progress); - if (_error->PendingError() == true) - return false; - Progress.Done(); - // Check that the system is OK if (Cache->DelCount() != 0 || Cache->InstCount() != 0) return _error->Error("Internal Error, non-zero counts"); @@ -676,7 +632,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey = return _error->Error("Aborting Install."); } - Cache.Lock.Close(); + Cache.ReleaseLock(); return PM.DoInstall(); } /*}}}*/ @@ -724,7 +680,7 @@ bool DoUpdate(CommandLine &) // Prepare the cache. CacheFile Cache; - if (Cache.Open() == false) + if (Cache.Open() == false || Cache.CheckDeps() == false) return false; return true; @@ -737,7 +693,7 @@ bool DoUpdate(CommandLine &) bool DoUpgrade(CommandLine &CmdL) { CacheFile Cache; - if (Cache.Open() == false) + if (Cache.Open() == false || Cache.CheckDeps() == false) return false; // Do the upgrade @@ -756,7 +712,7 @@ bool DoUpgrade(CommandLine &CmdL) bool DoInstall(CommandLine &CmdL) { CacheFile Cache; - if (Cache.Open(CmdL.FileSize() != 1) == false) + if (Cache.Open() == false || Cache.CheckDeps(CmdL.FileSize() != 1) == false) return false; // Enter the special broken fixing mode if the user specified arguments @@ -949,7 +905,7 @@ bool DoInstall(CommandLine &CmdL) bool DoDistUpgrade(CommandLine &CmdL) { CacheFile Cache; - if (Cache.Open() == false) + if (Cache.Open() == false || Cache.CheckDeps() == false) return false; c0out << "Calculating Upgrade... " << flush; @@ -971,7 +927,7 @@ bool DoDistUpgrade(CommandLine &CmdL) bool DoDSelectUpgrade(CommandLine &CmdL) { CacheFile Cache; - if (Cache.Open() == false) + if (Cache.Open() == false || Cache.CheckDeps() == false) return false; // Install everything with the install flag set @@ -1066,7 +1022,7 @@ class LogCleaner : public pkgArchiveCleaner bool DoAutoClean(CommandLine &CmdL) { CacheFile Cache; - if (Cache.Open(true) == false) + if (Cache.Open() == false) return false; LogCleaner Cleaner; @@ -1083,19 +1039,23 @@ bool DoCheck(CommandLine &CmdL) { CacheFile Cache; Cache.Open(); + Cache.CheckDeps(); return true; } /*}}}*/ // DoSource - Fetch a source archive /*{{{*/ // --------------------------------------------------------------------- -/* */ +/* Fetch souce packages */ bool DoSource(CommandLine &CmdL) { CacheFile Cache; - if (Cache.Open(true) == false) + if (Cache.Open(false) == false) return false; + if (CmdL.FileSize() <= 1) + return _error->Error("Must specify at least one package to fetch source for"); + // Read the source list pkgSourceList List; if (List.ReadMainList() == false) -- cgit v1.2.3