CatalogueDrive.cpp 28.6 KB
Newer Older
Steven Murray's avatar
Steven Murray committed
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
Steven Murray's avatar
Steven Murray committed
22
23
 *****************************************************************************/

24
#include "castor/common/CastorConfiguration.hpp"
25
#include "castor/exception/Exception.hpp"
26
#include "castor/tape/tapeserver/daemon/CatalogueDrive.hpp"
27
#include "castor/tape/tapeserver/daemon/Constants.hpp"
28
29
#include "castor/utils/utils.hpp"
#include "h/Ctape_constants.h"
30
#include "h/rmc_constants.h"
Steven Murray's avatar
Steven Murray committed
31
32
33
34
35
36

#include <string.h>

//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
37
castor::tape::tapeserver::daemon::CatalogueDrive::CatalogueDrive(
38
  const int netTimeout,
39
40
  log::Logger &log,
  ProcessForkerProxy &processForker,
41
  legacymsg::CupvProxy &cupv,
42
  legacymsg::VdqmProxy &vdqm,
43
  legacymsg::VmgrProxy &vmgr,
44
45
46
  const std::string &hostName,
  const utils::DriveConfig &config,
  const DriveState state)
Steven Murray's avatar
Steven Murray committed
47
  throw():
48
  m_netTimeout(netTimeout),
49
50
  m_log(log),
  m_processForker(processForker),
51
  m_cupv(cupv),
52
  m_vdqm(vdqm),
53
  m_vmgr(vmgr),
54
  m_hostName(hostName),
55
56
  m_config(config),
  m_state(state),
57
  m_sessionType(SESSION_TYPE_NONE),
Daniele Kruse's avatar
Daniele Kruse committed
58
  m_session(NULL) {
59
60
61
}

//------------------------------------------------------------------------------
62
// destructor
63
//------------------------------------------------------------------------------
64
castor::tape::tapeserver::daemon::CatalogueDrive::~CatalogueDrive()
65
  throw() {
66
67
68
  deleteSession();
}

69
70
71
72
73
74
75
76
77
78
79
80
81
//------------------------------------------------------------------------------
// tick
//------------------------------------------------------------------------------
void castor::tape::tapeserver::daemon::CatalogueDrive::tick() {
  try {
    checkForSession();
  } catch(...) {
    return;
  }

  m_session->tick();
}

82
83
84
//------------------------------------------------------------------------------
// deleteSession
//------------------------------------------------------------------------------
85
void castor::tape::tapeserver::daemon::CatalogueDrive::deleteSession() {
86
  delete m_session;
87
  m_session = NULL;
Steven Murray's avatar
Steven Murray committed
88
89
90
91
92
93
}

//-----------------------------------------------------------------------------
// drvState2Str
//-----------------------------------------------------------------------------
const char
94
  *castor::tape::tapeserver::daemon::CatalogueDrive::drvState2Str(
Steven Murray's avatar
Steven Murray committed
95
96
  const DriveState state) throw() {
  switch(state) {
97
98
99
100
101
102
  case DRIVE_STATE_INIT    : return "INIT";
  case DRIVE_STATE_DOWN    : return "DOWN";
  case DRIVE_STATE_UP      : return "UP";
  case DRIVE_STATE_RUNNING : return "RUNNING";
  case DRIVE_STATE_WAITDOWN: return "WAITDOWN";
  default                  : return "UNKNOWN";
Steven Murray's avatar
Steven Murray committed
103
104
105
106
107
108
109
  }
}

//-----------------------------------------------------------------------------
// sessionType2Str
//-----------------------------------------------------------------------------
const char
110
   *castor::tape::tapeserver::daemon::CatalogueDrive::sessionType2Str(
Steven Murray's avatar
Steven Murray committed
111
112
113
  const SessionType sessionType) throw() {
  switch(sessionType) {
  case SESSION_TYPE_NONE        : return "NONE";
114
  case SESSION_TYPE_CLEANER     : return "CLEANER";
Steven Murray's avatar
Steven Murray committed
115
116
117
118
119
  case SESSION_TYPE_DATATRANSFER: return "DATATRANSFER";
  case SESSION_TYPE_LABEL       : return "LABEL";
  default                       : return "UNKNOWN";
  }
}
120
121
122
123
124

//------------------------------------------------------------------------------
// getConfig
//------------------------------------------------------------------------------
const castor::tape::utils::DriveConfig
125
  &castor::tape::tapeserver::daemon::CatalogueDrive::getConfig() const {
126
127
128
129
  return m_config;
}

//------------------------------------------------------------------------------
130
131
// getState
//------------------------------------------------------------------------------
132
133
castor::tape::tapeserver::daemon::CatalogueDrive::DriveState
  castor::tape::tapeserver::daemon::CatalogueDrive::getState()
134
135
136
137
138
139
  const throw() {
  return m_state;
} 

//------------------------------------------------------------------------------
// getSession
140
//------------------------------------------------------------------------------
141
142
const castor::tape::tapeserver::daemon::CatalogueSession &
  castor::tape::tapeserver::daemon::CatalogueDrive::getSession()
143
144
145
146
147
148
149
150
151
152
  const {
  try {
    checkForSession();
    return *m_session;
  } catch(castor::exception::Exception &ne) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to get tape session for drive " <<
      m_config.unitName << " from drive catalogue: " << ne.getMessage().str();
    throw ex;
  }
153
154
155
}

//------------------------------------------------------------------------------
156
// checkForSession
157
//------------------------------------------------------------------------------
158
void castor::tape::tapeserver::daemon::CatalogueDrive::checkForSession()
159
  const {
160
  if(DRIVE_STATE_RUNNING != m_state && DRIVE_STATE_WAITDOWN != m_state) {
161
162
163
164
165
166
167
168
169
170
    castor::exception::Exception ex;
    ex.getMessage() << "Drive is currently not running a session";
    throw ex;
  }
  if(NULL == m_session) {
    // Should never get here
    castor::exception::Exception ex;
    ex.getMessage() << "Pointer to tape session is unexpectedly NULL";
    throw ex;
  }
171
172
173
}

//------------------------------------------------------------------------------
174
// getCleanerSession
175
//------------------------------------------------------------------------------
176
177
const castor::tape::tapeserver::daemon::CatalogueCleanerSession &
  castor::tape::tapeserver::daemon::CatalogueDrive::getCleanerSession()
178
179
180
  const {
  try {
    checkForCleanerSession();
181
182
    const CatalogueCleanerSession *const cleanerSession =
      dynamic_cast<const CatalogueCleanerSession*>(m_session);
183
184
185
186
    if(NULL == cleanerSession) {
      // Should never get here
      castor::exception::Exception ex;
      ex.getMessage() <<
187
        "Failed to cast session to CatalogueCleanerSession";
188
189
190
191
192
193
194
195
196
197
198
      throw ex;
    }

    return *cleanerSession;
  } catch(castor::exception::Exception &ne) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to get cleaner session for drive " <<
      m_config.unitName << " from drive catalogue: " << ne.getMessage().str();
    throw ex;
  }
}
199

Daniele Kruse's avatar
Daniele Kruse committed
200
//------------------------------------------------------------------------------
201
// getCleanerSession
Daniele Kruse's avatar
Daniele Kruse committed
202
//------------------------------------------------------------------------------
203
204
castor::tape::tapeserver::daemon::CatalogueCleanerSession &
  castor::tape::tapeserver::daemon::CatalogueDrive::getCleanerSession() {
205
206
  try {
    checkForCleanerSession();
207
208
    CatalogueCleanerSession *const cleanerSession =
      dynamic_cast<CatalogueCleanerSession*>(m_session);
209
210
211
212
    if(NULL == cleanerSession) {
      // Should never get here
      castor::exception::Exception ex;
      ex.getMessage() << 
213
        "Failed to cast session to CatalogueCleanerSession";
214
215
216
217
218
219
220
221
222
223
      throw ex;
    }

    return *cleanerSession;
  } catch(castor::exception::Exception &ne) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to get cleaner session for drive " <<
      m_config.unitName << " from drive catalogue: " << ne.getMessage().str();
    throw ex;
  }
Daniele Kruse's avatar
Daniele Kruse committed
224
225
226
}

//------------------------------------------------------------------------------
227
// checkForCleanerSession
Daniele Kruse's avatar
Daniele Kruse committed
228
//------------------------------------------------------------------------------
229
void castor::tape::tapeserver::daemon::CatalogueDrive::
230
  checkForCleanerSession() const {
231
  checkForSession();
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
  if(SESSION_TYPE_CLEANER != m_sessionType) {
    castor::exception::Exception ex;
    ex.getMessage() <<
      "Session associated with drive is not a cleaner session"
      ": actual=" << sessionType2Str(m_sessionType);
    throw ex;
  }
  if(NULL == m_session) {
    // Should never get here
    castor::exception::Exception ex;
    ex.getMessage() << "Pointer to cleaner session is unexpectedly NULL";
    throw ex;
  }
}

//------------------------------------------------------------------------------
// getLabelSession
//------------------------------------------------------------------------------
250
251
const castor::tape::tapeserver::daemon::CatalogueLabelSession &
  castor::tape::tapeserver::daemon::CatalogueDrive::getLabelSession()
Daniele Kruse's avatar
Daniele Kruse committed
252
  const {
253
254
  try {
    checkForLabelSession();
255
256
    const CatalogueLabelSession *const labelSession =
      dynamic_cast<const CatalogueLabelSession*>(m_session);
257
258
259
    if(NULL == labelSession) {
      // Should never get here
      castor::exception::Exception ex;
260
      ex.getMessage() << "Failed to cast session to CatalogueLabelSession";
261
262
263
264
265
      throw ex;
    }

    return *labelSession;
  } catch(castor::exception::Exception &ne) {
Daniele Kruse's avatar
Daniele Kruse committed
266
    castor::exception::Exception ex;
267
268
269
270
271
272
273
274
275
    ex.getMessage() << "Failed to get label session for drive " <<
      m_config.unitName << " from drive catalogue: " << ne.getMessage().str();
    throw ex;
  }
}

//------------------------------------------------------------------------------
// getLabelSession
//------------------------------------------------------------------------------
276
277
castor::tape::tapeserver::daemon::CatalogueLabelSession &
  castor::tape::tapeserver::daemon::CatalogueDrive::getLabelSession() {
278
279
  try {
    checkForLabelSession();
280
281
    CatalogueLabelSession *const labelSession =
      dynamic_cast<CatalogueLabelSession*>(m_session);
282
283
284
    if(NULL == labelSession) {
      // Should never get here
      castor::exception::Exception ex;
285
      ex.getMessage() << "Failed to cast session to CatalogueLabelSession";
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
      throw ex;
    }

    return *labelSession;
  } catch(castor::exception::Exception &ne) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to get label session for drive " <<
      m_config.unitName << " from drive catalogue: " << ne.getMessage().str();
    throw ex;
  }
}

//------------------------------------------------------------------------------
// checkForLabelSession
//------------------------------------------------------------------------------
301
void castor::tape::tapeserver::daemon::CatalogueDrive::
302
  checkForLabelSession() const {
303
  checkForSession();
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
  if(SESSION_TYPE_LABEL != m_sessionType) {
    castor::exception::Exception ex;
    ex.getMessage() << "Session associated with drive is not a label session"
      ": actual=" << sessionType2Str(m_sessionType);
    throw ex;
  }
  if(NULL == m_session) {
    // Should never get here
    castor::exception::Exception ex;
    ex.getMessage() << "Pointer to label session is unexpectedly NULL";
    throw ex;
  }
}

//------------------------------------------------------------------------------
// getTransferSession
//------------------------------------------------------------------------------
321
322
const castor::tape::tapeserver::daemon::CatalogueTransferSession &
  castor::tape::tapeserver::daemon::CatalogueDrive::getTransferSession()
323
324
325
  const {
  try {
    checkForTransferSession();
326
327
    CatalogueTransferSession *const transferSession =
      dynamic_cast<CatalogueTransferSession*>(m_session);
328
329
330
331
    if(NULL == transferSession) {
      // Should never get here
      castor::exception::Exception ex;
      ex.getMessage() <<
332
        "Failed to cast session to CatalogueTransferSession";
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
      throw ex;
    }

    return *transferSession;
  } catch(castor::exception::Exception &ne) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to get transfer session for drive " <<
      m_config.unitName << " from drive catalogue: " << ne.getMessage().str();
    throw ex;
  }
}

//------------------------------------------------------------------------------
// getTransferSession
//------------------------------------------------------------------------------
348
349
castor::tape::tapeserver::daemon::CatalogueTransferSession &
  castor::tape::tapeserver::daemon::CatalogueDrive::getTransferSession() {
350
351
  try {
    checkForTransferSession();
352
353
    CatalogueTransferSession *const transferSession =
      dynamic_cast<CatalogueTransferSession*>(m_session);
354
355
356
357
    if(NULL == transferSession) {
      // Should never get here
      castor::exception::Exception ex;
      ex.getMessage() <<
358
        "Failed to cast session to CatalogueTransferSession";
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
      throw ex;
    }

    return *transferSession;
  } catch(castor::exception::Exception &ne) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to get transfer session for drive " <<
      m_config.unitName << " from drive catalogue: " << ne.getMessage().str();
    throw ex;
  }
}

//------------------------------------------------------------------------------
// checkForTransferSession
//------------------------------------------------------------------------------
374
void castor::tape::tapeserver::daemon::CatalogueDrive::
375
  checkForTransferSession() const {
376
  checkForSession();
377
378
379
380
381
382
383
384
385
386
387
  if(SESSION_TYPE_DATATRANSFER != m_sessionType) {
    castor::exception::Exception ex;
    ex.getMessage() <<
      "Session associated with drive is not a transfer session"
      ": actual=" << sessionType2Str(m_sessionType);
    throw ex;
  }
  if(NULL == m_session) {
    // Should never get here
    castor::exception::Exception ex;
    ex.getMessage() << "Pointer to transfer session is unexpectedly NULL";
Daniele Kruse's avatar
Daniele Kruse committed
388
389
390
391
    throw ex;
  }
}

392
393
394
//------------------------------------------------------------------------------
// getSessionType
//------------------------------------------------------------------------------
395
396
castor::tape::tapeserver::daemon::CatalogueDrive::SessionType
  castor::tape::tapeserver::daemon::CatalogueDrive::getSessionType()
397
398
399
400
401
402
403
  const throw() {
  return m_sessionType;
}

//------------------------------------------------------------------------------
// configureUp
//------------------------------------------------------------------------------
404
void castor::tape::tapeserver::daemon::CatalogueDrive::configureUp() {
405
406
  switch(m_state) {
  case DRIVE_STATE_UP:
407
  case DRIVE_STATE_RUNNING:
408
409
410
411
412
    break;
  case DRIVE_STATE_DOWN:
    m_state = DRIVE_STATE_UP;
    break;
  case DRIVE_STATE_WAITDOWN:
413
    m_state = DRIVE_STATE_RUNNING;
414
415
416
417
418
419
420
421
422
    break;
  default:
    {
      castor::exception::Exception ex;
      ex.getMessage() << "Failed to configure tape-drive " << m_config.unitName
        << " up : Incompatible drive state: state=" << drvState2Str(m_state);
      throw ex;
    }
  }
423
  m_vdqm.setDriveUp(m_hostName, m_config.unitName, m_config.dgn);
424
425
426
427
428
}

//-----------------------------------------------------------------------------
// configureDown
//-----------------------------------------------------------------------------
429
void castor::tape::tapeserver::daemon::CatalogueDrive::configureDown() {
430
431
432
433
434
435
  switch(m_state) {
  case DRIVE_STATE_DOWN:
    break;
  case DRIVE_STATE_UP:
    m_state = DRIVE_STATE_DOWN;
    break;
436
  case CatalogueDrive::DRIVE_STATE_RUNNING:
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
    m_state = DRIVE_STATE_WAITDOWN;
    break;
  default:
    {
      castor::exception::Exception ex;
      ex.getMessage() << "Failed to configure tape drive " << m_config.unitName
        << " down: " << ": Incompatible drive state: state=" <<
        drvState2Str(m_state);
      throw ex;
    }
  }
}

//-----------------------------------------------------------------------------
// receivedVdqmJob
//-----------------------------------------------------------------------------
453
void castor::tape::tapeserver::daemon::CatalogueDrive::receivedVdqmJob(
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
  const legacymsg::RtcpJobRqstMsgBody &job)  {

  std::ostringstream task;
  task << "handle vdqm job for tape drive " << m_config.unitName;

  // Sanity check
  if(job.driveUnit != m_config.unitName) {
    // Should never happen
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to " << task.str() <<
      ": unit name mismatch: job.driveUnit=" << job.driveUnit <<
      " m_config.unitName=" << m_config.unitName;
    throw ex;
  }
  
  switch(m_state) {
  case DRIVE_STATE_UP:
    if(std::string(job.dgn) != m_config.dgn) {
      castor::exception::Exception ex;
      ex.getMessage() << "Failed to " << task.str() <<
        ": DGN mismatch: catalogueDgn=" << m_config.dgn << " vdqmJobDgn="
          << job.dgn;
      throw ex;
    }
478
    m_state = DRIVE_STATE_RUNNING;
Daniele Kruse's avatar
Daniele Kruse committed
479
    m_sessionType = SESSION_TYPE_DATATRANSFER;
480
481
482
483
    {
      const unsigned short rmcPort =
        common::CastorConfiguration::getConfig().getConfEntInt("RMC", "PORT",
          (unsigned short)RMC_PORT, &m_log);
484
485
486
      const time_t blockMoveTimeoutInSecs =
        common::CastorConfiguration::getConfig().getConfEntInt("TAPESERVERD",
          "BLKMOVETIMEOUT", TAPESERVER_BLKMOVETIMEOUT_DEFAULT, &m_log);
487
488
      CatalogueTransferSession *const transferSession =
        CatalogueTransferSession::create(
489
490
491
          m_log,
          m_netTimeout,
          m_config,
492
493
494
          job,
          m_vmgr,
          m_cupv,
495
          m_hostName,
496
          blockMoveTimeoutInSecs,
497
498
          rmcPort,
          m_processForker);
499
      m_session = dynamic_cast<CatalogueSession *>(transferSession);
500
501
      m_vdqm.assignDrive(m_hostName, m_config.unitName, job.dgn,
        job.volReqId, m_session->getPid());
502
    }
503
504
505
506
507
508
509
510
511
512
513
514
515
516
    break;
  default:
    {
      castor::exception::Exception ex;
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(m_state);
      throw ex;
    }
  } 
} 

//-----------------------------------------------------------------------------
// receivedLabelJob
//-----------------------------------------------------------------------------
517
void castor::tape::tapeserver::daemon::CatalogueDrive::receivedLabelJob(
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
  const legacymsg::TapeLabelRqstMsgBody &job, const int labelCmdConnection) {
  const std::string unitName(job.drive);

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

  // Sanity check
  if(job.drive != m_config.unitName) {
    // Should never happen
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to " << task.str() <<
      ": unit name mismatch: job.drive=" << job.drive << 
      " m_config.unitName=" << m_config.unitName;
    throw ex;
  }

  switch(m_state) {
  case DRIVE_STATE_UP:
    if(std::string(job.dgn) != m_config.dgn) {
      castor::exception::Exception ex;
      ex.getMessage() << "Failed to " << task.str() <<
        ": DGN mismatch: catalogueDgn=" << m_config.dgn << " labelJobDgn="
        << job.dgn;
      throw ex;
    }
543
544
545
546
    {
      const unsigned short rmcPort =
        common::CastorConfiguration::getConfig().getConfEntInt("RMC", "PORT",
          (unsigned short)RMC_PORT, &m_log);
547
      m_session = CatalogueLabelSession::create(
548
549
550
551
        m_log,
        m_netTimeout,
        m_config,
        job,
Steven Murray's avatar
WIP    
Steven Murray committed
552
553
        labelCmdConnection,
        m_cupv,
554
        rmcPort,
Steven Murray's avatar
WIP    
Steven Murray committed
555
        m_processForker);
556
    }
557
558
    m_state = DRIVE_STATE_RUNNING;
    m_sessionType = SESSION_TYPE_LABEL;
559
560
561
562
563
564
565
566
567
568
569
    break;
  default:
    {
      castor::exception::Exception ex;
      ex.getMessage() << "Failed to " << task.str() <<
        ": Incompatible drive state: state=" << drvState2Str(m_state);
      throw ex;
    }
  }
}

570
//-----------------------------------------------------------------------------
571
// createCleaner
572
//-----------------------------------------------------------------------------
573
void castor::tape::tapeserver::daemon::CatalogueDrive::createCleaner(
574
  const std::string &vid, const time_t assignmentTime) {
575
576
577
578
579
580
581
  try {
    // Create a cleaner session in the catalogue
    m_state = DRIVE_STATE_RUNNING;
    m_sessionType = SESSION_TYPE_CLEANER;
    const unsigned short rmcPort =
      common::CastorConfiguration::getConfig().getConfEntInt("RMC", "PORT",
        (unsigned short)RMC_PORT, &m_log);
582
    m_session = CatalogueCleanerSession::create(
583
      m_log,
584
      m_netTimeout,
585
      m_config,
586
      m_processForker,
587
588
589
590
591
592
593
594
      vid,
      rmcPort,
      assignmentTime);
  } catch(castor::exception::Exception &ne) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to create cleaner session: " <<
      ne.getMessage().str();
    throw ex;
595
  } 
596
597
}

598
599
600
//-----------------------------------------------------------------------------
// sessionSucceeded
//-----------------------------------------------------------------------------
601
void castor::tape::tapeserver::daemon::CatalogueDrive::
602
  sessionSucceeded() {
603
  switch(m_state) {
604
  case DRIVE_STATE_RUNNING:
605
    m_state = DRIVE_STATE_UP;
606
    m_vdqm.setDriveUp(m_hostName, m_config.unitName, m_config.dgn);
607
608
    break;
  case DRIVE_STATE_WAITDOWN:
609
    m_state = CatalogueDrive::DRIVE_STATE_DOWN;
610
    m_vdqm.setDriveDown(m_hostName, m_config.unitName, m_config.dgn);
611
612
613
614
615
616
    break;
  default:
    {
      castor::exception::Exception ex;
      ex.getMessage() <<
        "Failed to record tape session succeeded for session with pid " <<
617
        getSession().getPid() << ": Incompatible drive state: state=" <<
618
        drvState2Str(m_state);
Daniele Kruse's avatar
Daniele Kruse committed
619
620
621
      delete m_session;
      m_session = NULL;
      m_sessionType = SESSION_TYPE_NONE;
622
623
624
      throw ex;
    }
  }
625
626
627

  // Wrap the session in an auto pointer to gaurantee it is deleted even in the
  // event of an exception
628
  std::auto_ptr<CatalogueSession> session(m_session);
629
630
631

  // Set the member variable m_session to NULL to prevent the desstruxtor from
  // trying a double delete
Daniele Kruse's avatar
Daniele Kruse committed
632
633
  m_session = NULL;
  m_sessionType = SESSION_TYPE_NONE;
634
635

  session->sessionSucceeded();
636
637
638
639
640
}

//-----------------------------------------------------------------------------
// sessionFailed
//-----------------------------------------------------------------------------
641
void castor::tape::tapeserver::daemon::CatalogueDrive::sessionFailed() {
642
  switch(m_state) {
643
  case DRIVE_STATE_RUNNING:
644
645
646
647
648
649
650
651
  case DRIVE_STATE_WAITDOWN:
    m_state = DRIVE_STATE_DOWN;
    break;
  default:
    {
      castor::exception::Exception ex;
      ex.getMessage() <<
        "Failed to record tape session failed for session with pid " <<
652
        getSession().getPid() << ": Incompatible drive state: state=" <<
653
        drvState2Str(m_state);
Daniele Kruse's avatar
Daniele Kruse committed
654
655
656
      delete m_session;
      m_session = NULL;
      m_sessionType = SESSION_TYPE_NONE;
657
658
659
      throw ex;
    }
  }
660

661
662
  m_vdqm.setDriveDown(m_hostName, m_config.unitName, m_config.dgn);

663
664
  // Wrap the session in an auto pointer to gaurantee it is deleted even in the
  // event of an exception
665
  std::auto_ptr<CatalogueSession> session(m_session);
666
667
668

  // Set the member variable m_session to NULL to prevent the desstruxtor from
  // trying a double delete
Daniele Kruse's avatar
Daniele Kruse committed
669
670
  m_session = NULL;
  m_sessionType = SESSION_TYPE_NONE;
671
672

  session->sessionFailed();
673
674
675
676
677
678
}

//------------------------------------------------------------------------------
// getTapeStatDriveEntry
//------------------------------------------------------------------------------
castor::legacymsg::TapeStatDriveEntry
679
  castor::tape::tapeserver::daemon::CatalogueDrive::getTapeStatDriveEntry()
680
681
682
683
  const {
  legacymsg::TapeStatDriveEntry entry;

  try {
684
685
    entry.uid = getUidForTapeStatDriveEntry();
    entry.jid = getJidForTapeStatDriveEntry();
686
    castor::utils::copyString(entry.dgn, m_config.dgn);
687
688
689
    entry.up = getUpForTapeStatDriveEntry();
    entry.asn = getAsnForTapeStatDriveEntry();
    entry.asn_time = getAsnTimeForTapeStatDriveEntry();
690
    castor::utils::copyString(entry.drive, m_config.unitName);
691
692
693
694
    entry.mode = getModeForTapeStatDriveEntry();
    castor::utils::copyString(entry.lblcode,
      getLblCodeForTapeStatDriveEntry().c_str());
    entry.tobemounted = getToBeMountedForTapeStatDriveEntry();
695
696
    castor::utils::copyString(entry.vid, getVidForTapeStatDriveEntry());
    castor::utils::copyString(entry.vsn, getVsnForTapeStatDriveEntry());
697
698
699
700
701
702
703
704
705
706
707
708
709
710
    entry.cfseq = 0; // the fseq is ignored by tpstat, so we leave it set to 0
  } catch(castor::exception::Exception &ne) {
    castor::exception::Exception ex;
    ex.getMessage() << "Failed to get TapeStatDriveEntry: " <<
      ne.getMessage().str();
    throw ex;
  }

  return entry;
}

//------------------------------------------------------------------------------
// getUidForTapeStatDriveEntry
//------------------------------------------------------------------------------
711
uint32_t castor::tape::tapeserver::daemon::CatalogueDrive::
712
713
  getUidForTapeStatDriveEntry() const throw() {
  switch(m_state) {
714
  case DRIVE_STATE_RUNNING:
715
716
717
718
719
720
721
722
723
724
  case DRIVE_STATE_WAITDOWN:
    return geteuid();
  default:
    return 0;
  }
}

//------------------------------------------------------------------------------
// getJidForTapeStatDriveEntry
//------------------------------------------------------------------------------
725
uint32_t castor::tape::tapeserver::daemon::CatalogueDrive::
726
  getJidForTapeStatDriveEntry() const throw() {
727
  try {
728
    return getSession().getPid();
729
  } catch(...) {
730
731
732
733
734
735
736
    return 0;
  }
}

//------------------------------------------------------------------------------
// getUpForTapeStatDriveEntry
//------------------------------------------------------------------------------
737
uint16_t castor::tape::tapeserver::daemon::CatalogueDrive::
738
739
740
  getUpForTapeStatDriveEntry() const throw() {
  switch(m_state) {
  case DRIVE_STATE_UP:
741
  case DRIVE_STATE_RUNNING:
742
743
744
745
746
747
748
749
750
    return 1;
  default:
    return 0;
  }
}

//------------------------------------------------------------------------------
// getAsnForTapeStatDriveEntry
//------------------------------------------------------------------------------
751
uint16_t castor::tape::tapeserver::daemon::CatalogueDrive::
752
753
  getAsnForTapeStatDriveEntry() const throw() {
  switch(m_state) {
754
  case DRIVE_STATE_RUNNING:
755
756
757
758
759
760
761
762
763
764
  case DRIVE_STATE_WAITDOWN:
    return 1;
  default:
    return 0;
  }
}

//------------------------------------------------------------------------------
// getAsnTimeForTapeStatDriveEntry
//------------------------------------------------------------------------------
765
uint32_t castor::tape::tapeserver::daemon::CatalogueDrive::
766
  getAsnTimeForTapeStatDriveEntry() const throw() {
767
768
769
  try {
    return getSession().getAssignmentTime();
  } catch(...) {
770
771
    return 0;
  }
772
773
774
775
776
}

//------------------------------------------------------------------------------
// getModeForTapeStatDriveEntry
//------------------------------------------------------------------------------
777
uint16_t castor::tape::tapeserver::daemon::CatalogueDrive::
778
  getModeForTapeStatDriveEntry() const throw() {
779
780
781
  try {
    return getSession().getMode();
  } catch(...) {
782
783
784
785
786
787
788
    return WRITE_DISABLE;
  }
}

//------------------------------------------------------------------------------
// getLblCodeForTapeStatDriveEntry
//------------------------------------------------------------------------------
789
std::string castor::tape::tapeserver::daemon::CatalogueDrive::
790
791
792
793
794
795
796
  getLblCodeForTapeStatDriveEntry() const throw() {
  return "aul";
}

//------------------------------------------------------------------------------
// getToBeMountedForTapeStatDriveEntry
//------------------------------------------------------------------------------
797
uint16_t castor::tape::tapeserver::daemon::CatalogueDrive::
798
  getToBeMountedForTapeStatDriveEntry() const throw() {
799
800
801
  try {
    return getSession().tapeIsBeingMounted();
  } catch(...) {
802
803
    return 0;
  }
804
805
806
807
808
}

//------------------------------------------------------------------------------
// getVidForTapeStatDriveEntry
//------------------------------------------------------------------------------
809
std::string castor::tape::tapeserver::daemon::CatalogueDrive::
810
  getVidForTapeStatDriveEntry() const throw() {
811
812
813
  try {
    return getSession().getVid();
  } catch(...) {
814
815
    return "";
  }
816
817
}

818
819
820
//------------------------------------------------------------------------------
// getVidForCleaner
//------------------------------------------------------------------------------
821
std::string castor::tape::tapeserver::daemon::CatalogueDrive::
822
823
824
825
826
827
828
829
830
831
832
  getVidForCleaner() const throw() {
  try {
    return getSession().getVid();
  } catch(...) {
    return "";
  }
}

//------------------------------------------------------------------------------
// getAssignmentTimeForCleaner
//------------------------------------------------------------------------------
833
time_t castor::tape::tapeserver::daemon::CatalogueDrive::
834
835
836
837
838
839
840
841
  getAssignmentTimeForCleaner() const throw() {
  try {
    return getSession().getAssignmentTime();
  } catch(...) {
    return 0;
  }
}

842
843
844
//------------------------------------------------------------------------------
// getVsnForTapeStatDriveEntry
//------------------------------------------------------------------------------
845
std::string castor::tape::tapeserver::daemon::CatalogueDrive::
846
847
848
  getVsnForTapeStatDriveEntry() const throw() {
  return getVidForTapeStatDriveEntry();
}