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

VestaSourceAtomic.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 // VestaSourceAtomic.H
00021 // Last modified on Wed Feb 23 20:06:06 EST 2005 by ken@xorian.net  
00022 //      modified on Fri Nov 10 12:11:54 PST 2000 by mann  
00023 //
00024 
00025 // Facility for grouping several VestaSource actions into an atomic
00026 // unit, from outside the repository address space.  The interface
00027 // essentially lets you write a short, straight-line program in a very
00028 // restricted language and ship it to the repository, where it is
00029 // executed atomically.
00030 
00031 // A program is a sequence of steps.  A newly created
00032 // VestaSourceAtomic object represents an empty program; invoking
00033 // methods on this object appends steps to the program.  After the
00034 // program is completely entered, it can either be run by invoking the
00035 // run() method, or be cancelled by using the cancel() method or
00036 // deleting the object.  A program can be run at most once.  Programs
00037 // that have not yet been run or cancelled consume resources on the
00038 // repository server.
00039 
00040 // A program's state consists of a list of VestaSource objects, two
00041 // current target error codes, and an ok-replacement error code.  The
00042 // list of objects is initially empty, and the three error codes are
00043 // all initially VestaSource::ok.  A step can either append a given
00044 // VestaSource to the list, change the target and ok-replacement error
00045 // codes, or select a VestaSource from the list by index number and
00046 // invoke one of its methods.  If such a method invocation returns a
00047 // new VestaSource object, the new object is appended to the list.
00048 // Every step is executed with the privileges of the same user, as
00049 // specified in the VestaSourceAtomic constructor.
00050 
00051 // Unless otherwise noted below, the execution of each step generates
00052 // a VestaSource::errorCode that is tested against the targets.  If it
00053 // matches either target, the program continues; if not, it halts.
00054 // When a program halts due to missing the error code target, no
00055 // further steps are executed, but any preceding steps that had side
00056 // effects ARE STILL COMMITTED; there is no voluntary abort and
00057 // roll-back feature.  When the program halts or ends normally, the
00058 // number of steps successfully completed is available in the ndone
00059 // field, the VestaSource::errorCode returned by the last step is
00060 // available in the lasterr field, and the ok-replacement error code
00061 // after the last step is available in the okreplace field.
00062 
00063 // A common use for the target and ok-replacement error codes is to
00064 // check that a given name does *not* exist, by doing a lookup() with
00065 // both targets set to VestaSource::notFound and the ok-replacement set
00066 // to VestaSource::nameInUse.
00067 
00068 // Defaulting the timestamp argument in a step (i.e., setting it to 0)
00069 // is handled specially.  For each atomic program, the repository
00070 // server reads the system clock once (after the write lock is
00071 // acquired) and uses the resulting time for all steps where the
00072 // timestamp argument is defaulted.
00073 
00074 // Program execution is atomic in the following sense: First, the
00075 // repository write lock is held during execution, so no client can
00076 // see intermediate states between steps.  Second, the repository's
00077 // atomic logging mechanism ensures that neither a repository crash
00078 // nor a client crash can cause the program to halt and commit; the
00079 // program either runs as if there had not been a crash, or aborts and
00080 // makes no change to the repository.
00081 
00082 // Each step method accepts a stepname argument.  These names are
00083 // accumulated into a sequence and can be retrieved using the name()
00084 // method.  This feature is intended for use in error message
00085 // printing; for example:
00086 //
00087 //  if (!vsa.run()) {
00088 //    VestaSource::errorCode err =
00089 //      (vsa.lasterr == VestaSource::ok) ? vsa.okeplace : vsa.lasterr;
00090 //    cerr << program_name << ": " << vsa.name(vsa.ndone) << ": "
00091 //         << ReposUI::errorCodeText(err) << endl;
00092 //    exit(1);
00093 //  }
00094 //
00095 // For uniformity, all step types take a stepname argument, even those
00096 // that cannot cause an error.  The repos_ui tools generally supply
00097 // the full pathname of the VestaSource object being operated on as
00098 // the stepname, but other ways of naming steps could make sense too.
00099 // Printing vsa.ndone itself in the error message can be useful when
00100 // debugging.
00101 
00102 // The methods of this interface are not monitored, and should not be
00103 // called concurrently on the same VestaSourceAtomic object.  The
00104 // client is responsible for any locking needed to ensure this.
00105 
00106 #ifndef _VSA_H
00107 #define _VSA_H 1
00108 
00109 #include "Basics.H"
00110 #include "FP.H"
00111 #include "SRPC.H"
00112 #include "MultiSRPC.H"
00113 #include "AccessControl.H"
00114 #include "VestaSource.H"
00115 #include "Sequence.H"
00116 
00117 class VestaSourceAtomic {
00118  public:
00119   //
00120   // Types
00121   //
00122   typedef int VSIndex;
00123 
00124   //
00125   // Data fields.  These are all read-only for the client!
00126   //
00127 
00128   // Counts the number of steps entered so far.
00129   int nsteps;
00130   // Counts the number of VestaSource objects on the list.
00131   VSIndex nobjects;
00132   // Remembers the current target error codes.
00133   VestaSource::errorCode target1, target2;
00134 
00135   // Returns the number of steps successfully executed.
00136   int ndone;
00137   // Returns the error code from the last step attempted.
00138   VestaSource::errorCode lasterr;
00139   // Returns the ok-replacement error code from the last step attempted.
00140   VestaSource::errorCode okreplace;
00141 
00142   //
00143   // Constructors and destructor
00144   //
00145 
00146   // Use the default repository
00147   VestaSourceAtomic(AccessControl::Identity who =NULL) throw (SRPC::failure);
00148 
00149   // Specify the repository by host and port
00150   VestaSourceAtomic(const Text& host, const Text& port,
00151                     AccessControl::Identity who =NULL) throw (SRPC::failure);
00152 
00153   // Free resources consumed by the program
00154   ~VestaSourceAtomic() throw ();
00155 
00156   //
00157   // Add steps to the program.  Where no comments are provided, the
00158   // step invokes a VestaSource method of the same name in the obvious
00159   // way; see VestaSource.H and the general description above.
00160   //
00161 
00162   // Set the target and ok-replacement error codes.  Generates no
00163   // error code of its own.
00164   void setTarget(const Text& stepname,
00165                  VestaSource::errorCode target1 =VestaSource::ok,
00166                  VestaSource::errorCode target2 =VestaSource::ok,
00167                  VestaSource::errorCode okreplace =VestaSource::ok
00168                  ) throw (SRPC::failure);
00169 
00170   // Add a VestaSource to the list and return its index number.  If
00171   // vs->longid proves to be invalid at runtime, NULL is added to the
00172   // list and the error code is VestaSource::notFound; otherwise the
00173   // error code is VestaSource::ok.
00174   VSIndex decl(const Text& stepname, VestaSource* vs) throw (SRPC::failure);
00175 
00176   // Call resync at the server.  Always generates VestaSource::ok.
00177   void resync(const Text& stepname, VSIndex vsi) throw (SRPC::failure);
00178 
00179   void setTimestamp(const Text& stepname, VSIndex vsi, time_t ts)
00180     throw (SRPC::failure);
00181 
00182   VSIndex lookup(const Text& stepname, VSIndex vsi, const Text& arc)
00183     throw (SRPC::failure);
00184 
00185   VSIndex lookupPathname(const Text& stepname,
00186                          VSIndex vsi, const Text& pathname,
00187                          char pathnameSep =PathnameSep) throw (SRPC::failure);
00188 
00189   VSIndex lookupIndex(const Text& stepname,
00190                       VSIndex vsi, unsigned int index) throw (SRPC::failure);
00191 
00192   void reallyDelete(const Text& stepname,
00193                     VSIndex vsi, const Text& arc, bool existCheck =true,
00194                     time_t timestamp =0) throw (SRPC::failure);
00195 
00196   VSIndex insertFile(const Text& stepname,
00197                      VSIndex vsi, const Text& arc, ShortId sid, bool master,
00198                      VestaSource::dupeCheck chk =VestaSource::dontReplace,
00199                      time_t timestamp =0, FP::Tag* fptag =NULL
00200                      ) throw (SRPC::failure);
00201 
00202   VSIndex insertMutableFile(const Text& stepname,
00203                             VSIndex vsi, const Text& arc, ShortId sid, bool master,
00204                             VestaSource::dupeCheck chk
00205                             =VestaSource::dontReplace,
00206                             time_t timestamp =0, FP::Tag* fptag =NULL
00207                             ) throw (SRPC::failure);
00208 
00209   // If dir is to be NULL in the method, use -1 as diri.
00210   VSIndex insertImmutableDirectory(const Text& stepname, VSIndex parenti,
00211                                    const Text& arc, VSIndex diri, bool master,
00212                                    VestaSource::dupeCheck chk
00213                                    =VestaSource::dontReplace,
00214                                    time_t timestamp =0,
00215                                    FP::Tag* fptag =NULL) throw (SRPC::failure);
00216 
00217   VSIndex insertAppendableDirectory(const Text& stepname,
00218                                     VSIndex vsi, const Text& arc, bool master,
00219                                    VestaSource::dupeCheck chk
00220                                    =VestaSource::dontReplace,
00221                                    time_t timestamp =0) throw (SRPC::failure);
00222 
00223   // If dir is to be NULL in the method, use -1 as diri.
00224   VSIndex insertMutableDirectory(const Text& stepname, VSIndex parenti,
00225                                  const Text& arc, VSIndex diri, bool master,
00226                                  VestaSource::dupeCheck chk
00227                                  =VestaSource::dontReplace,
00228                                  time_t timestamp =0) throw (SRPC::failure);
00229 
00230   VSIndex insertGhost(const Text& stepname, VSIndex vsi,
00231                       const Text& arc, bool master,
00232                       VestaSource::dupeCheck chk =VestaSource::dontReplace,
00233                       time_t timestamp =0) throw (SRPC::failure);
00234 
00235   VSIndex insertStub(const Text& stepname, VSIndex vsi,
00236                      const Text& arc, bool master,
00237                      VestaSource::dupeCheck chk =VestaSource::dontReplace,
00238                      time_t timestamp =0) throw (SRPC::failure);
00239 
00240   void renameTo(const Text& stepname,
00241                 VSIndex vsi, const Text& arc,
00242                 VSIndex fromDirI, const Text& fromArc,
00243                 VestaSource::dupeCheck chk =VestaSource::dontReplace,
00244                 time_t timestamp =0) throw (SRPC::failure);
00245 
00246   void makeFilesImmutable(const Text& stepname, VSIndex vsi,
00247                           unsigned int threshold) throw (SRPC::failure);
00248 
00249   // For error code checking, a true return (vs->master == master) 
00250   // generates VestaSource::ok; a false return generates the err argument.
00251   void testMaster(const Text& stepname, VSIndex vsi, bool master,
00252                   VestaSource::errorCode err) throw (SRPC::failure);
00253 
00254   void setMaster(const Text& stepname, VSIndex vsi, bool state)
00255     throw (SRPC::failure);
00256 
00257   // For error code checking, inAttribs == expected generates
00258   // VestaSource::ok; inAttribs != expected generates the err argument.
00259   void inAttribs(const Text& stepname,
00260                  VSIndex vsi, const Text& name, const Text& value,
00261                  bool expected, VestaSource::errorCode err)
00262     throw (SRPC::failure);
00263 
00264   inline void setAttrib(const Text& stepname,
00265                         VSIndex vsi, const Text& name, const Text& value,
00266                         time_t timestamp =0) throw (SRPC::failure)
00267     { writeAttrib(stepname, vsi, VestaSource::opSet, name, value,
00268                   timestamp); };
00269 
00270   inline void clearAttrib(const Text& stepname, VSIndex vsi, const Text& name,
00271                           time_t timestamp =0) throw (SRPC::failure)
00272     { writeAttrib(stepname, vsi, VestaSource::opClear, name, "", timestamp); };
00273 
00274   inline void addAttrib(const Text& stepname,
00275                         VSIndex vsi, const Text& name, const Text& value,
00276                  time_t timestamp =0) throw (SRPC::failure)
00277     { writeAttrib(stepname, vsi, VestaSource::opAdd, name, value, timestamp); }
00278 
00279   inline void removeAttrib(const Text& stepname,
00280                            VSIndex vsi, const Text& name, const Text& value,
00281                            time_t timestamp =0) throw (SRPC::failure)
00282     { writeAttrib(stepname, vsi, VestaSource::opRemove, name, value,
00283                   timestamp); };
00284 
00285   void writeAttrib(const Text& stepname, VSIndex vsi, VestaSource::attribOp op,
00286                    const Text& name, const Text& value,
00287                    time_t timestamp =0) throw (SRPC::failure);
00288 
00289   // Merge the value(s) of attribute "name" from fromvsi into tovsi.
00290   // If name is NULL or "", all attributes of fromvsi are merged in.
00291   void mergeAttrib(const Text& stepname, VSIndex fromvsi, VSIndex tovsi,
00292                    const Text& name, time_t timestamp =0)
00293     throw (SRPC::failure);
00294 
00295   // Invoke AccessControl::check on vsi's ac field.  For error code
00296   // checking, check == expected generates VestaSource::ok;
00297   // check != expected generates the err argument.
00298   void accessCheck(const Text& stepname,
00299                    VSIndex vsi, AccessControl::Class cls, bool expected,
00300                    VestaSource::errorCode err) throw (SRPC::failure);
00301 
00302   // Compare vsi's type field to a bitmap of allowed value(s).  Let
00303   // tbit = 1 << (int) type(vsi).  Then if (tbit & allowed) == 0, this
00304   // step generates err; otherwise it generates VestaSource::ok.
00305   static inline unsigned int typebit(VestaSource::typeTag type) {
00306     return 1 << ((int) type);
00307   };
00308   void typeCheck(const Text& stepname,
00309                  VSIndex vsi, unsigned int allowed,
00310                  VestaSource::errorCode err) throw (SRPC::failure);
00311 
00312   //
00313   // Run the program.  Returns true if all steps were successfully
00314   // executed.  The number of steps successfully executed and the
00315   // error code value from the last step attempted are placed in the
00316   // ndone and lasterr fields of the object, respectively.  The
00317   // resources associated with the program are freed and it cannot be
00318   // executed again.
00319   //
00320   bool run() throw (SRPC::failure);
00321 
00322   // 
00323   // Choose not to run the program.  The resources associated with the
00324   // program are freed and it cannot be executed again.  Called
00325   // automatically by the destructor if run() has not yet been called.
00326   //
00327   void cancel() throw (SRPC::failure);
00328 
00329   //
00330   // Obtain the name of the nth step (0-origin).
00331   //
00332   Text name(int step) throw ();
00333 
00334   //
00335   // Private stuff
00336   //
00337  private:
00338   SRPC* srpc;
00339   MultiSRPC::ConnId id;
00340   typedef Sequence<Text> NameSeq;
00341   NameSeq* names;
00342 };
00343 
00344 #endif // _VSA_H

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