LTP GCOV extension - code coverage report
Current view: directory - src/libstore - store-api.hh
Test: app.info
Date: 2008-11-20 Instrumented lines: 22
Code covered: 54.5 % Executed lines: 12

       1                 : #ifndef __STOREAPI_H
       2                 : #define __STOREAPI_H
       3                 : 
       4                 : #include <string>
       5                 : #include <map>
       6                 : 
       7                 : #include <boost/shared_ptr.hpp>
       8                 : 
       9                 : #include "hash.hh"
      10                 : #include "serialise.hh"
      11                 : 
      12                 : 
      13                 : namespace nix {
      14                 : 
      15                 : 
      16                 : typedef std::map<Path, Path> Roots;
      17                 : 
      18                 : 
      19                 : 
      20                 : 
      21                 : struct GCOptions
      22              23 : {
      23                 :     /* Garbage collector operation:
      24                 : 
      25                 :        - `gcReturnRoots': find and return the set of roots for the
      26                 :          garbage collector.  These are the store paths symlinked to in
      27                 :          the `gcroots' directory.
      28                 : 
      29                 :        - `gcReturnLive': return the set of paths reachable from
      30                 :          (i.e. in the closure of) the roots.
      31                 : 
      32                 :        - `gcReturnDead': return the set of paths not reachable from
      33                 :          the roots.
      34                 : 
      35                 :        - `gcDeleteDead': actually delete the latter set.
      36                 : 
      37                 :        - `gcDeleteSpecific': delete the paths listed in
      38                 :           `pathsToDelete', insofar as they are not reachable.
      39                 :     */
      40                 :     typedef enum {
      41                 :         gcReturnRoots,
      42                 :         gcReturnLive,
      43                 :         gcReturnDead,
      44                 :         gcDeleteDead,
      45                 :         gcDeleteSpecific,
      46                 :     } GCAction;
      47                 : 
      48                 :     GCAction action;
      49                 : 
      50                 :     /* If `ignoreLiveness' is set, then reachability from the roots is
      51                 :        ignored (dangerous!).  However, the paths must still be
      52                 :        unreferenced *within* the store (i.e., there can be no other
      53                 :        store paths that depend on them). */
      54                 :     bool ignoreLiveness;
      55                 : 
      56                 :     /* For `gcDeleteSpecific', the paths to delete. */
      57                 :     PathSet pathsToDelete;
      58                 : 
      59                 :     /* Stop after at least `maxFreed' bytes have been freed. */
      60                 :     unsigned long long maxFreed;
      61                 : 
      62                 :     /* Stop after the number of hard links to the Nix store directory
      63                 :        has dropped below `maxLinks'. */
      64                 :     unsigned int maxLinks;
      65                 : 
      66                 :     /* Delete paths in order of ascending last access time.  I.e.,
      67                 :        prefer deleting unrecently used paths.  Useful in conjunction
      68                 :        with `maxFreed' and `maxLinks' (or manual interruption).  The
      69                 :        access time of a path is defined as the highest atime of any
      70                 :        non-directory, non-symlink file under that path.  Directories
      71                 :        and symlinks are ignored because their atimes are frequently
      72                 :        mass-updated, e.g. by `locate'.  Note that optimiseStore()
      73                 :        somewhat reduces the usefulness of this option: it hard-links
      74                 :        regular files and symlink together, giving them a "shared"
      75                 :        atime. */
      76                 :     bool useAtime;
      77                 : 
      78                 :     /* Do not delete paths newer than `maxAtime'.  -1 means no age
      79                 :        limit. */
      80                 :     time_t maxAtime;
      81                 : 
      82                 :     GCOptions();
      83                 : };
      84                 : 
      85                 : 
      86                 : struct GCResults 
      87              23 : {
      88                 :     /* Depending on the action, the GC roots, or the paths that would
      89                 :        be or have been deleted. */
      90                 :     PathSet paths;
      91                 : 
      92                 :     /* For `gcReturnDead', `gcDeleteDead' and `gcDeleteSpecific', the
      93                 :        number of bytes that would be or was freed. */
      94                 :     unsigned long long bytesFreed;
      95                 : 
      96                 :     /* The number of file system blocks that would be or was freed. */
      97                 :     unsigned long long blocksFreed;
      98                 : 
      99              23 :     GCResults()
     100              23 :     {
     101              23 :         bytesFreed = 0;
     102              23 :         blocksFreed = 0;
     103              23 :     }
     104                 : };
     105                 : 
     106                 : 
     107                 : struct SubstitutablePathInfo
     108             798 : {
     109                 :     Path deriver;
     110                 :     PathSet references;
     111                 :     unsigned long long downloadSize; /* 0 = unknown or inapplicable */
     112                 : };
     113                 : 
     114                 : 
     115                 : class StoreAPI 
     116             512 : {
     117                 : public:
     118                 : 
     119             512 :     virtual ~StoreAPI() { }
     120                 : 
     121                 :     /* Checks whether a path is valid. */ 
     122                 :     virtual bool isValidPath(const Path & path) = 0;
     123                 : 
     124                 :     /* Query the set of valid paths. */
     125                 :     virtual PathSet queryValidPaths() = 0;
     126                 : 
     127                 :     /* Queries the hash of a valid path. */ 
     128                 :     virtual Hash queryPathHash(const Path & path) = 0;
     129                 : 
     130                 :     /* Queries the set of outgoing FS references for a store path.
     131                 :        The result is not cleared. */
     132                 :     virtual void queryReferences(const Path & path,
     133                 :         PathSet & references) = 0;
     134                 : 
     135                 :     /* Like queryReferences, but with self-references filtered out. */
     136               0 :     PathSet queryReferencesNoSelf(const Path & path)
     137                 :     {
     138               0 :         PathSet res;
     139               0 :         queryReferences(path, res);
     140               0 :         res.erase(path);
     141               0 :         return res;
     142                 :     }
     143                 : 
     144                 :     /* Queries the set of incoming FS references for a store path.
     145                 :        The result is not cleared. */
     146                 :     virtual void queryReferrers(const Path & path,
     147                 :         PathSet & referrers) = 0;
     148                 : 
     149                 :     /* Like queryReferrers, but with self-references filtered out. */
     150               0 :     PathSet queryReferrersNoSelf(const Path & path)
     151                 :     {
     152               0 :         PathSet res;
     153               0 :         queryReferrers(path, res);
     154               0 :         res.erase(path);
     155               0 :         return res;
     156                 :     }
     157                 : 
     158                 :     /* Query the deriver of a store path.  Return the empty string if
     159                 :        no deriver has been set. */
     160                 :     virtual Path queryDeriver(const Path & path) = 0;
     161                 : 
     162                 :     /* Query whether a path has substitutes. */
     163                 :     virtual bool hasSubstitutes(const Path & path) = 0;
     164                 : 
     165                 :     /* Query the references, deriver and download size of a
     166                 :        substitutable path. */
     167                 :     virtual bool querySubstitutablePathInfo(const Path & path,
     168                 :         SubstitutablePathInfo & info) = 0;
     169                 :     
     170                 :     /* Copy the contents of a path to the store and register the
     171                 :        validity the resulting path.  The resulting path is returned.
     172                 :        If `fixed' is true, then the output of a fixed-output
     173                 :        derivation is pre-loaded into the Nix store.  The function
     174                 :        object `filter' can be used to exclude files (see
     175                 :        libutil/archive.hh). */
     176                 :     virtual Path addToStore(const Path & srcPath, bool fixed = false,
     177                 :         bool recursive = false, string hashAlgo = "",
     178                 :         PathFilter & filter = defaultPathFilter) = 0;
     179                 : 
     180                 :     /* Like addToStore, but the contents written to the output path is
     181                 :        a regular file containing the given string. */
     182                 :     virtual Path addTextToStore(const string & suffix, const string & s,
     183                 :         const PathSet & references) = 0;
     184                 : 
     185                 :     /* Export a store path, that is, create a NAR dump of the store
     186                 :        path and append its references and its deriver.  Optionally, a
     187                 :        cryptographic signature (created by OpenSSL) of the preceding
     188                 :        data is attached. */
     189                 :     virtual void exportPath(const Path & path, bool sign,
     190                 :         Sink & sink) = 0;
     191                 : 
     192                 :     /* Import a NAR dump created by exportPath() into the Nix
     193                 :        store. */
     194                 :     virtual Path importPath(bool requireSignature, Source & source) = 0;
     195                 : 
     196                 :     /* Ensure that the output paths of the derivation are valid.  If
     197                 :        they are already valid, this is a no-op.  Otherwise, validity
     198                 :        can be reached in two ways.  First, if the output paths is
     199                 :        substitutable, then build the path that way.  Second, the
     200                 :        output paths can be created by running the builder, after
     201                 :        recursively building any sub-derivations. */
     202                 :     virtual void buildDerivations(const PathSet & drvPaths) = 0;
     203                 : 
     204                 :     /* Ensure that a path is valid.  If it is not currently valid, it
     205                 :        may be made valid by running a substitute (if defined for the
     206                 :        path). */
     207                 :     virtual void ensurePath(const Path & path) = 0;
     208                 : 
     209                 :     /* Add a store path as a temporary root of the garbage collector.
     210                 :        The root disappears as soon as we exit. */
     211                 :     virtual void addTempRoot(const Path & path) = 0;
     212                 : 
     213                 :     /* Add an indirect root, which is merely a symlink to `path' from
     214                 :        /nix/var/nix/gcroots/auto/<hash of `path'>.  `path' is supposed
     215                 :        to be a symlink to a store path.  The garbage collector will
     216                 :        automatically remove the indirect root when it finds that
     217                 :        `path' has disappeared. */
     218                 :     virtual void addIndirectRoot(const Path & path) = 0;
     219                 : 
     220                 :     /* Acquire the global GC lock, then immediately release it.  This
     221                 :        function must be called after registering a new permanent root,
     222                 :        but before exiting.  Otherwise, it is possible that a running
     223                 :        garbage collector doesn't see the new root and deletes the
     224                 :        stuff we've just built.  By acquiring the lock briefly, we
     225                 :        ensure that either:
     226                 : 
     227                 :        - The collector is already running, and so we block until the
     228                 :          collector is finished.  The collector will know about our
     229                 :          *temporary* locks, which should include whatever it is we
     230                 :          want to register as a permanent lock.
     231                 : 
     232                 :        - The collector isn't running, or it's just started but hasn't
     233                 :          acquired the GC lock yet.  In that case we get and release
     234                 :          the lock right away, then exit.  The collector scans the
     235                 :          permanent root and sees our's.
     236                 : 
     237                 :        In either case the permanent root is seen by the collector. */
     238                 :     virtual void syncWithGC() = 0;
     239                 : 
     240                 :     /* Find the roots of the garbage collector.  Each root is a pair
     241                 :        (link, storepath) where `link' is the path of the symlink
     242                 :        outside of the Nix store that point to `storePath'.  */
     243                 :     virtual Roots findRoots() = 0;
     244                 : 
     245                 :     /* Perform a garbage collection. */
     246                 :     virtual void collectGarbage(const GCOptions & options, GCResults & results) = 0;
     247                 : };
     248                 : 
     249                 : 
     250                 : /* !!! These should be part of the store API, I guess. */
     251                 : 
     252                 : /* Throw an exception if `path' is not directly in the Nix store. */
     253                 : void assertStorePath(const Path & path);
     254                 : 
     255                 : bool isInStore(const Path & path);
     256                 : bool isStorePath(const Path & path);
     257                 : 
     258                 : void checkStoreName(const string & name);
     259                 : 
     260                 : 
     261                 : /* Chop off the parts after the top-level store name, e.g.,
     262                 :    /nix/store/abcd-foo/bar => /nix/store/abcd-foo. */
     263                 : Path toStorePath(const Path & path);
     264                 : 
     265                 : 
     266                 : /* Follow symlinks until we end up with a path in the Nix store. */
     267                 : Path followLinksToStore(const Path & path);
     268                 : 
     269                 : 
     270                 : /* Same as followLinksToStore(), but apply toStorePath() to the
     271                 :    result. */
     272                 : Path followLinksToStorePath(const Path & path);
     273                 : 
     274                 : 
     275                 : /* Constructs a unique store path name. */
     276                 : Path makeStorePath(const string & type,
     277                 :     const Hash & hash, const string & suffix);
     278                 :     
     279                 : Path makeFixedOutputPath(bool recursive,
     280                 :     string hashAlgo, Hash hash, string name);
     281                 : 
     282                 : 
     283                 : /* This is the preparatory part of addToStore() and addToStoreFixed();
     284                 :    it computes the store path to which srcPath is to be copied.
     285                 :    Returns the store path and the cryptographic hash of the
     286                 :    contents of srcPath. */
     287                 : std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath,
     288                 :     bool fixed = false, bool recursive = false, string hashAlgo = "",
     289                 :     PathFilter & filter = defaultPathFilter);
     290                 : 
     291                 : /* Preparatory part of addTextToStore().
     292                 : 
     293                 :    !!! Computation of the path should take the references given to
     294                 :    addTextToStore() into account, otherwise we have a (relatively
     295                 :    minor) security hole: a caller can register a source file with
     296                 :    bogus references.  If there are too many references, the path may
     297                 :    not be garbage collected when it has to be (not really a problem,
     298                 :    the caller could create a root anyway), or it may be garbage
     299                 :    collected when it shouldn't be (more serious).
     300                 : 
     301                 :    Hashing the references would solve this (bogus references would
     302                 :    simply yield a different store path, so other users wouldn't be
     303                 :    affected), but it has some backwards compatibility issues (the
     304                 :    hashing scheme changes), so I'm not doing that for now. */
     305                 : Path computeStorePathForText(const string & suffix, const string & s,
     306                 :     const PathSet & references);
     307                 : 
     308                 : 
     309                 : /* Remove the temporary roots file for this process.  Any temporary
     310                 :    root becomes garbage after this point unless it has been registered
     311                 :    as a (permanent) root. */
     312                 : void removeTempRoots();
     313                 : 
     314                 : 
     315                 : /* Register a permanent GC root. */
     316                 : Path addPermRoot(const Path & storePath, const Path & gcRoot,
     317                 :     bool indirect, bool allowOutsideRootsDir = false);
     318                 : 
     319                 : 
     320                 : /* Sort a set of paths topologically under the references relation.
     321                 :    If p refers to q, then p follows q in this list. */
     322                 : Paths topoSortPaths(const PathSet & paths);
     323                 : 
     324                 : 
     325                 : /* For now, there is a single global store API object, but we'll
     326                 :    purify that in the future. */
     327                 : extern boost::shared_ptr<StoreAPI> store;
     328                 : 
     329                 : 
     330                 : /* Factory method: open the Nix database, either through the local or
     331                 :    remote implementation. */
     332                 : boost::shared_ptr<StoreAPI> openStore();
     333                 : 
     334                 : 
     335                 : /* Display a set of paths in human-readable form (i.e., between quotes
     336                 :    and separated by commas). */
     337                 : string showPaths(const PathSet & paths);
     338                 : 
     339                 : 
     340                 : string makeValidityRegistration(const PathSet & paths,
     341                 :     bool showDerivers, bool showHash);
     342                 :     
     343                 : struct ValidPathInfo 
     344          128104 : {
     345                 :     Path path;
     346                 :     Path deriver;
     347                 :     Hash hash;
     348                 :     PathSet references;
     349                 :     time_t registrationTime;
     350           32404 :     ValidPathInfo() : registrationTime(0) { }
     351                 : };
     352                 : 
     353                 : typedef list<ValidPathInfo> ValidPathInfos;
     354                 : 
     355                 : ValidPathInfo decodeValidPathInfo(std::istream & str,
     356                 :     bool hashGiven = false);
     357                 : 
     358                 : 
     359                 : }
     360                 : 
     361                 : 
     362                 : #endif /* !__STOREAPI_H */

Generated by: LTP GCOV extension version 1.6