DriveCatalogue.cpp 32.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/******************************************************************************
 *                castor/tape/tapeserver/daemon/DriveCatalogue.cpp
 *
 * 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.
 *
 *
 *
 * @author Steven.Murray@cern.ch
 *****************************************************************************/

#include "castor/tape/tapeserver/daemon/DriveCatalogue.hpp"
26
#include "castor/utils/utils.hpp"
27
#include "castor/legacymsg/TapeUpdateDriveRqstMsgBody.hpp"
28
29

#include <string.h>
Daniele Kruse's avatar
Daniele Kruse committed
30
#include <time.h>
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//-----------------------------------------------------------------------------
// destructor
//-----------------------------------------------------------------------------
castor::tape::tapeserver::daemon::DriveCatalogue::~DriveCatalogue() throw() {
  // 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();
     itor++) {
    const DriveState driveState = itor->second.state;
    const SessionType sessionType = itor->second.sessionType;
    const int labelCmdConnection = itor->second.labelCmdConnection;

    if(DRIVE_STATE_WAITLABEL == driveState &&
      SESSION_TYPE_LABEL == sessionType &&
      -1 != labelCmdConnection) {
      close(labelCmdConnection);
    }
  }
}

52
//-----------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
53
// drvState2Str
54
//-----------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
55
const char *castor::tape::tapeserver::daemon::DriveCatalogue::drvState2Str(
56
  const DriveState state) throw() {
57
  switch(state) {
58
59
60
61
62
63
64
65
  case DRIVE_STATE_INIT     : return "INIT";
  case DRIVE_STATE_DOWN     : return "DOWN";
  case DRIVE_STATE_UP       : return "UP";
  case DRIVE_STATE_WAITFORK : return "WAITFORK";
  case DRIVE_STATE_WAITLABEL: return "WAITLABEL";
  case DRIVE_STATE_RUNNING  : return "RUNNING";
  case DRIVE_STATE_WAITDOWN : return "WAITDOWN";
  default                   : return "UNKNOWN";
66
67
68
  }
}

Steven Murray's avatar
Steven Murray committed
69
70
71
72
73
74
75
76
77
78
79
80
81
//-----------------------------------------------------------------------------
// mountSessionType2Str
//-----------------------------------------------------------------------------
const char *castor::tape::tapeserver::daemon::DriveCatalogue::sessionType2Str(
  const SessionType sessionType) throw() {
  switch(sessionType) {
  case SESSION_TYPE_NONE        : return "NONE";
  case SESSION_TYPE_DATATRANSFER: return "DATATRANSFER";
  case SESSION_TYPE_LABEL       : return "LABEL";
  default                       : return "UNKNOWN";
  }
}

82
83
84
85
//-----------------------------------------------------------------------------
// populateCatalogue
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogue::populateCatalogue(
86
  const utils::TpconfigLines &lines)  {
87

88
  // Enter each TPCONFIG line into the catalogue
89
90
91
92
93
94
95
96
97
98
  for(utils::TpconfigLines::const_iterator itor = lines.begin();
    itor != lines.end(); itor++) {
    enterTpconfigLine(*itor);
  }
}

//-----------------------------------------------------------------------------
// enterTpconfigLine
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogue::enterTpconfigLine(
99
  const utils::TpconfigLine &line)  {
100
101
102
103
104
105
106
107
108
109

  DriveMap::iterator itor = m_drives.find(line.unitName);

  // If the drive is not in the catalogue
  if(m_drives.end() == itor) {
    // Insert it
    DriveEntry entry;
    entry.dgn = line.dgn;
    entry.devFilename = line.devFilename;
    entry.densities.push_back(line.density);
110
    entry.state = DRIVE_STATE_DOWN;
111
    entry.librarySlot = line.librarySlot;
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
    entry.devType = line.devType;
    m_drives[line.unitName] = entry;
  // Else the drive is already in the catalogue
  } else {
    checkTpconfigLine(itor->second, line);

    // Each TPCONFIG line for a given drive specifies a new tape density
    //
    // Add the new density to the list of supported densities already stored
    // within the tape-drive catalogue
    itor->second.densities.push_back(line.density);
  }
}

//-----------------------------------------------------------------------------
// checkTpconfigLine
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogue::checkTpconfigLine(
  const DriveEntry &catalogueEntry, const utils::TpconfigLine &line)
131
   {
132
133
134
  checkTpconfigLineDgn(catalogueEntry.dgn, line);
  checkTpconfigLineDevFilename(catalogueEntry.devFilename, line);
  checkTpconfigLineDensity(catalogueEntry.densities, line);
135
  checkTpconfigLineLibrarySlot(catalogueEntry.librarySlot, line);
136
137
138
139
140
141
142
143
  checkTpconfigLineDevType(catalogueEntry.devType, line);
}

//-----------------------------------------------------------------------------
// checkTpconfigLineDgn
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogue::checkTpconfigLineDgn(
  const std::string &catalogueDgn, const utils::TpconfigLine &line)
144
   {
145
  if(catalogueDgn != line.dgn) {
146
    castor::exception::Exception ex;
147
148
149
150
151
152
153
154
155
156
157
158
    ex.getMessage() << "Invalid TPCONFIG line"
      ": A tape drive can only be asscoiated with one DGN"
      ": catalogueDgn=" << catalogueDgn << " lineDgn=" << line.dgn;
    throw ex;
  }
}

//-----------------------------------------------------------------------------
// checkTpconfigLineDevFilename
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogue::
  checkTpconfigLineDevFilename(const std::string &catalogueDevFilename,
159
  const utils::TpconfigLine &line)  {
160
  if(catalogueDevFilename != line.devFilename) {
161
    castor::exception::Exception ex;
162
163
164
165
166
167
168
169
170
171
172
173
174
    ex.getMessage() << "Invalid TPCONFIG line"
      ": A tape drive can only have one device filename"
      ": catalogueDevFilename=" << catalogueDevFilename <<
      " lineDevFilename=" << line.devFilename;
    throw ex;
  }
}

//-----------------------------------------------------------------------------
// checkTpconfigLineDensity
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogue::checkTpconfigLineDensity(
  const std::list<std::string> &catalogueDensities,
175
  const utils::TpconfigLine &line)  {
176
177
178
  for(std::list<std::string>::const_iterator itor = catalogueDensities.begin();
    itor != catalogueDensities.end(); itor++) {
    if((*itor) == line.density) {
179
      castor::exception::Exception ex;
180
181
182
183
184
185
186
187
188
      ex.getMessage() << "Invalid TPCONFIG line"
        ": A tape drive can only be associated with a tape density once"
        ": repeatedDensity=" << line.density;
      throw ex;
    }
  }
}

//-----------------------------------------------------------------------------
189
// checkTpconfigLineLibrarySlot
190
191
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogue::
192
193
  checkTpconfigLineLibrarySlot(
  const std::string &catalogueLibrarySlot,
194
  const utils::TpconfigLine &line)  {
195
  if(catalogueLibrarySlot != line.librarySlot) {
196
    castor::exception::Exception ex;
197
    ex.getMessage() << "Invalid TPCONFIG line"
198
199
200
      ": A tape drive can only have one slot within its library"
      ": catalogueLibrarySlot=" << catalogueLibrarySlot <<
      " lineLibrarySlot=" << line.librarySlot;
201
202
203
204
205
206
207
208
209
    throw ex;
  }
}

//-----------------------------------------------------------------------------
// checkTpconfigLineDevType
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogue::
  checkTpconfigLineDevType(const std::string &catalogueDevType,
210
  const utils::TpconfigLine &line)  {
211
  if(catalogueDevType != line.devType) {
212
    castor::exception::Exception ex;
213
214
215
216
217
218
219
220
    ex.getMessage() << "Invalid TPCONFIG line"
      ": A tape drive can only have one device type"
      ": catalogueDevType=" << catalogueDevType <<
      " lineDevType=" << line.devType;
    throw ex;
  }
}

Steven Murray's avatar
Steven Murray committed
221
222
223
//-----------------------------------------------------------------------------
// getUnitName
//-----------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
224
std::string castor::tape::tapeserver::daemon::DriveCatalogue::getUnitName(
225
  const pid_t sessionPid) const  {
Steven Murray's avatar
Steven Murray committed
226
227

  for(DriveMap::const_iterator i = m_drives.begin(); i!=m_drives.end(); i++) {
Steven Murray's avatar
Steven Murray committed
228
229
    if(sessionPid == i->second.sessionPid) return i->first;
  }
230
  castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
231
232
233
234
235
  ex.getMessage() << "Failed to find the unit name of the tape drive on which "
    << "the session with process ID " << sessionPid << " is running.";
  throw ex;
}

236
237
238
//-----------------------------------------------------------------------------
// getUnitNames
//-----------------------------------------------------------------------------
239
std::list<std::string> castor::tape::tapeserver::daemon::DriveCatalogue::getUnitNames() const  {
240
241
242
243
244
245
246
247
248
249
  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;
}

250
251
252
//-----------------------------------------------------------------------------
// getUnitNames
//-----------------------------------------------------------------------------
253
std::list<std::string> castor::tape::tapeserver::daemon::DriveCatalogue::getUnitNames(const DriveState state) const  {
254
255
256
257
258
259
260
261
262
263
264
265
  std::list<std::string> unitNames;

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

  return unitNames;
}

266
267
268
269
//-----------------------------------------------------------------------------
// getDgn
//-----------------------------------------------------------------------------
const std::string &castor::tape::tapeserver::daemon::DriveCatalogue::getDgn(
270
  const std::string &unitName) const  {
271
272
  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
273
    castor::exception::Exception ex;
274
    ex.getMessage() << "Failed to get DGN of tape drive " <<
Steven Murray's avatar
Steven Murray committed
275
      unitName << ": Unknown drive";
276
277
278
279
280
281
    throw ex;
  }

  return itor->second.dgn;
}

282
283
284
285
//-----------------------------------------------------------------------------
// getVid
//-----------------------------------------------------------------------------
const std::string &castor::tape::tapeserver::daemon::DriveCatalogue::getVid(
286
  const std::string &unitName) const  {
287
288
  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
289
    castor::exception::Exception ex;
290
291
292
293
294
295
296
297
298
299
300
301
    ex.getMessage() << "Failed to get VID of tape drive " <<
      unitName << ": Unknown drive";
    throw ex;
  }

  return itor->second.vid;
}

//-----------------------------------------------------------------------------
// getAssignmentTime
//-----------------------------------------------------------------------------
time_t castor::tape::tapeserver::daemon::DriveCatalogue::getAssignmentTime(
302
  const std::string &unitName) const  {
303
304
  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
305
    castor::exception::Exception ex;
306
307
308
309
310
311
312
313
    ex.getMessage() << "Failed to get the assignment time of tape drive " <<
      unitName << ": Unknown drive";
    throw ex;
  }

  return itor->second.assignment_time;
}

314
315
316
317
318
//-----------------------------------------------------------------------------
// getDevFilename
//-----------------------------------------------------------------------------
const std::string
  &castor::tape::tapeserver::daemon::DriveCatalogue::getDevFilename(
319
    const std::string &unitName) const  {
320
321
  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
322
    castor::exception::Exception ex;
323
    ex.getMessage() << "Failed to get the device filename of tape drive " <<
Steven Murray's avatar
Steven Murray committed
324
      unitName << ": Unknown drive";
325
326
327
328
329
330
331
332
333
334
335
    throw ex;
  }

  return itor->second.devFilename;
}

//-----------------------------------------------------------------------------
// getDensities
//-----------------------------------------------------------------------------
const std::list<std::string>
  &castor::tape::tapeserver::daemon::DriveCatalogue::getDensities(
336
    const std::string &unitName) const  {
337
338
  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
339
    castor::exception::Exception ex;
340
    ex.getMessage() << "Failed to get the supported taep densities of tape"
Steven Murray's avatar
Steven Murray committed
341
      " drive " << unitName << ": Unknown drive";
342
343
344
345
346
347
    throw ex;
  }

  return itor->second.densities;
}

Steven Murray's avatar
Steven Murray committed
348
349
350
351
352
//-----------------------------------------------------------------------------
// getSessionType
//-----------------------------------------------------------------------------
castor::tape::tapeserver::daemon::DriveCatalogue::SessionType
  castor::tape::tapeserver::daemon::DriveCatalogue::getSessionType(
353
  const pid_t sessionPid) const  {
Steven Murray's avatar
Steven Murray committed
354
355
356
357
358
359
360
  std::ostringstream task;
  task << "get the type of the session with pid " << sessionPid;

  std::string unitName;
  try {
    unitName = getUnitName(sessionPid);
  } catch(castor::exception::Exception &ne) {
361
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
362
363
364
365
366
367
    ex.getMessage() << "Failed to " << task.str() << ": " << ne.getMessage();
    throw ex;
  }

  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
368
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
369
370
371
372
373
374
375
376
    ex.getMessage() << "Failed to " << task.str() << ": unit name " <<
      unitName << " is not known";
    throw ex;
  }

  return itor->second.sessionType;
}

377
378
379
380
381
//-----------------------------------------------------------------------------
// getState
//-----------------------------------------------------------------------------
castor::tape::tapeserver::daemon::DriveCatalogue::DriveState
  castor::tape::tapeserver::daemon::DriveCatalogue::getState(
382
  const std::string &unitName) const  {
383
384
  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
385
    castor::exception::Exception ex;
386
    ex.getMessage() << "Failed to get current state of tape drive " <<
Steven Murray's avatar
Steven Murray committed
387
      unitName << ": Unknown drive";
388
389
390
391
392
393
    throw ex;
  }

  return itor->second.state;
}

394
//-----------------------------------------------------------------------------
395
// getLibrarySlot
396
397
//-----------------------------------------------------------------------------
const std::string &
398
  castor::tape::tapeserver::daemon::DriveCatalogue::getLibrarySlot(
399
    const std::string &unitName) const  {
400
401
  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
402
    castor::exception::Exception ex;
403
404
    ex.getMessage() << "Failed to get library slot of tape drive " << unitName
      << ": Unknown drive";
405
406
407
    throw ex;
  }

408
  return itor->second.librarySlot;
409
410
411
412
413
414
415
}

//-----------------------------------------------------------------------------
// getDevType
//-----------------------------------------------------------------------------
const std::string &
  castor::tape::tapeserver::daemon::DriveCatalogue::getDevType(
416
    const std::string &unitName) const  {
417
418
  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
419
    castor::exception::Exception ex;
Daniele Kruse's avatar
Daniele Kruse committed
420
    ex.getMessage() << "Failed to get device type of tape drive " << unitName <<
Steven Murray's avatar
Steven Murray committed
421
      ": Unknown drive";
422
423
424
425
426
427
    throw ex;
  }

  return itor->second.devType;
}

428
429
430
//-----------------------------------------------------------------------------
// getTapeMode
//-----------------------------------------------------------------------------
431
castor::legacymsg::TapeUpdateDriveRqstMsgBody::TapeMode castor::tape::tapeserver::daemon::DriveCatalogue::getTapeMode(
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
    const std::string &unitName) const  {
  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to get device type of tape drive " << unitName <<
      ": Unknown drive";
    throw ex;
  }

  return itor->second.mode;
}

//-----------------------------------------------------------------------------
// getTapeEvent
//-----------------------------------------------------------------------------
447
castor::legacymsg::TapeUpdateDriveRqstMsgBody::TapeEvent castor::tape::tapeserver::daemon::DriveCatalogue::getTapeEvent(
448
449
450
451
452
453
454
455
456
457
458
459
    const std::string &unitName) const  {
  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to get device type of tape drive " << unitName <<
      ": Unknown drive";
    throw ex;
  }

  return itor->second.event;
}

460
//-----------------------------------------------------------------------------
Daniele Kruse's avatar
Daniele Kruse committed
461
462
// updateVidAssignment
//-----------------------------------------------------------------------------
463
464
void castor::tape::tapeserver::daemon::DriveCatalogue::updateDriveVolumeInfo(
  const legacymsg::TapeUpdateDriveRqstMsgBody &body)
465
   {
Daniele Kruse's avatar
Daniele Kruse committed
466
  std::ostringstream task;
467
  task << "update the VID of tape drive " << body.drive;
Daniele Kruse's avatar
Daniele Kruse committed
468

469
  DriveMap::iterator itor = m_drives.find(body.drive);
Daniele Kruse's avatar
Daniele Kruse committed
470
  if(m_drives.end() == itor) {
471
    castor::exception::Exception ex;
Daniele Kruse's avatar
Daniele Kruse committed
472
473
474
475
    ex.getMessage() << "Failed to " << task.str() << ": Unknown drive";
    throw ex;
  }
  
476
  itor->second.vid = body.vid;
477
  if(castor::legacymsg::TapeUpdateDriveRqstMsgBody::TAPE_STATUS_BEFORE_MOUNT_STARTED == body.event) {    
478
479
    itor->second.assignment_time = time(0); // set to "now"
  }
480
481
  itor->second.event = (castor::legacymsg::TapeUpdateDriveRqstMsgBody::TapeEvent)body.event;
  itor->second.mode = (castor::legacymsg::TapeUpdateDriveRqstMsgBody::TapeMode)body.mode;
Daniele Kruse's avatar
Daniele Kruse committed
482
483
}

Steven Murray's avatar
Steven Murray committed
484
//-----------------------------------------------------------------------------
485
// releaseLabelCmdConnection
Steven Murray's avatar
Steven Murray committed
486
//-----------------------------------------------------------------------------
487
int castor::tape::tapeserver::daemon::DriveCatalogue::releaseLabelCmdConnection(
488
  const std::string &unitName)  {
Steven Murray's avatar
Steven Murray committed
489
490
  std::ostringstream task;
  task << "get the file-descriptor of the connection with the label command"
491
    " associated with tape drive " << unitName;
Steven Murray's avatar
Steven Murray committed
492

493
  DriveMap::iterator itor = m_drives.find(unitName);
Steven Murray's avatar
Steven Murray committed
494
  if(m_drives.end() == itor) {
495
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
496
497
498
499
500
501
502
503
504
    ex.getMessage() << "Failed to " << task.str() << ": unit name " <<
      unitName << " is not known";
    throw ex;
  }

  const DriveState driveState = itor->second.state;
  const SessionType sessionType = itor->second.sessionType;
  if(DRIVE_STATE_WAITLABEL != driveState &&
    SESSION_TYPE_LABEL != sessionType) {
505
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
506
507
508
509
510
511
    ex.getMessage() << "Failed to " << task.str() <<
      ": Invalid drive state and session type: driveState=" <<
      drvState2Str(driveState) << " sessionType=" <<
      sessionType2Str(sessionType);
    throw ex;
  }
512
513
514
515
516
517
518
519
520
521

  if(-1 == itor->second.labelCmdConnection) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to " << task.str() <<
      ": Connection with label command already released";
    throw ex;
  }

  const int labelCmdConnection = itor->second.labelCmdConnection;
  itor->second.labelCmdConnection = -1;
522
  
523
  return labelCmdConnection;
Steven Murray's avatar
Steven Murray committed
524
525
}

Daniele Kruse's avatar
Daniele Kruse committed
526
//-----------------------------------------------------------------------------
527
528
// configureUp
//-----------------------------------------------------------------------------
529
void castor::tape::tapeserver::daemon::DriveCatalogue::configureUp(const std::string &unitName)  {
Steven Murray's avatar
Steven Murray committed
530
531
532
  std::ostringstream task;
  task << "configure tape drive " << unitName << " up";

533
534
  DriveMap::iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
535
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
536
    ex.getMessage() << "Failed to " << task.str() << ": Unknown drive";
537
538
539
    throw ex;
  }

Steven Murray's avatar
Steven Murray committed
540
  switch(itor->second.state) {
Daniele Kruse's avatar
Daniele Kruse committed
541
  case DRIVE_STATE_UP:
542
  case DRIVE_STATE_RUNNING:
Daniele Kruse's avatar
Daniele Kruse committed
543
    break;
Steven Murray's avatar
Steven Murray committed
544
545
546
547
548
549
550
551
  case DRIVE_STATE_DOWN:
    itor->second.state = DRIVE_STATE_UP;
    break;
  case DRIVE_STATE_WAITDOWN:
    itor->second.state = DRIVE_STATE_RUNNING;
    break;
  default:
    {
552
      castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
553
554
555
556
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(itor->second.state);
      throw ex;
    }
557
558
559
560
561
562
563
  }
}

//-----------------------------------------------------------------------------
// configureDown
//-----------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::DriveCatalogue::configureDown(
564
  const std::string &unitName)  {
Steven Murray's avatar
Steven Murray committed
565
566
567
568
  std::ostringstream task;
  task << "configure tape drive " << unitName << " down";


569
570
  DriveMap::iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
571
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
572
    ex.getMessage() << "Failed to " << task.str() << ": Unknown drive";
573
574
575
    throw ex;
  }

Steven Murray's avatar
Steven Murray committed
576
  switch(itor->second.state) {
Daniele Kruse's avatar
Daniele Kruse committed
577
578
  case DRIVE_STATE_DOWN:
    break;
Steven Murray's avatar
Steven Murray committed
579
580
581
582
583
584
585
586
  case DRIVE_STATE_UP:
    itor->second.state = DRIVE_STATE_DOWN;
    break;
  case DRIVE_STATE_RUNNING:
    itor->second.state = DRIVE_STATE_WAITDOWN;
    break;
  default:
    {
587
      castor::exception::Exception ex;  
Steven Murray's avatar
Steven Murray committed
588
589
590
591
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(itor->second.state);
      throw ex;
    }
592
593
594
595
  } 
}

//-----------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
596
// receivedVdqmJob
597
//-----------------------------------------------------------------------------
598
void castor::tape::tapeserver::daemon::DriveCatalogue::receivedVdqmJob(const legacymsg::RtcpJobRqstMsgBody &job)  {
599
600
  const std::string unitName(job.driveUnit);

Steven Murray's avatar
Steven Murray committed
601
602
603
  std::ostringstream task;
  task << "handle vdqm job for tape drive " << unitName;

604
605
  DriveMap::iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
606
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
607
    ex.getMessage() << "Failed to " << task.str() << ": Unknown drive";
608
609
610
    throw ex;
  }

Steven Murray's avatar
Steven Murray committed
611
612
613
  switch(itor->second.state) {
  case DRIVE_STATE_UP:
    if(std::string(job.dgn) != itor->second.dgn) {
614
      castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
615
      ex.getMessage() << "Failed to " << task.str() <<
616
        ": DGN mismatch: catalogueDgn=" << itor->second.dgn << " vdqmJobDgn=" << job.dgn;
Steven Murray's avatar
Steven Murray committed
617
618
      throw ex;
    }
Daniele Kruse's avatar
Daniele Kruse committed
619
    itor->second.vdqmJob = job;
Steven Murray's avatar
Steven Murray committed
620
621
622
623
    itor->second.state = DRIVE_STATE_WAITFORK;
    break;
  default:
    {
624
      castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
625
626
627
628
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(itor->second.state);
      throw ex;
    }
629
  }
Steven Murray's avatar
Steven Murray committed
630
631
}

632
633
634
//-----------------------------------------------------------------------------
// receivedLabelJob
//-----------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
635
636
void castor::tape::tapeserver::daemon::DriveCatalogue::receivedLabelJob(
  const legacymsg::TapeLabelRqstMsgBody &job, const int labelCmdConnection)
637
   {
Daniele Kruse's avatar
Daniele Kruse committed
638
639
640
641
642
643
644
  const std::string unitName(job.drive);

  std::ostringstream task;
  task << "handle label job for tape drive " << unitName;

  DriveMap::iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
645
    castor::exception::Exception ex;
Daniele Kruse's avatar
Daniele Kruse committed
646
647
648
649
650
651
652
    ex.getMessage() << "Failed to " << task.str() << ": Unknown drive";
    throw ex;
  }

  switch(itor->second.state) {
  case DRIVE_STATE_UP:
    if(std::string(job.dgn) != itor->second.dgn) {
653
      castor::exception::Exception ex;
Daniele Kruse's avatar
Daniele Kruse committed
654
      ex.getMessage() << "Failed to " << task.str() <<
655
        ": DGN mismatch: catalogueDgn=" << itor->second.dgn << " labelJobDgn=" << job.dgn;
Daniele Kruse's avatar
Daniele Kruse committed
656
657
      throw ex;
    }
658
659
660
661
662
663
    if(-1 != itor->second.labelCmdConnection) {
      castor::exception::Exception ex;
      ex.getMessage() << "Failed to " << task.str() <<
        ": Drive catalogue already owns a label-command connection";
      throw ex;
    }
Daniele Kruse's avatar
Daniele Kruse committed
664
    itor->second.labelJob = job;
Steven Murray's avatar
Steven Murray committed
665
    itor->second.labelCmdConnection = labelCmdConnection;
Daniele Kruse's avatar
Daniele Kruse committed
666
667
668
669
    itor->second.state = DRIVE_STATE_WAITLABEL;
    break;
  default:
    {
670
      castor::exception::Exception ex;
Daniele Kruse's avatar
Daniele Kruse committed
671
672
673
674
675
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(itor->second.state);
      throw ex;
    }
  }
676
677
}

Steven Murray's avatar
Steven Murray committed
678
//-----------------------------------------------------------------------------
Daniele Kruse's avatar
Daniele Kruse committed
679
// getVdqmJob
Steven Murray's avatar
Steven Murray committed
680
//-----------------------------------------------------------------------------
681
const castor::legacymsg::RtcpJobRqstMsgBody &castor::tape::tapeserver::daemon::DriveCatalogue::getVdqmJob(const std::string &unitName) const  {
Steven Murray's avatar
Steven Murray committed
682
683
  std::ostringstream task;
  task << "get vdqm job for tape drive " << unitName;
684

Steven Murray's avatar
Steven Murray committed
685
686
  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
687
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
688
    ex.getMessage() << "Failed to " << task.str() << ": Unknown drive";
689
690
691
    throw ex;
  }

Steven Murray's avatar
Steven Murray committed
692
693
694
695
  switch(itor->second.state) {
  case DRIVE_STATE_WAITFORK:
  case DRIVE_STATE_RUNNING:
  case DRIVE_STATE_WAITDOWN:
Daniele Kruse's avatar
Daniele Kruse committed
696
697
698
    return itor->second.vdqmJob;
  default:
    {
699
      castor::exception::Exception ex;
Daniele Kruse's avatar
Daniele Kruse committed
700
701
702
703
704
705
706
707
708
709
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(itor->second.state);
      throw ex;
    }
  }
}

//-----------------------------------------------------------------------------
// getLabelJob
//-----------------------------------------------------------------------------
710
const castor::legacymsg::TapeLabelRqstMsgBody &castor::tape::tapeserver::daemon::DriveCatalogue::getLabelJob(const std::string &unitName) const  {
Daniele Kruse's avatar
Daniele Kruse committed
711
712
713
714
715
  std::ostringstream task;
  task << "get label job for tape drive " << unitName;

  DriveMap::const_iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
716
    castor::exception::Exception ex;
Daniele Kruse's avatar
Daniele Kruse committed
717
718
719
720
721
    ex.getMessage() << "Failed to " << task.str() << ": Unknown drive";
    throw ex;
  }

  switch(itor->second.state) {
722
  case DRIVE_STATE_WAITLABEL:
Daniele Kruse's avatar
Daniele Kruse committed
723
724
725
  case DRIVE_STATE_RUNNING:
  case DRIVE_STATE_WAITDOWN:
    return itor->second.labelJob;
Steven Murray's avatar
Steven Murray committed
726
727
  default:
    {
728
      castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
729
730
731
732
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(itor->second.state);
      throw ex;
    }
733
  }
734
735
736
}

//-----------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
737
// forkedMountSession
738
//-----------------------------------------------------------------------------
739
void castor::tape::tapeserver::daemon::DriveCatalogue::forkedMountSession(const std::string &unitName, const pid_t sessionPid)  {
Steven Murray's avatar
Steven Murray committed
740
741
742
743
  std::ostringstream task;
  task << "handle fork of mount session for tape drive " << unitName;

  DriveMap::iterator itor = m_drives.find(unitName);
744
  if(m_drives.end() == itor) {
745
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
746
    ex.getMessage() << "Failed to " << task.str() << ": Unknown drive";
747
748
749
    throw ex;
  }

Steven Murray's avatar
Steven Murray committed
750
751
752
  switch(itor->second.state) {
  case DRIVE_STATE_WAITFORK:
    itor->second.sessionPid = sessionPid;
Steven Murray's avatar
Steven Murray committed
753
    itor->second.sessionType = SESSION_TYPE_DATATRANSFER;
Steven Murray's avatar
Steven Murray committed
754
755
756
757
    itor->second.state = DRIVE_STATE_RUNNING;
    break;
  default:
    {
758
      castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
759
760
761
762
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(itor->second.state);
      throw ex;
    }
763
764
765
  }
}

766
767
768
//-----------------------------------------------------------------------------
// forkedLabelSession
//-----------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
769
770
void castor::tape::tapeserver::daemon::DriveCatalogue::forkedLabelSession(
  const std::string &unitName, const pid_t sessionPid)
771
   {
Daniele Kruse's avatar
Daniele Kruse committed
772
773
774
775
776
  std::ostringstream task;
  task << "handle fork of label session for tape drive " << unitName;

  DriveMap::iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
777
    castor::exception::Exception ex;
Daniele Kruse's avatar
Daniele Kruse committed
778
779
780
781
782
783
784
    ex.getMessage() << "Failed to " << task.str() << ": Unknown drive";
    throw ex;
  }

  switch(itor->second.state) {
  case DRIVE_STATE_WAITLABEL:
    itor->second.sessionPid = sessionPid;
Steven Murray's avatar
Steven Murray committed
785
    itor->second.sessionType = SESSION_TYPE_LABEL;
Daniele Kruse's avatar
Daniele Kruse committed
786
787
788
789
    itor->second.state = DRIVE_STATE_RUNNING;
    break;
  default:
    {
790
      castor::exception::Exception ex;
Daniele Kruse's avatar
Daniele Kruse committed
791
792
793
794
795
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(itor->second.state);
      throw ex;
    }
  }
796
797
}

798
//-----------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
799
// getSessionPid
800
//-----------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
801
pid_t castor::tape::tapeserver::daemon::DriveCatalogue::getSessionPid(
802
  const std::string &unitName) const  {
Steven Murray's avatar
Steven Murray committed
803
804
805
806
  std::ostringstream task;
  task << "get process ID of mount session for tape drive " << unitName;

  DriveMap::const_iterator itor = m_drives.find(unitName);
807
  if(m_drives.end() == itor) {
808
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
809
    ex.getMessage() << "Failed to " << task.str() << ": Unknown drive";
810
811
812
    throw ex;
  }

Steven Murray's avatar
Steven Murray committed
813
814
815
816
817
  switch(itor->second.state) {
  case DRIVE_STATE_RUNNING:
  case DRIVE_STATE_WAITDOWN:
    return itor->second.sessionPid;
  default:
Steven Murray's avatar
Steven Murray committed
818
    {
819
      castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
820
821
822
823
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(itor->second.state);
      throw ex;
    }
824
  }
Steven Murray's avatar
Steven Murray committed
825
}
826

Steven Murray's avatar
Steven Murray committed
827
//-----------------------------------------------------------------------------
828
// sessionSucceeded
Steven Murray's avatar
Steven Murray committed
829
//-----------------------------------------------------------------------------
830
void castor::tape::tapeserver::daemon::DriveCatalogue::sessionSucceeded(const pid_t sessionPid)  {
Steven Murray's avatar
Steven Murray committed
831
832
833
834
  std::string unitName;
  try {
    unitName = getUnitName(sessionPid);
  } catch(castor::exception::Exception &ne) {
835
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
836
837
838
839
840
841
    ex.getMessage() <<
      "Failed to record tape session succeeded for session with pid " <<
      sessionPid << ": " << ne.getMessage();
    throw ex;
  }

842
  sessionSucceeded(unitName);  
843
844
845
}

//-----------------------------------------------------------------------------
846
// sessionSucceeded
847
//-----------------------------------------------------------------------------
848
void castor::tape::tapeserver::daemon::DriveCatalogue::sessionSucceeded(const std::string &unitName)  {
Steven Murray's avatar
Steven Murray committed
849
850
851
  std::ostringstream task;
  task << "record tape session succeeded for tape drive " << unitName;

852
853
  DriveMap::iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
854
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
855
    ex.getMessage() << "Failed to " << task.str() << ": Unknown drive";
856
857
858
    throw ex;
  }

Steven Murray's avatar
Steven Murray committed
859
860
861
862
863
864
865
866
867
  switch(itor->second.state) {
  case DRIVE_STATE_RUNNING:
    itor->second.state = DRIVE_STATE_UP;
    break;
  case DRIVE_STATE_WAITDOWN:
    itor->second.state = DRIVE_STATE_DOWN;
    break;
  default:
    {
868
      castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
869
870
871
872
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(itor->second.state);
      throw ex;
    }
873
874
  }
}
875
876

//-----------------------------------------------------------------------------
877
// sessionFailed
878
//-----------------------------------------------------------------------------
879
void castor::tape::tapeserver::daemon::DriveCatalogue::sessionFailed(const pid_t sessionPid)  {
880
881
882
883
  std::string unitName;
  try {
    unitName = getUnitName(sessionPid);
  } catch(castor::exception::Exception &ne) {
884
    castor::exception::Exception ex;
885
886
887
888
889
890
891
    ex.getMessage() <<
      "Failed to record tape session failed for session with pid " <<
      sessionPid << ": " << ne.getMessage();
    throw ex;
  }

  sessionFailed(unitName);
892
893
894
}

//-----------------------------------------------------------------------------
895
// sessionFailed
896
//-----------------------------------------------------------------------------
897
void castor::tape::tapeserver::daemon::DriveCatalogue::sessionFailed(const std::string &unitName)  {
Steven Murray's avatar
Steven Murray committed
898
899
900
901
902
  std::ostringstream task;
  task << "record tape session failed for tape drive " << unitName;

  DriveMap::iterator itor = m_drives.find(unitName);
  if(m_drives.end() == itor) {
903
    castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
904
905
906
907
908
909
910
911
912
913
914
    ex.getMessage() << "Failed to " << task.str() << ": Unknown drive";
    throw ex;
  }

  switch(itor->second.state) {
  case DRIVE_STATE_RUNNING:
  case DRIVE_STATE_WAITDOWN:
    itor->second.state = DRIVE_STATE_DOWN;
    break;
  default:
    {
915
      castor::exception::Exception ex;
Steven Murray's avatar
Steven Murray committed
916
917
918
919
920
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(itor->second.state);
      throw ex;
    }
  }
921
}