Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

VestaSource.H

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 //
00020 // VestaSource.H
00021 // Last modified on Fri Feb 10 16:09:24 EST 2006 by ken@xorian.net  
00022 //      modified on Mon Nov 15 08:53:29 EST 2004 by irina.furman@intel.com 
00023 //      modified on Fri Aug 10 15:09:15 PDT 2001 by mann  
00024 //      modified on Tue May  4 10:51:22 PDT 1999 by heydon
00025 //
00026 // Primary internal interface for the Vesta repository directory
00027 // structure.  
00028 
00029 #ifndef _VSOURCE
00030 #define _VSOURCE 1
00031 
00032 #include "SourceOrDerived.H"
00033 #include "ArcTable.H"
00034 #include "AccessControl.H"
00035 #include "ReadersWritersLock.H"
00036 #include "FP.H"
00037 #include "VRErrorCode.H"
00038 #include "VestaAttribs.H"
00039 #include <iostream>
00040 
00041 typedef const char* Arc;        // must not contain /, \, or \000
00042 #define MAX_ARC_LEN 255
00043 
00044 class VestaSource; // forward
00045 
00046 // A LongId is an identifier for a Vesta source that is suitable for
00047 // use with NFS.  Every source in the /vesta directory tree at a site
00048 // has a LongId, as does every source in a Vesta mutable (working)
00049 // directory tree.
00050 //
00051 class LongId {
00052   public:
00053     Byte32 value;
00054 
00055     // Form the LongId of the indexth child of this source.
00056     // (1-origin) Return NullLongId if there is no room for more
00057     // children.  Crash if invoked on NullLongId.
00058     LongId append(unsigned int index) const throw ();
00059 
00060     // Form the LongId of the parent directory of this source.  If
00061     // index is not NULL, also set *index to the index of this source
00062     // within its parent.  Return NullLongId if this source has no
00063     // parent.
00064     LongId getParent(unsigned int* index =NULL) const throw ();
00065 
00066     // Return true if this LongId is an ancestor of the given child.
00067     // A LongId is considered to be its own ancestor.
00068     bool isAncestorOf(const LongId& child) const throw ();
00069 
00070     // Compare two LongIds
00071     bool operator==(const LongId& child) throw () {
00072         return memcmp(this->value.byte, child.value.byte, sizeof(Byte32)) == 0;
00073     };
00074 
00075     // Construct a LongId from a ShortId.  If the ShortId belongs to
00076     // a file, the fingerprint must be supplied.  If the ShortId
00077     // belongs to an immutable directory, the fingerprint is ignored;
00078     // the repository looks it up internally when the LongId is used.
00079     static LongId fromShortId(ShortId sid, const FP::Tag* fptag =NULL)
00080         throw ();
00081 
00082     // Find the length of a LongId.  When pickling and unpickling
00083     // LongIds, only the first "length" bytes need be pickled; the
00084     // rest are zeros (and must be filled with zeros upon unpickling).
00085     int length() const throw ();
00086 
00087     // Look up LongId to get a VestaSource.  Return NULL if this
00088     // LongId does not correspond to any extant source.  The caller is
00089     // responsible for freeing the object returned.
00090     //
00091     // The following feature is available only inside the repository
00092     // address space: If lockKind == readLock, readLockV, writeLock,
00093     // or writeLockV, acquire the repository global read or write lock
00094     // on the directory tree that the LongId is in (either the stable
00095     // tree lock or a volatile tree lock), and return a pointer to the
00096     // correct lock.  If lockKind == readLockV or writeLockV, the
00097     // caller already has the volatile root read lock, so it is not
00098     // acquired again during the call.  If lockKind == checkLock,
00099     // check that the supplied lock pointer is the correct one for the
00100     // tree the LongId is in, and return NULL if it is not.  If the
00101     // LongId represents a file ShortId, *lock is set to NULL, as no
00102     // tree lock is needed.
00103     //
00104     // The method can throw SRPC::failure only if used outside the
00105     // repository address space.
00106     //
00107     enum lockKindTag { readLock, writeLock, noLock, checkLock,
00108                        readLockV, writeLockV };
00109     VestaSource* lookup(lockKindTag lockKind =noLock,
00110                         ReadersWritersLock** lock =NULL)
00111       throw (SRPC::failure);
00112 
00113     // Check whether a LongId is valid.  Returns false if lookup would
00114     // return NULL; true if it would return non-NULL .
00115     bool valid() throw (SRPC::failure);
00116 };
00117 
00118 extern const LongId RootLongId;        // LongId of /vesta
00119 extern const LongId MutableRootLongId;
00120 extern const LongId VolatileRootLongId;
00121 extern const LongId DirShortIdRootLongId;
00122 extern const LongId FileShortIdRootLongId;
00123 extern const LongId NullLongId;        // A known invalid LongId
00124 
00125 // VestaSource is the base class for all types of Vesta source.
00126 
00127 // The logical type of a VestaSource is given by a typeTag (see
00128 // below).  Most of these types are discussed in the repository design
00129 // notes.
00130 
00131 // The representation type (subclass) used for a VestaSource is
00132 // generally determined by its logical type and whether the source is
00133 // local or remote.  The representation types include VLeaf,
00134 // VDirUnchangeable, VDirChangeable, VDirEvaluator, and VDirSurrogate.
00135 // Do not create an object of the base class.
00136 
00137 // All these representations are in-memory data structures.  The
00138 // on-disk representation of a directory is the repository log and
00139 // checkpoint.  The on-disk representation of a ghost or stub is in
00140 // its parent directory.  The on-disk representation of a file is
00141 // partly in its parent directory and partly in the file corresponding
00142 // to its ShortId.
00143 
00144 // Here is how the representations are used.  Note that some logical
00145 // types have multiple representations possible.
00146 
00147 // Logical type           Representation        Notes
00148 // ------------           --------------        -----
00149 // any source             VDirSurrogate         1
00150 // immutableFile          VLeaf                 
00151 // mutableFile            VLeaf                 
00152 // immutableDirectory     VDirChangeable        2
00153 // appendableDirectory    VDirChangeable        
00154 // mutableDirectory       VDirChangeable        
00155 // ghost                  VLeaf                 
00156 // stub                   VLeaf                 
00157 // deleted                none                  3
00158 // outdated               none                  3
00159 // volatileDirectory      VDirChangeable
00160 // volatileROEDirectory   VDirChangeable
00161 // evaluatorDirectory     VDirEvaluator         4
00162 // evaluatorROEDirectory  VDirEvaluator         4
00163 // device                 none                  5
00164 // gap                    none                  3
00165 // unused                 none                  3
00166 
00167 // 1) Used on the client side of the SRPC interface to the repository
00168 // server, for all sources.  The "Dir" in the name is historical; the
00169 // type is no longer used only for directories.
00170 // 2) It was once intended to have a separate type VDirUnchangeable
00171 // for immutable directories, but that idea has been abandoned.
00172 // 3) These values are used inside the directory implementation, and
00173 // "deleted" may be returned by the listCallback if the caller has
00174 // asked to see a delta instead of a full directory.
00175 // 4) This is a kind of surrogate inside the repository server for a
00176 // "directory" that is really a binding in the evaluator value space.
00177 // 5) /dev/null implementation inside the repository NFS server.
00178 
00179 // Note: Most methods have SRPC::failure in their throw () clauses, but
00180 // they can really throw this exception only in the subclass
00181 // VDirSurrogate.
00182 
00183 class VestaSource : public VestaAttribs, public VRErrorCode {
00184   public:
00185     enum dupeCheck { dontReplace = 0,  // Report error if name is in use.
00186                      replaceDiff,      // Replace existing object, if
00187                                        //  any, with a different object
00188                                        //  having the same name.
00189                      replaceNonMaster  // Replace existing object, if any,
00190                                        //  with a different object
00191                                        //  having the same name, unless
00192                                        //  the existing object is master.
00193                  };
00194     enum typeTag { immutableFile=0, mutableFile, immutableDirectory,
00195                    appendableDirectory, mutableDirectory, ghost, stub,
00196                    deleted, outdated, volatileDirectory,
00197                    evaluatorDirectory, device, volatileROEDirectory,
00198                    evaluatorROEDirectory, gap, unused=15 };
00199 
00200     // The following two functions return pointers to static storage
00201     static const char* errorCodeString(errorCode err) throw (); 
00202     static const char* typeTagString(typeTag type) throw ();
00203     static char typeTagChar(typeTag type) throw ();
00204       // immutable(f)ile, m(u)tableFile, (i)mmutableDirectory,
00205       // (a)ppendableDirectory, (m)utableDirectory, (g)host, (s)tub,
00206       // (d)eleted, (o)utdated, (v)olatileDirectory, (e)valuatorDirectory,
00207       // dev(n)ull, volatile(r)OEDirectory, eva(l)uatorROEDirectory,
00208       // ga(p), unused(x)
00209 
00210     // Find roots.  Outside the repository address space, the
00211     // parameters must be defaulted.
00212     static VestaSource*
00213       repositoryRoot(LongId::lockKindTag lockKind =LongId::noLock,
00214                      ReadersWritersLock** lock =NULL) throw (SRPC::failure);
00215     static VestaSource*
00216       mutableRoot(LongId::lockKindTag lockKind =LongId::noLock,
00217                   ReadersWritersLock** lock =NULL) throw (SRPC::failure);
00218     static VestaSource*
00219       volatileRoot(LongId::lockKindTag lockKind =LongId::noLock,
00220                    ReadersWritersLock** lock =NULL) throw (SRPC::failure);
00221 
00222     // The following fields should not be modified after initialization
00223     typeTag type;
00224     LongId longid;
00225     bool master;
00226     Bit32 pseudoInode;  // See below
00227     FP::Tag fptag;  // See below
00228 
00229     // Server-side initialization.  These methods are not
00230     // needed (or supplied) in the client-side implementation.
00231     // init() must be called before the first use of anything else in
00232     // this interface.  recoveryDone() must be called after recovery
00233     // from the repository log is complete, to turn on logging of new
00234     // updates; it sets doLogging to true.
00235     static void init() throw ();
00236     static void recoveryDone() throw ();
00237     static bool doLogging;
00238 
00239     // Someone else may have modified the representation that this
00240     // object points to, so discard any state cached in the object.
00241     virtual void resync(AccessControl::Identity who =NULL)
00242       throw (SRPC::failure);
00243 
00244     // Get a VestaSource for the parent directory.  Returns 0 if this
00245     // object has no parent directory.  (Note: not implemented inside
00246     // the repository server.)
00247     VestaSource* getParent() throw (SRPC::failure);
00248 
00249     // The following methods work only on files.  If you call one on
00250     // a non-file, it will return an error, except as noted below.
00251     // These methods are meant only for remote, "arm's length" use by
00252     // the replicator: local processes with sufficient privilege can
00253     // obtain a file's ShortId and access it more efficiently through
00254     // the SourceOrDerived interface.  These methods modify the
00255     // underlying ShortId file directly and immediately; they are not
00256     // part of the current failure-atomic transaction.
00257 
00258     // Immutable or mutable files
00259     virtual errorCode
00260       read(void* buffer, /*INOUT*/int* nbytes, Basics::uint64 offset,
00261            AccessControl::Identity who =NULL) throw (SRPC::failure);
00262     // Read the entire file at once.  Write its contents to the
00263     // specified ostream.  (Note: not implemented inside the
00264     // repository server.)
00265     virtual errorCode
00266       readWhole(std::ostream &out, AccessControl::Identity who =NULL)
00267       throw (SRPC::failure);
00268     // Returns false for non-files:
00269     virtual bool executable() throw (SRPC::failure);
00270     // Returns 0 for non-files:
00271     virtual Basics::uint64 size() throw (SRPC::failure); 
00272 
00273     // Mutable files only
00274     virtual errorCode
00275       write(const void* buffer, /*INOUT*/int* nbytes, Basics::uint64 offset,
00276             AccessControl::Identity who =NULL) throw (SRPC::failure);
00277     virtual errorCode
00278       setExecutable(bool x, AccessControl::Identity who =NULL)
00279       throw (SRPC::failure);
00280     virtual errorCode
00281       setSize(Basics::uint64 s, AccessControl::Identity who =NULL)
00282       throw (SRPC::failure);
00283 
00284     // The following methods work on both files and directories.
00285 
00286     // Get the modified time.  Returns "2" on ghosts and stubs.
00287     virtual time_t timestamp() throw (SRPC::failure);
00288 
00289     // Set the modified time.  No-op on ghosts and stubs.  When
00290     // applied to a file, this method modifies the underlying ShortId
00291     // file directly and immediately; it is not part of the current
00292     // failure-atomic transaction.
00293     virtual errorCode
00294       setTimestamp(time_t ts, AccessControl::Identity who =NULL)
00295       throw (SRPC::failure);
00296 
00297     // The following method works only on a file or immutable
00298     // directory.  If you call it on another type of source, it will
00299     // return NullShortId.
00300     virtual ShortId shortId() throw (SRPC::failure);
00301 
00302     // The following methods work only on directories.  If you
00303     // call one on a non-directory, it will return notADirectory,
00304     // unless the specific comments state otherwise.  In the methods
00305     // that take a timestamp argument, this value is used as the
00306     // modified time if supplied; otherwise the current time is used.
00307 
00308     // Look up an Arc relative to this directory.  Note that ".",
00309     // "..", and "" arcs are not understood at this layer.  The
00310     // indexOffset argument to lookup() is for internal use only;
00311     // clients must always default it.  The caller is responsible for
00312     // freeing the object returned in result.
00313     virtual errorCode
00314       lookup(Arc arc, VestaSource*& result, AccessControl::Identity who =NULL,
00315              unsigned int indexOffset =0) throw (SRPC::failure);
00316 
00317     // Look up a pathname, consisting of arcs separated by
00318     // pathnameSep characters, relative to this directory.  Again,
00319     // ".", "..", and "" arcs are not understood.  Also, an initial
00320     // pathnameSep character does not specify the root.  The caller is
00321     // responsible for freeing the object returned in result.
00322     virtual errorCode
00323       lookupPathname(const char* pathname, VestaSource*& result,
00324                      AccessControl::Identity who =NULL,
00325                      char pathnameSep =PathnameSep) throw (SRPC::failure);
00326 
00327     // Find the indexth child of this directory.  If arcbuf is not
00328     // NULL, the arc corresponding to the child found is returned in
00329     // the supplied buffer, which must be at least MAX_ARC_LEN+1 bytes
00330     // long.  This method may indirect through a forwarding pointer
00331     // (if the indexth entry was renamed), so the LongId of the result may
00332     // be different from longid.append(index).  The caller is
00333     // responsible for freeing the object returned in result.
00334     virtual errorCode lookupIndex(unsigned int index, VestaSource*& result,
00335                                   char* arcbuf =NULL) throw (SRPC::failure);
00336 
00337     // Really delete this entry; do not leave a ghost.  WARNING: do not
00338     // use on a master appendable directory, or the repository's guarantee
00339     // not to reuse a name with a different meaning can be violated.
00340     // If existCheck is false, the routine succeeds even if no entry by the 
00341     // given name exists. 
00342     virtual errorCode reallyDelete(Arc arc, AccessControl::Identity who =NULL,
00343                                    bool existCheck =true,
00344                                    time_t timestamp =0) throw (SRPC::failure);
00345 
00346     // Insert an entry into the directory.  The behavior if this name
00347     // is already bound depends on the dupeCheck parameter; see above.
00348     // If the newvs parameter is not NULL, a VestaSource object
00349     // referring to the new entry is returned there; the caller is
00350     // responsible for freeing this object.
00351 
00352     // Link to an existing file by ShortId.  Parent may be mutable,
00353     // appendable, or volatile (including volatileROE).  Normally
00354     // fptag is NULL, but you can choose the fingerprint by setting it.
00355     virtual errorCode
00356       insertFile(Arc arc, ShortId sid, bool master, 
00357                  AccessControl::Identity who =NULL,
00358                  dupeCheck chk=dontReplace, VestaSource** newvs =NULL,
00359                  time_t timestamp =0, FP::Tag* fptag =NULL)
00360       throw (SRPC::failure);
00361     // Mutable link to an existing or new file by ShortId.  Parent must be
00362     // mutable or volatile (including volatileROE).  If sid is NullShortId,
00363     // a new shortid is assigned and an empty file is created.
00364     virtual errorCode
00365       insertMutableFile(Arc arc, ShortId sid, bool master,
00366                  AccessControl::Identity who =NULL,
00367                  dupeCheck chk=dontReplace, VestaSource** newvs =NULL,
00368                  time_t timestamp =0) throw (SRPC::failure);
00369     // If dir is immutable, bind arc to it.  If dir is mutable, bind
00370     // arc to a new immutableDirectory that is a deep copy of dir.  If
00371     // dir is NULL, bind arc to an empty immutableDirectory.  Parent
00372     // must be appendable or mutable.  CheckIn and Advance use this method.
00373     // Normally fptag is NULL, but if dir is mutable or NULL, you can
00374     // choose the new directory's fingerprint by setting fptag.
00375     virtual errorCode
00376       insertImmutableDirectory(Arc arc, 
00377                  VestaSource* dir, bool master, 
00378                  AccessControl::Identity who =NULL,
00379                  dupeCheck chk=dontReplace, VestaSource** newvs =NULL,
00380                  time_t timestamp =0, FP::Tag* fptag =NULL)
00381        throw (SRPC::failure);
00382     // Create new, empty appendableDirectory.  Parent must be appendable.
00383     virtual errorCode
00384       insertAppendableDirectory(Arc arc, bool master,
00385                  AccessControl::Identity who =NULL,
00386                  dupeCheck chk=dontReplace, VestaSource** newvs =NULL,
00387                  time_t timestamp =0) throw (SRPC::failure);
00388     // Create new mutable (or volatile, or volatileROE) directory.
00389     // Parent must be mutable (or volatile, or volatileROE,
00390     // respectively).  If dir is NULL, the new directory is empty;
00391     // otherwise, dir must be immutable, and the new directory is
00392     // initially a shallow copy of it.  CheckOut uses this method.
00393     virtual errorCode
00394       insertMutableDirectory(Arc arc, VestaSource* dir, bool master, 
00395                  AccessControl::Identity who =NULL,
00396                  dupeCheck chk=dontReplace, VestaSource** newvs =NULL,
00397                  time_t timestamp =0) throw (SRPC::failure);
00398     // Create new ghost.  Parent must be appendable.
00399     virtual errorCode
00400       insertGhost(Arc arc, bool master,
00401                  AccessControl::Identity who =NULL,
00402                  dupeCheck chk=dontReplace, VestaSource** newvs =NULL,
00403                  time_t timestamp =0) throw (SRPC::failure);
00404     // Create new stub.  Parent must be appendable.
00405     virtual errorCode
00406       insertStub(Arc arc, bool master,
00407                  AccessControl::Identity who =NULL,
00408                  dupeCheck chk=dontReplace, VestaSource** newvs =NULL,
00409                  time_t timestamp =0) throw (SRPC::failure);
00410 
00411     // Rename existing file or directory.  Should be used only on
00412     // mutable or volatile/volatileROE directories.  Currently also
00413     // works on appendable directories for backward compatibility
00414     // only; this functionality may be removed in the future.
00415     virtual errorCode
00416       renameTo(Arc arc, VestaSource* fromDir, Arc fromArc,
00417                AccessControl::Identity who =NULL,
00418                dupeCheck chk=dontReplace, time_t timestamp =0)
00419       throw (SRPC::failure);
00420 
00421     // Directory listing.  For each directory entry, beginning with
00422     // firstIndex, the callback is invoked with the corresponding
00423     // object's parameters.  The shortid is provided only for files,
00424     // not directories, and is also omitted for files in an evaluator
00425     // directory (including the base of a volatile directory).  If the
00426     // callback returns true, the listing is continued; if not, it is
00427     // stopped.  Note that "." and ".." arcs are not understood at
00428     // this layer.  You can get the LongId for ".." with
00429     // longid.getParent().  To list starting at the next entry after
00430     // one returned with index=i, begin with firstIndex=i+2.  To list
00431     // starting at the first entry, begin with firstIndex=0.
00432     //
00433     // If deltaOnly is true for a mutable, volatile, or volatileROE
00434     // directory, only the changes with respect to the directory base
00435     // are shown; deletions are shown as arcs of type deleted.  (In
00436     // a deleted arc may sometimes appear for a name that transiently
00437     // existed in the directory but never existed in the base.)
00438     //
00439     // The indexOffset argument is for internal use only; clients
00440     // must always default it.
00441 
00442     typedef bool (*listCallback)(void* closure, typeTag type, Arc arc,
00443                                  unsigned int index, Bit32 pseudoInode,
00444                                  ShortId fileSid, bool master);
00445     virtual errorCode
00446       list(unsigned int firstIndex, listCallback callback,
00447            void* closure, AccessControl::Identity who =NULL,
00448            bool deltaOnly =false, unsigned int indexOffset =0)
00449       /*throw (SRPC::failure or anything thrown by the callback)*/;
00450 
00451     // Acquire base of directory and return a new VestaSource object
00452     // for the base. The caller is responsible for freeing the 
00453     // object returned.
00454     virtual errorCode
00455       getBase(VestaSource*& result, AccessControl::Identity who =NULL)
00456       throw (SRPC::failure);
00457 
00458     // Replace an immutableFile or immutableDirectory with a mutable
00459     // (or volatile) one, and return a new VestaSource object for the
00460     // new source.  The new source has the same name and (unlike
00461     // sources inserted with other methods) the same LongId as the old
00462     // source had.  The source must be a descendent of MutableRoot (or
00463     // VolatileRoot).
00464     // 
00465     // If the source parent is an immutable (or evaluator) directory,
00466     // the parent is made mutable (resp. volatile) recursively.  If
00467     // the old source was a directory, the new source is a shallow
00468     // copy of the old one, as with insertMutableDirectory above.
00469     //
00470     // If the old source was a file, the caller may either supply the
00471     // ShortId of a new source, or supply NullShortId.  In the latter
00472     // case, the repository assigns a new shortid and copies the first
00473     // copyMax bytes of the old data to it.
00474     //
00475     // It is an error to apply this method to a file whose LongId is
00476     // based on its ShortId; such LongIds are assigned explicitly by
00477     // LongId::fromShortId, or implicitly to files in directory trees
00478     // created by createVolatileDirectory with the readOnlyExisting
00479     // flag.
00480     //
00481     // On return, the old VestaSource object is invalid (but has not
00482     // been freed).  The caller is responsible for freeing the object
00483     // returned.
00484     virtual errorCode
00485       makeMutable(VestaSource*& result, ShortId sid =NullShortId,
00486                   Basics::uint64 copyMax = (Basics::uint64) -1,
00487                   AccessControl::Identity who =NULL)
00488        throw (SRPC::failure);
00489 
00490     // Similar to makeMutable, but doesn't make the object itself
00491     // mutable.  This allows for adding attributes to an object in a
00492     // mutable directory without actually creating a mutable copy.  As
00493     // with makeMutable, the new source has the same name and LongId
00494     // as the old source.  The source must be a descendent of
00495     // MutableRoot.
00496     //
00497     // If the source parent is an immutable directory, the parent is
00498     // made mutable recursively.
00499     //
00500     // On return, the old VestaSource object is invalid (but has not
00501     // been freed).  The caller is responsible for freeing the object
00502     // returned.
00503     virtual errorCode
00504       copyToMutable(VestaSource*& result,
00505                     AccessControl::Identity who =NULL)
00506        throw (SRPC::failure);
00507 
00508     // Make files in a directory tree immutable and optionally
00509     // cause their fingerprints to be based on content.
00510     // The object must be a mutable, volatile, or volatileROE
00511     // directory, or a mutable file.  Walks the directory tree rooted
00512     // at the object and examines each mutable file.  If a mutable
00513     // file is less than threshold bytes long, it is made immutable
00514     // with a fingerprint computed based on its content.  Otherwise,
00515     // if the directory is volatile[ROE], the file is made immutable
00516     // with a fingerprint based on its preassigned unique id.
00517     // Otherwise (i.e., if the file is threshold or more bytes long
00518     // and the directory is mutable), the file remains mutable and a
00519     // fingerprint is not assigned yet.  A threshold of (unsigned int)
00520     // -1 is "infinity".
00521     //
00522     // This method must be used at the end of every tool invocation,
00523     // to ensure that the files created will really be read-only in
00524     // volatileROE directories created later.  It is also used by
00525     // vadvance to implement the -F flag.
00526     //
00527     virtual errorCode
00528       makeFilesImmutable(unsigned int threshold,
00529                          AccessControl::Identity who =NULL)
00530         throw (SRPC::failure);
00531 
00532     // Turn the master flag on or off.  Use with care to preserve the
00533     // replication invariants!  setMaster is a convenience method
00534     // implemented on top of setIndexMaster.  Subclasses need only 
00535     // provide the latter.
00536     virtual errorCode setMaster(bool state,
00537                                 AccessControl::Identity who =NULL)
00538       throw (SRPC::failure);
00539     virtual errorCode setIndexMaster(unsigned int index, bool state,
00540                                      AccessControl::Identity who =NULL)
00541        throw (SRPC::failure);
00542 
00543     // Find out which repository this VestaSource is in
00544     virtual Text host() throw ();
00545     virtual Text port() throw ();
00546 
00547     // The following method should be called only from inside the
00548     // repository that is acquiring mastership, not from ordinary clients.
00549     // See Mastership.C.  Caller is responsible for freeing *grantidOut.
00550     virtual errorCode
00551       cedeMastership(const char* requestid, const char** grantidOut,
00552                      AccessControl::Identity who =NULL) throw (SRPC::failure);
00553 
00554     // Access control
00555     AccessControl ac;
00556 
00557     // The following methods give an assertion failure if applied to
00558     // a nondirectory.
00559 
00560     // Methods for use in source weeding (garbage collection).
00561     // Cannot be used outside the repository address space.
00562     virtual bool hasName() throw ();
00563     virtual void setHasName(bool val) throw ();
00564     virtual bool visited() throw ();
00565     virtual void setVisited(bool val) throw ();
00566     virtual void mark(bool byName =true, ArcTable* hidden =NULL) throw();
00567 
00568     // Method for explicit free of directory tree.  The object must
00569     // be a volatile or evaluator directory.  Used to reclaim memory
00570     // allocated to volatile directory trees eagerly instead of
00571     // waiting for the next source weed.  The caller guarantees that
00572     // there are no references to this rep or any of its substructure
00573     // from outside the tree.  Cannot be used outside the repository
00574     // address space.
00575     virtual void freeTree() throw ();
00576 
00577     // Method for checkpointing.  nextSP is the new short pointer
00578     // that the next item written to the checkpoint file will receive.
00579     // The method increments nextSP by the number of bytes it writes
00580     // into the checkpoint.  The new short pointer for this object is
00581     // returned.  Cannot be used outside the repository address space.
00582     virtual Bit32 checkpoint(Bit32& nextSP, std::fstream& ckpt) throw ();
00583 
00584     // Utility method for generating pseudo-inode numbers.
00585     // Should not be used outside the repository address space.
00586     inline Bit32 indexToPseudoInode(unsigned int index) throw (){
00587       return 0x7fffffff & (((pseudoInode << 8) | (pseudoInode >> 23)) + index);
00588     }
00589 
00590     //
00591     // Convenience wrappers around writeAttrib
00592     //
00593 
00594     // opSet: Bind name to the singleton set {value}.  Equivalent to clear
00595     // followed by add, but atomic even in the presence of other
00596     // changes with the same timestamp.
00597     inline VRErrorCode::errorCode
00598       setAttrib(const char* name, const char* value,
00599                 AccessControl::Identity who =NULL,
00600                 time_t timestamp =0) throw (SRPC::failure)
00601       { return writeAttrib(opSet, name, value, who, timestamp); };
00602 
00603     // opClear: Bind name to the empty set; i.e., unbind it.
00604     // Client should pass "" as value.
00605     inline VRErrorCode::errorCode
00606       clearAttrib(const char* name, AccessControl::Identity who =NULL,
00607                   time_t timestamp =0) throw (SRPC::failure)
00608       { return writeAttrib(opClear, name, "", who, timestamp); };
00609 
00610     // opAdd: Add value to the set that is bound to name.
00611     inline VRErrorCode::errorCode
00612       addAttrib(const char* name, const char* value,
00613                 AccessControl::Identity who =NULL,
00614                 time_t timestamp =0) throw (SRPC::failure)
00615       { return writeAttrib(opAdd, name, value, who, timestamp); };
00616 
00617     // opRemove: Remove value from the set that is bound to name, if present.
00618     inline VRErrorCode::errorCode
00619       removeAttrib(const char* name, const char* value,
00620                    AccessControl::Identity who =NULL,
00621                    time_t timestamp =0) throw (SRPC::failure)
00622       { return writeAttrib(opRemove, name, value, who, timestamp); };
00623 
00624     // Our own version of VestaAttribs::writeAttrib.  This one does
00625     // access checking and logging; the base class's method does not.
00626     // The method is a no-op if this source does not have attributes.
00627     virtual errorCode
00628       writeAttrib(attribOp op, const char* name, const char* value,
00629                   AccessControl::Identity who =NULL, time_t timestamp =0)
00630       throw (SRPC::failure);
00631 
00632     // Statistics primarily intended for VDirChangeable.  Other object
00633     // types return inapproprateOp.
00634     struct directoryStats
00635     {
00636       Basics::uint32
00637         // A mutable/immutable directory can be based on another, in
00638         // which case it represents a delta over the base.  (See
00639         // getBase above.)  This measurement tells you how long the
00640         // chain of base directories is.
00641         baseChainLength,
00642         // When one directory is based on another, only some of
00643         // directory entries along the base chain will be used to make
00644         // up the directory at the head.  However, the repository must
00645         // walk along all of these entries when listing the directory.
00646         // These measurements give the number and size in bytes of
00647         // directory entries used by the directory at the head and by
00648         // all directories along the base chain.
00649         usedEntryCount,
00650         usedEntrySize,
00651         totalEntryCount,
00652         totalEntrySize;
00653     };
00654     virtual errorCode
00655       measureDirectory(/*OUT*/directoryStats &result,
00656                        AccessControl::Identity who =NULL)
00657       throw (SRPC::failure);
00658 
00659     // Special method for immutable directories.  Causes the base
00660     // directory of this directory to be collapsed, eliminating some
00661     // amount of directory delta encoding, which may make some
00662     // operations (lookup, directory listing, changes) more efficient.
00663     virtual errorCode
00664       collapseBase(AccessControl::Identity who =NULL)
00665       throw (SRPC::failure);
00666 
00667     // Get the number of links to a file.  Returns 1 except for mutable
00668     // files in directories which support hard links.
00669     virtual unsigned int linkCount();
00670 
00671     // Create a duplicate of this instance of the appropriate subclass.
00672     virtual VestaSource *copy() throw();
00673 
00674     virtual ~VestaSource() { }
00675 
00676   public:
00677     Bit8* rep;
00678 };
00679 
00680 // FILEHANDLE PERSISTENCE
00681 
00682 // The longid of a source is used as its NFS filehandle.  NFS
00683 // filehandles have one property that longids do not share: an object
00684 // is supposed to keep the same filehandle despite renaming or
00685 // copy-on-write.  We use two mechanisms to ensure this.
00686 
00687 // 1) A VForward pointer keeps the old longid of a renamed object
00688 // working as long as its old parent directory is not deleted.
00689 // Opening the object under its new name gives a new longid.  This
00690 // seems to work well enough in practice.
00691 
00692 // 2) After copy-on-write, the new directory entry has a "sameAsBase"
00693 // flag set, indicating that it should appear to have the longid of
00694 // the newest object of the same name in the base rather than its own
00695 // natural longid.  The object is accessible under its own longid as
00696 // well, but this longid is never actually used.
00697 
00698 // PSEUDO-INODE NUMBERS
00699 
00700 // The pseudo-inode number of a source is presented through the NFS
00701 // interface as its inode number.
00702 
00703 // Some NFS clients expect every file and directory to have a unique
00704 // and persistent inode number, not just a 32-byte NFS file handle
00705 // (longid).  Even though inode numbers cannot be used for lookup
00706 // through the NFS interface, some clients use the inode number to
00707 // index their cache and/or check it for consistency; in particular,
00708 // the Linux 2.2 NFS client is quite fussy about inode numbers.
00709 
00710 // These requirements are difficult to meet in Vesta for several
00711 // reasons.  There is no truly unique 32-bit identifier across all
00712 // types of object that can appear in Vesta directories.  One cannot
00713 // simply use the 32-bit shortid, for several reasons: (1) Only files
00714 // and immutable directories have shortids.  (2) A file changes its
00715 // shortid when copy-on-write occurs.  (3) The same immutable
00716 // directory can (and frequently does) appear in multiple places in
00717 // the hierarchy, with either the same or different parent.  Each
00718 // instance has a different filehandle (since its virtual ".." link is
00719 // different), but the same shortid.
00720 
00721 // Here are the measures taken to alleviate (but not fully solve)
00722 // these problems.
00723 
00724 // The pseudo-inode number of a file that is not subject to
00725 // copy-on-write is its shortid.  This includes files in the appendable
00726 // tree and files in volatileROE or evaluatorROE directories.
00727 
00728 // The pseudo-inode number of a mutable, volatile, or volatileROE
00729 // directory is stored in its representation and remains the same
00730 // across renamings.  For a directory that is created by
00731 // copy-on-write, the pseudo-inode number is initialized to that of
00732 // the base directory; otherwise it is initialized as described in the
00733 // next paragraph.
00734 
00735 // The pseudo-inode number of any other source is a 31-bit hash of its
00736 // longid, computed incrementally on the sequence of indices.  The
00737 // high-order bit of the hash is set to 0 to prevent collisions with
00738 // file shortids.
00739 
00740 // With the scheme above, pseudo-inode number collisions should be
00741 // infrequent, but they can occur.  The known problems that collisions
00742 // can cause are:
00743 
00744 // 1) If two directories with the same inode number appear in the same
00745 // parent directory, some implementations of the Unix "pwd" program or
00746 // "getwd" library routine will return the wrong answer when asked for
00747 // the name of the second of them (or of one of the descendants of the
00748 // latter).  The hash function used does an excellent job of
00749 // preventing collisions within the same parent directory, however.
00750 
00751 // 2) If two different objects with the same inode number are accessed
00752 // by the same client fairly close together in time, and the client
00753 // indexes its cache by inode instead of file handle, cached
00754 // information about the first might be erroneously accepted as
00755 // applying to the second.  (On Linux 2.2, this case seems to cause
00756 // confusion only if both objects are directories.  On Tru64 Unix,
00757 // it seems never to cause a problem.)  It would be nice to have a
00758 // solution that makes this error impossible instead of just very
00759 // unlikely.
00760 
00761 // FINGERPRINTS
00762 
00763 // The repository maintains fingerprints (type FP::Tag) of some
00764 // sources for use by the evaluator.  
00765 
00766 // The appendable tree rooted at repositoryRoot keeps a fingerprint
00767 // for every immutableDirectory and immutableFile.  Repository
00768 // operations return a source fingerprint in the VestaSource::fptag
00769 // field.  Ghosts, stubs, and appendableDirectories do not have
00770 // fingerprints; their fptag fields contain FP::Tag("").
00771 
00772 // Two sources with different contents are guaranteed to have
00773 // different fingerprints.  Two sources with the same content may or
00774 // may not have the same fingerprint.  A source acquires a fingerprint
00775 // based on the pathname under which it is first placed in the
00776 // appendable part of the repository.  That fingerprint stays with it
00777 // as the same source acquires new names via the checkin/advance/
00778 // checkout cycle or by renaming in an appendable directory.  (But see
00779 // below.)
00780 
00781 // The mutable tree does not keep fingerprints for its sources.  The
00782 // fptag field of a source looked up in the mutable tree is
00783 // unspecified.
00784 
00785 // Volatile directory trees keep a fingerprint for every file, but no
00786 // fingerprints for directories; the fptag field of a volatile (or
00787 // evaluator) directory is unspecified.
00788 
00789 // Fingerprints for existing files in a volatile directory (that is,
00790 // files in the base evaluator directory) are obtained from the
00791 // evaluator.  When a new file is created, an arbitrary unique id
00792 // number is generated for it and the fingerprint of that value is
00793 // used.
00794 
00795 // A mutable file's fingerprint can be recomputed to be based on its
00796 // content by calling makeFilesImmutable with the proper arguments.
00797 // This applies both to new files in mutable directories and new files
00798 // in volatile directories.
00799 
00800 #endif //_VSOURCE

Generated on Mon May 8 00:48:50 2006 for Vesta by  doxygen 1.4.2