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 // SourceOrDerived.H 00021 // Last modified on Tue Sep 21 11:22:00 EDT 2004 by ken@xorian.net 00022 // modified on Thu Jul 20 14:24:31 PDT 2000 by mann 00023 // 00024 // This interface provides access to source and derived files named by 00025 // ShortId. The interface is implemented mostly in library code local 00026 // to each client. An underlying RPC interface is used to get blocks 00027 // of new ShortIds from the repository server and to inform it of 00028 // values passed to the KeepOnly procedures. 00029 00030 // A process running this code accesses source and derived files 00031 // directly in the underlying filesystem, so it must run with the 00032 // proper permissions. Usually that means it must run as user 00033 // "vadmin." (Exception: if only the weeder interface procedures 00034 // are used, no special permissions are needed.) 00035 00036 #ifndef _VSOD 00037 #define _VSOD 00038 00039 #include <sys/stat.h> 00040 00041 #include "Basics.H" 00042 #include "SRPC.H" 00043 #include <fstream> 00044 00045 typedef Bit32 ShortId; 00046 #define NullShortId ((ShortId) 0) 00047 typedef ShortId ShortIdsFile; // ShortId of a file containing 00048 // ShortIds, formatted in hexadecimal, 00049 // zero-filled to 8 digits, one per line. 00050 00051 // SourceOrDerived provides access to source and derived files 00052 // named by ShortId. It is a subclass of the underlying fstream file 00053 // class. Opening a SourceOrDerived file is somewhat different 00054 // from opening an ordinary file: an existing file is named by ShortId 00055 // in the open call, but for new files, the create call chooses and 00056 // returns a new ShortId, with the caller supplying only the LeafFlag. 00057 // 00058 class SourceOrDerived : public std::fstream { 00059 void open(const char *name, std::ios::openmode mode) 00060 { }; // not permitted 00061 public: 00062 static const mode_t default_prot = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 00063 00064 // Catchable exception for fatal errors, allowing the caller to 00065 // print a message and exit instead of dumping core. 00066 class Fatal { 00067 public: 00068 Fatal(const Text msg) throw() : msg(msg) { }; 00069 Text msg; 00070 }; 00071 00072 // Get or set the filesystem pathname that this package is to use 00073 // for accessing the metadata root. If the set method is not 00074 // called, the value of [Repository]metadata_root in vesta.cfg is 00075 // used. This package will open files faster if a shorter 00076 // pathname can be used. In particular, the main program may 00077 // chdir() to the metadata root and pass an empty string to this 00078 // method. If the supplied pathname is not empty, it must end 00079 // with a pathname separator ("/" on Unix). The caller is 00080 // responsible for freeing the storage returned by the get method. 00081 static void setMetadataRootLocalName(char* pathname) throw(); 00082 static char* getMetadataRootLocalName() throw(); 00083 00084 // Create or open a SourceOrDerived as an fstream 00085 ShortId create(bool leafflag =true, std::ios::openmode mode =std::ios::out, 00086 mode_t prot =default_prot) 00087 throw(SRPC::failure, Fatal); 00088 void open(ShortId sid, std::ios::openmode mode =std::ios::in) throw(); 00089 00090 // Create or open a SourceOrDerived and return a file descriptor. 00091 // The oflag and prot arguments are passed directly to the creat() 00092 // or open() system call. If the returned value is -1, errno is set. 00093 static int fdcreate(ShortId& sid, bool leafflag =true, 00094 mode_t prot =default_prot) 00095 throw(SRPC::failure, Fatal); 00096 static int fdopen(ShortId sid, int oflag, mode_t prot =default_prot) 00097 throw(); 00098 00099 // One bit of a derived's ShortId is a flag to indicate whether 00100 // the derived may contain pointers (ShortIds) referring to other 00101 // deriveds, which must be traced by the weeder. A "leaf" 00102 // contains none. The repository does this tracing for directory 00103 // ShortId's, but not for file ShortId's. The evaluator and cache 00104 // are free to create non-leaf files, but the derived weeder is 00105 // responsible for tracing them. 00106 // 00107 static inline bool leafShortId(ShortId sid) throw() 00108 { return (bool) ((sid & 0x80000000) != 0); }; 00109 00110 // The repository provides ShortIds for immutable directories as 00111 // well as files. One bit of a non-leaf ShortId is a flag to 00112 // indicate whether the ShortId is a directory. 00113 static inline bool dirShortId(ShortId sid) throw() 00114 { return (bool) ((sid & 0xc0000000) == 0x40000000); }; 00115 00116 // Convert ShortId to filename. If tailOnly is true, the name is 00117 // relative to [Repository]metadata_root as defined in the 00118 // vesta.cfg file. If tailOnly is false, the metadata root local 00119 // name (see above) is prepended, so the returned name can be used 00120 // directly in the current process, but not necessarily in any 00121 // other process. The caller is responsible for freeing the 00122 // storage allocated. Applying this method to a dirShortId is 00123 // invalid. 00124 static char* shortIdToName(ShortId sid, bool tailOnly =true) throw(); 00125 00126 // Release server resources held by this process. It is polite 00127 // (but not essential) to call this routine before exiting. 00128 // Details: The routine releases a "stock" of ShortIds that are 00129 // reserved by this process. If it is not called, the stock will 00130 // eventually be freed anyway when its lease expires. 00131 static void releaseResources() throw(); 00132 00133 // Update the last-modified time of a SourceOrDerived to the 00134 // current time. This "renews the lease" on the SourceOrDerived; 00135 // i.e., protects it from deletion by the weeding machinery. 00136 // Returns false if the sid did not exist (or could not be touched 00137 // for some other reason); this is a fatal error in the expected 00138 // use of this function. 00139 static bool touch(ShortId sid) throw(); 00140 00141 // 00142 // Weeder interface. 00143 // 00144 00145 // The repository is free to delete any SourceOrDerived that is 00146 // not a source (that is, does not have a pathname in the 00147 // repository source name space), that is not a descendent in the 00148 // namespace of an immutable directory whose ShortId is in ds, 00149 // that does not have its own ShortId listed in ds, and whose 00150 // last-modified time is less than dt. 00151 // 00152 // Initially ds = NullShortId (representing the empty set) and dt 00153 // = 0 (a time far in the past, which causes everything to be 00154 // kept). Calls to keepDerived update these values, and they are 00155 // retained stably across repository restarts. The file ds must 00156 // contain its own ShortId. 00157 // 00158 // In the implementation, keepDerived also asks the repository 00159 // to recompute its notion of which SourceOrDeriveds are sources 00160 // ("source weed") and to delete SourceOrDeriveds that are not 00161 // required to be kept. The call does not return until the 00162 // weeding and deletions are finished. The return value is 0 for 00163 // success, otherwise an errno value. Some disk space is required 00164 // for these operations, so ENOSPC is a possible error. 00165 // 00166 // If keepDerived is called a second time with the same 00167 // parameters, the second call will wait for the first to 00168 // complete. Then if force is false and the first call was 00169 // successful, the second call will return 0 without taking any 00170 // further action. If force is true, the second call will start a 00171 // new weed even if the first one succeeded. 00172 // 00173 static int keepDerived(ShortIdsFile ds, time_t dt, bool force =false) 00174 throw(SRPC::failure); 00175 00176 // checkpoint() tells the repository to checkpoint its internal 00177 // state, thereby trucating its recovery log and speeding up 00178 // recovery after future crashes. The checkpoint will be smaller 00179 // if keepDerived was called recently. Warning: The repository 00180 // will crash and restart if there is not enough disk space to 00181 // write the checkpoint. 00182 static void checkpoint() throw(SRPC::failure); 00183 00184 // Get the current state of the various low-level weeding 00185 // parameters. <ds, dt> are the values described above. <ss, st> 00186 // are corresponding values for sources, as determined internally 00187 // by the last completed source weed. 00188 static void getWeedingState(ShortIdsFile& ds, time_t& dt, 00189 ShortIdsFile& ss, time_t& st, 00190 bool& sourceWeedInProgress, 00191 bool& deletionsInProgress, 00192 bool& deletionsDone, 00193 bool& checkpointInProgress) 00194 throw (SRPC::failure); 00195 }; 00196 00197 #endif // _VSOD