CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
repository_transaction.cc
Go to the documentation of this file.
1 
6 #include <string>
7 
8 #include "backoff.h"
9 #include "catalog_mgr_ro.h"
10 #include "catalog_mgr_rw.h"
11 #include "directory_entry.h"
12 #include "manifest.h"
13 #include "publish/except.h"
14 #include "publish/repository.h"
16 #include "publish/settings.h"
17 #include "util/exception.h"
18 #include "util/logging.h"
19 #include "util/pointer.h"
20 #include "util/posix.h"
21 
22 namespace publish {
23 
24 
26  bool waiting_on_lease = false;
27  if (managed_node_.IsValid()) {
28  int rvi = managed_node_->Check(false /* is_quiet */);
29  if (rvi != 0)
30  throw EPublish("cannot establish writable mountpoint");
31  }
32 
33  BackoffThrottle throttle(500, 5000, 10000);
34  // Negative timeouts (i.e.: no retry) will result in a deadline that has
35  // already passed and thus has the correct effect
36  uint64_t deadline = platform_monotonic_time()
37  + settings_.transaction().GetTimeoutS();
38  if (settings_.transaction().GetTimeoutS() == 0)
39  deadline = uint64_t(-1);
40 
41  while (true) {
42  try {
43  TransactionImpl(waiting_on_lease);
44  break;
45  } catch (const publish::EPublish &e) {
47  session_->Drop();
49  }
50 
52  || (e.failure() == EPublish::kFailLeaseBusy)) {
53  if (platform_monotonic_time() > deadline)
54  throw;
55 
56  waiting_on_lease = true;
57  LogCvmfs(kLogCvmfs, kLogStdout, "repository busy, retrying");
58  throttle.Throttle();
59  continue;
60  }
61 
62  throw;
63  } // try-catch
64  } // while (true)
65 
66  if (managed_node_.IsValid())
67  managed_node_->Open();
68 }
69 
70 
71 void Publisher::TransactionImpl(bool waiting_on_lease) {
72  if (in_transaction_.IsSet()) {
73  throw EPublish("another transaction is already open",
75  }
76 
77  InitSpoolArea();
78 
79  // On error, Transaction() will release the transaction lock and drop
80  // the session
81  session_->Acquire();
82 
83  // We might have a valid lease for a non-existing path. Nevertheless, we run
84  // run into problems when merging catalogs later, so for the time being we
85  // disallow transactions on non-existing paths.
86  if (!settings_.transaction().lease_path().empty()) {
87  std::string path = GetParentPath("/"
88  + settings_.transaction().lease_path());
91  bool retval = catalog_mgr->LookupPath(path, catalog::kLookupDefault,
92  &dirent);
93  if (!retval) {
94  throw EPublish("cannot open transaction on non-existing path " + path,
96  }
97  if (!dirent.IsDirectory()) {
98  throw EPublish(
99  "cannot open transaction on " + path + ", which is not a directory",
101  }
102  }
103 
104 
106  settings_.transaction().spool_area().checkout_marker()));
107  // TODO(jblomer): take root hash from r/o mountpoint?
108 
109 
110  if (settings_.storage().type() == upload::SpoolerDefinition::Gateway
111  && waiting_on_lease) {
113  settings_.transaction().spool_area().tmp_dir());
114  int rvi = managed_node_->Check(true /* is_quiet */);
115  if (rvi != 0)
116  throw EPublish("cannot establish writable mountpoint");
117  }
118 
121  if (marker.IsValid())
122  settings_.GetTransaction()->SetBaseHash(marker->hash());
123  else
124  settings_.GetTransaction()->SetBaseHash(manifest_->catalog_hash());
125 
126  if (settings_.transaction().HasTemplate()) {
128  "CernVM-FS: cloning template %s --> %s ... ",
129  settings_.transaction().template_from().c_str(),
130  settings_.transaction().template_to().c_str());
132 
133  try {
134  catalog_mgr_->CloneTree(settings_.transaction().template_from(),
135  settings_.transaction().template_to());
136  } catch (const ECvmfsException &e) {
137  std::string panic_msg = e.what();
139  // TODO(aandvalenzuela): release session token (gateway publishing)
140  throw publish::EPublish("cannot clone directory tree. " + panic_msg,
142  }
143 
144  Sync();
146  settings_.transaction().spool_area().readonly_talk_socket(),
147  "chroot " + settings_.transaction().base_hash().ToString() + "\n");
148  LogCvmfs(kLogCvmfs, llvl_ | kLogStdout, "[done]");
149  // TODO(jblomer): fix-me
150  // PushReflog();
151  }
152 
153  LogCvmfs(kLogCvmfs, llvl_ | kLogDebug | kLogSyslog, "(%s) opened transaction",
154  settings_.fqrn().c_str());
155 }
156 
157 } // namespace publish
void TransactionImpl(bool waiting_on_lease=false)
const SettingsRepository settings_
Definition: repository.h:136
void CloneTree(const std::string &from_dir, const std::string &to_dir)
void ConstructSyncManagers()
Definition: repository.cc:705
catalog::SimpleCatalogManager * GetSimpleCatalogManager()
Definition: repository.cc:118
UniquePtr< ManagedNode > managed_node_
Definition: repository.h:380
bool IsDirectory() const
const unsigned kLookupDefault
Definition: catalog_mgr.h:43
catalog::WritableCatalogManager * catalog_mgr_
Definition: repository.h:384
void Throttle()
Definition: backoff.cc:48
shash::Any hash() const
void DownloadRootObjects(const std::string &url, const std::string &fqrn, const std::string &tmp_dir)
Definition: repository.cc:134
void Sync()
Definition: repository.cc:803
void InitSpoolArea()
Definition: repository.cc:596
shash::Any catalog_hash() const
Definition: manifest.h:125
uint64_t platform_monotonic_time()
std::string SendTalkCommand(const std::string &socket, const std::string &cmd)
UniquePtr< Session > session_
Definition: repository.h:379
manifest::Manifest * manifest_
Definition: repository.h:147
EFailures failure() const
Definition: except.h:44
ServerFlagFile in_transaction_
Definition: repository.h:369
PathString GetParentPath(const PathString &path)
Definition: shortstring.cc:14
std::string fqrn() const
Definition: settings.h:366
int llvl_
Definition: repository.h:368
std::string url() const
Definition: settings.h:367
void ConstructSpoolers()
Definition: repository.cc:252
static CheckoutMarker * CreateFrom(const std::string &path)
std::string tmp_dir() const
Definition: settings.h:369
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:545