Catalogue.cpp 9.88 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/******************************************************************************
 *
 * This file is part of the Castor project.
 * See http://castor.web.cern.ch/castor
 *
 * Copyright (C) 2003  CERN
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 *
 *
21
 * @author Castor Dev team, castor-dev@cern.ch
22
23
 *****************************************************************************/

24
#include "castor/tape/tapeserver/daemon/Catalogue.hpp"
25
#include "castor/utils/utils.hpp"
26
27

#include <string.h>
Daniele Kruse's avatar
Daniele Kruse committed
28
#include <time.h>
29

30
31
32
//-----------------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------------
33
castor::tape::tapeserver::daemon::Catalogue::Catalogue(
34
  const int netTimeout,
35
36
  log::Logger &log,
  ProcessForkerProxy &processForker,
37
  legacymsg::CupvProxy &cupv,
38
  legacymsg::VdqmProxy &vdqm,
39
  legacymsg::VmgrProxy &vmgr,
40
  const std::string &hostName):
41
  m_netTimeout(netTimeout),
42
43
  m_log(log),
  m_processForker(processForker),
44
  m_cupv(cupv),
45
  m_vdqm(vdqm),
46
  m_vmgr(vmgr),
47
48
49
  m_hostName(hostName) {
}

50
51
52
//-----------------------------------------------------------------------------
// destructor
//-----------------------------------------------------------------------------
53
castor::tape::tapeserver::daemon::Catalogue::~Catalogue() throw() {
54
55
56
  // Close any label-command connections that are still owned by the
  // tape-drive catalogue
  for(DriveMap::const_iterator itor = m_drives.begin(); itor != m_drives.end();
57
58
    itor++) {
    const CatalogueDrive *const drive = itor->second;
59

Daniele Kruse's avatar
Daniele Kruse committed
60
    delete drive;
Steven Murray's avatar
Steven Murray committed
61
62
63
  }
}

64
65
66
67
68
69
70
71
72
73
74
//-----------------------------------------------------------------------------
// tick
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::Catalogue::tick() {
  for(DriveMap::const_iterator itor = m_drives.begin(); itor != m_drives.end();
    itor++) {
    CatalogueDrive *const drive = itor->second;
    drive->tick();
  }
}

75
//-----------------------------------------------------------------------------
76
// populate
77
//-----------------------------------------------------------------------------
78
void castor::tape::tapeserver::daemon::Catalogue::populate(
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
  const utils::DriveConfigMap &driveConfigs)  {
  try {
    for(utils::DriveConfigMap::const_iterator itor = driveConfigs.begin();
      itor != driveConfigs.end(); itor++) {
      const std::string &unitName = itor->first;
      const utils::DriveConfig &driveConfig = itor->second;

      // Sanity check
      if(unitName != driveConfig.unitName) {
        // This should never happen
        castor::exception::Exception ex;
        ex.getMessage() << "Unit name mismatch: expected=" << unitName <<
          " actual=" << driveConfig.unitName;
        throw ex;
      }
      enterDriveConfig(driveConfig);
    }
  } catch(castor::exception::Exception &ne) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to populate tape-drive catalogue: " <<
      ne.getMessage().str();
    throw ex;
101
102
103
104
  }
}

//-----------------------------------------------------------------------------
105
// enterDriveConfig
106
//-----------------------------------------------------------------------------
107
void castor::tape::tapeserver::daemon::Catalogue::enterDriveConfig(
108
  const utils::DriveConfig &driveConfig)  {
109

110
  DriveMap::iterator itor = m_drives.find(driveConfig.unitName);
111
112
113
114

  // If the drive is not in the catalogue
  if(m_drives.end() == itor) {
    // Insert it
115
    m_drives[driveConfig.unitName] = new CatalogueDrive(m_netTimeout,
116
      m_log, m_processForker, m_cupv, m_vdqm, m_vmgr, m_hostName, driveConfig,
117
      CatalogueDrive::DRIVE_STATE_DOWN);
118
119
  // Else the drive is already in the catalogue
  } else {
120
    castor::exception::Exception ex;
121
122
    ex.getMessage() <<
      "Failed to enter tape-drive configuration into tape-drive catalogue"
Steven Murray's avatar
Steven Murray committed
123
      ": Duplicate drive-entry: unitName=" << driveConfig.unitName;
124
125
126
127
    throw ex;
  }
}

128
129
130
//-----------------------------------------------------------------------------
// getUnitNames
//-----------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
131
std::list<std::string>
132
  castor::tape::tapeserver::daemon::Catalogue::getUnitNames() const  {
133
134
135
136
137
138
139
140
141
142
  std::list<std::string> unitNames;

  for(DriveMap::const_iterator itor = m_drives.begin();
    itor != m_drives.end(); itor++) {
    unitNames.push_back(itor->first);
  }

  return unitNames;
}

Daniele Kruse's avatar
Daniele Kruse committed
143
//-----------------------------------------------------------------------------
144
// findDrive
Daniele Kruse's avatar
Daniele Kruse committed
145
//-----------------------------------------------------------------------------
146
147
const castor::tape::tapeserver::daemon::CatalogueDrive
  &castor::tape::tapeserver::daemon::Catalogue::findDrive(
148
149
150
    const std::string &unitName) const {
  std::ostringstream task;
  task << "find tape drive in catalogue by unit name: unitName=" << unitName;
Daniele Kruse's avatar
Daniele Kruse committed
151

152
153
154
155
156
  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to " << task.str() << ": Entry does not exist";
    throw ex;
Daniele Kruse's avatar
Daniele Kruse committed
157
158
  }

159
160
161
162
163
164
  if(NULL == itor->second) {
    // Should never get here
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to " << task <<
      ": Pointer to drive entry is unexpectedly NULL";
    throw ex;
Daniele Kruse's avatar
Daniele Kruse committed
165
166
  }

167
  const CatalogueDrive &drive = *(itor->second);
168
  const utils::DriveConfig &driveConfig = drive.getConfig();
169

170
171
172
173
174
175
176
177
  // Sanity check
  if(unitName != driveConfig.unitName) {
    // Should never get here
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to " << task <<
      ": Found inconsistent entry in tape-drive catalogue"
      ": Unit name mismatch: actual=" << driveConfig.unitName;
    throw ex;
178
179
  }

180
  return drive;
181
182
}

183
//-----------------------------------------------------------------------------
184
// findDrive
Steven Murray's avatar
Steven Murray committed
185
//-----------------------------------------------------------------------------
186
187
castor::tape::tapeserver::daemon::CatalogueDrive
  &castor::tape::tapeserver::daemon::Catalogue::findDrive(
188
189
190
  const std::string &unitName) {
  std::ostringstream task;
  task << "find tape drive in catalogue by unit name: unitName=" << unitName;
Steven Murray's avatar
Steven Murray committed
191

192
  DriveMap::iterator itor = m_drives.find(unitName);
Steven Murray's avatar
Steven Murray committed
193
194
  if(m_drives.end() == itor) {
    castor::exception::Exception ex;
195
196
197
198
199
200
201
202
203
    ex.getMessage() << "Failed to " << task.str() << ": Entry does not exist";
    throw ex;
  }

  if(NULL == itor->second) {
    // Should never get here
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to " << task <<
      ": Pointer to drive entry is unexpectedly NULL";
Steven Murray's avatar
Steven Murray committed
204
205
    throw ex;
  }
206

207
  CatalogueDrive &drive = *(itor->second);
208
  const utils::DriveConfig &driveConfig = drive.getConfig();
Steven Murray's avatar
Steven Murray committed
209
210

  // Sanity check
211
  if(unitName != driveConfig.unitName) {
Steven Murray's avatar
Steven Murray committed
212
213
    // This should never happen
    castor::exception::Exception ex;
214
    ex.getMessage() << "Failed to " << task <<
Steven Murray's avatar
Steven Murray committed
215
216
      ": Found inconsistent entry in tape-drive catalogue"
      ": Unit name mismatch: expected=" << unitName <<
217
      " actual=" << driveConfig.unitName;
Steven Murray's avatar
Steven Murray committed
218
219
220
221
    throw ex;
  }

  return drive;
222
223
}

224
//-----------------------------------------------------------------------------
225
// findDrive
226
//-----------------------------------------------------------------------------
227
228
const castor::tape::tapeserver::daemon::CatalogueDrive
  &castor::tape::tapeserver::daemon::Catalogue::findDrive(
229
    const pid_t sessionPid) const {
230
231
232
233
234
235
236
237
238
239
240
241
242
243
  std::ostringstream task;
  task << "find tape drive in catalogue by session pid: sessionPid=" <<
    sessionPid;

  for(DriveMap::const_iterator itor = m_drives.begin(); itor != m_drives.end();
    itor++) {

    if(NULL == itor->second) {
      // Should never get here
      castor::exception::Exception ex;
      ex.getMessage() << "Failed to " << task.str() <<
        ": Encountered NULL drive-entry pointer: unitName=" <<  itor->first;
      throw ex;
    }
244

245
    const CatalogueDrive &drive = *(itor->second);
246
    try {
247
      const CatalogueSession &session = drive.getSession();
248
      if(sessionPid == session.getPid()) {
249
250
251
        return drive;
      }
    } catch(...) {
252
      // Ignore any exceptions thrown by getSession()
Steven Murray's avatar
Steven Murray committed
253
    }
254
  }
255

256
  castor::exception::Exception ex;
257
  ex.getMessage() << "Failed to " << task.str() << ": Entry does not exist";
258
  throw ex;
259
260
}

261
//-----------------------------------------------------------------------------
262
// findDrive
263
//-----------------------------------------------------------------------------
264
265
castor::tape::tapeserver::daemon::CatalogueDrive
  &castor::tape::tapeserver::daemon::Catalogue::findDrive(
266
267
268
269
    const pid_t sessionPid) {
  std::ostringstream task;
  task << "find tape drive in catalogue by session pid: sessionPid=" <<
    sessionPid;
Steven Murray's avatar
Steven Murray committed
270

271
272
  for(DriveMap::iterator itor = m_drives.begin(); itor != m_drives.end();
    itor++) {
273

274
275
276
277
278
279
280
    if(NULL == itor->second) {
      // Should never get here
      castor::exception::Exception ex;
      ex.getMessage() << "Failed to " << task.str() <<
        ": Encountered NULL drive-entry pointer: unitName=" <<  itor->first;
      throw ex;
    }
281

282
    CatalogueDrive &drive = *(itor->second);
283
    try {
284
      const CatalogueSession &session = drive.getSession();
285
      if(sessionPid == session.getPid()) {
286
287
288
289
        return drive;
      }
    } catch(...) {
      // Ignore any exceptions thrown by getSessionPid()
Steven Murray's avatar
Steven Murray committed
290
    }
291
  }
Steven Murray's avatar
Steven Murray committed
292

293
  castor::exception::Exception ex;
294
  ex.getMessage() << "Failed to " << task.str() << ": Entry does not exist";
295
  throw ex;
296
}