diff --git a/tapeserver/castor/tape/tapeserver/SCSI/Structures.hpp b/tapeserver/castor/tape/tapeserver/SCSI/Structures.hpp
index c5d1edbc1f817b42f6825be9998e9440c1c98ab0..55ba6fe6ce242ff5024d0dc9ccaeec505bd6e3a8 100644
--- a/tapeserver/castor/tape/tapeserver/SCSI/Structures.hpp
+++ b/tapeserver/castor/tape/tapeserver/SCSI/Structures.hpp
@@ -1224,6 +1224,10 @@ namespace SCSI {
         unsigned char reserved[2];                   // Reserved
         unsigned char logicalObjectIdentifier[6];    // The logical object identifier of the object at the end of the above wrap
       } wrapDescriptor[maxLTOTapeWraps];             // Array of wrap descriptiors
+      
+      uint16_t getNbWrapsReturned(){
+        return (SCSI::Structures::toU16(responseDataLength) / sizeof(wrapDescriptor));
+      }
     };
 
     /**
diff --git a/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.cpp b/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.cpp
index 0da6ca6dbb42233e1d271a11c6d1da8cab210776..f05f526943fc753d3873551a7f51a61cae05e6c8 100644
--- a/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.cpp
+++ b/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.cpp
@@ -118,6 +118,44 @@ void drive::DriveLTO::clearCompressionStats() {
   SCSI::ExceptionLauncher(sgh, "SCSI error in clearCompressionStats:");
 }
 
+std::vector<castor::tape::tapeserver::drive::endOfWrapPosition> drive::DriveLTO::getEndOfWrapPositions() {
+  std::vector<castor::tape::tapeserver::drive::endOfWrapPosition> ret;
+  
+  SCSI::Structures::readEndOfWrapPositionCDB_t cdb;
+  //WrapNumbeValid = 0, ReportAll = 1 and WrapNumber = 0 as we want all the end of wraps positions
+  cdb.WNV = 0;
+  cdb.RA = 1;
+  cdb.wrapNumber = 0;
+  //Each wrap descriptor is 12 bytes
+  SCSI::Structures::setU32(cdb.allocationLength,12 * castor::tape::SCSI::maxLTOTapeWraps);
+  
+  SCSI::Structures::readEndOfWrapPositionDataLongForm_t data;
+  
+  SCSI::Structures::LinuxSGIO_t sgh;
+  sgh.setCDB(&cdb);
+  sgh.setDataBuffer(&data);
+  sgh.dxfer_direction = SG_DXFER_FROM_DEV;
+  
+   /* Manage both system error and SCSI errors. */
+  cta::exception::Errnum::throwOnMinusOne(
+    m_sysWrapper.ioctl(m_tapeFD, SG_IO, &sgh),
+    "Failed SG_IO ioctl in DriveLTO::getEndOfWrapPositions");
+  SCSI::ExceptionLauncher(sgh, "SCSI error in getEndOfWrapPositions:");
+  
+  int nbWrapReturned = data.getNbWrapsReturned();
+  //Loop over the list of wraps of the tape returned by the drive
+  for(int i = 0; i < nbWrapReturned; ++i){
+    castor::tape::tapeserver::drive::endOfWrapPosition position;
+    auto wrapDescriptor = data.wrapDescriptor[i];
+    position.wrapNumber = SCSI::Structures::toU16(wrapDescriptor.wrapNumber);
+    position.partition = SCSI::Structures::toU16(wrapDescriptor.partition);
+    //blockId returned is 6*8 = 48 bytes, so we need to store it into a uint64_t
+    position.blockId = SCSI::Structures::toU64(wrapDescriptor.logicalObjectIdentifier);
+    ret.push_back(position);
+  }
+  return ret;
+}
+
 /**
  * Information about the drive. The vendor id is used in the user labels of the files.
  * @return    The deviceInfo structure with the information about the drive.
@@ -367,6 +405,15 @@ drive::physicalPositionInfo drive::DriveGeneric::getPhysicalPositionInfo()
   return posInfo;
 }
 
+/**
+* Returns all the end of wrap positions of the mounted tape
+* 
+* @return a vector of endOfWrapsPositions. 
+*/
+std::vector<drive::endOfWrapPosition> drive::DriveGeneric::getEndOfWrapPositions() {
+  return std::vector<drive::endOfWrapPosition>();
+}
+
 /**
  * Get tape alert information from the drive. There is a quite long list of possible tape alerts.
  * They are described in SSC-4, section 4.2.20: TapeAlert application client interface.
diff --git a/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.hpp b/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.hpp
index f1431d23462aa303e08dff1c58bed149eed8529d..2702ba46200139084eaa9fe80113717dca8a2398 100644
--- a/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.hpp
+++ b/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.hpp
@@ -139,6 +139,14 @@ namespace drive {
      * @return physicalPositionInfo class. This contains the wrap and linear position (LPOS).
      */
     virtual physicalPositionInfo getPhysicalPositionInfo();
+    
+    /**
+     * Returns all the end of wrap positions of the mounted tape
+     * 
+     * @return a vector of endOfWrapsPositions. 
+     */
+    virtual std::vector<endOfWrapPosition> getEndOfWrapPositions();
+    
 
     /**
      * Get tape alert information from the drive. There is a quite long list of possible tape alerts.
@@ -583,6 +591,7 @@ namespace drive {
 
     virtual compressionStats getCompression();
     virtual void clearCompressionStats();
+    virtual std::vector<castor::tape::tapeserver::drive::endOfWrapPosition> getEndOfWrapPositions();
   };
 
   class DriveIBM3592 : public DriveGeneric {
diff --git a/tapeserver/castor/tape/tapeserver/drive/DriveInterface.hpp b/tapeserver/castor/tape/tapeserver/drive/DriveInterface.hpp
index 9dfbdd7ac6075e7b35cc1cf083c287068c9d6c7b..8ed49e4497512e203ab0a720e1a62616764a6b31 100644
--- a/tapeserver/castor/tape/tapeserver/drive/DriveInterface.hpp
+++ b/tapeserver/castor/tape/tapeserver/drive/DriveInterface.hpp
@@ -120,6 +120,18 @@ namespace drive {
     }
   };
 
+  /**
+   * End of wraps position infos
+   * 
+   * It is used by the getEndOfWrapPositions() method
+   */
+  class endOfWrapPosition{
+  public:
+    uint16_t wrapNumber;
+    uint64_t blockId;
+    uint16_t partition;
+  };
+  
   /**
    * Logical block protection nformation, returned by getLBPInfo()
    */
@@ -213,6 +225,7 @@ namespace drive {
     virtual void positionToLogicalObject(uint32_t blockId)  = 0;
     virtual positionInfo getPositionInfo()  = 0;
     virtual physicalPositionInfo getPhysicalPositionInfo() = 0;
+    virtual std::vector<endOfWrapPosition> getEndOfWrapPositions() = 0;
     virtual std::vector<uint16_t> getTapeAlertCodes() = 0;
     virtual std::vector<std::string> getTapeAlerts(const std::vector<uint16_t>&) = 0;
     virtual std::vector<std::string> getTapeAlertsCompact (const std::vector<uint16_t>&) = 0;
diff --git a/tapeserver/castor/tape/tapeserver/drive/FakeDrive.cpp b/tapeserver/castor/tape/tapeserver/drive/FakeDrive.cpp
index 903fa0ddf20c259739170277b7340e399a1a4978..d37e78c47bde9a9d13816ed346d1617622da0422 100644
--- a/tapeserver/castor/tape/tapeserver/drive/FakeDrive.cpp
+++ b/tapeserver/castor/tape/tapeserver/drive/FakeDrive.cpp
@@ -98,6 +98,10 @@ castor::tape::tapeserver::drive::physicalPositionInfo castor::tape::tapeserver::
   return pos;
 }
 
+std::vector<castor::tape::tapeserver::drive::endOfWrapPosition> castor::tape::tapeserver::drive::FakeDrive::getEndOfWrapPositions() {
+  return std::vector<castor::tape::tapeserver::drive::endOfWrapPosition>();
+}
+
 std::vector<uint16_t> castor::tape::tapeserver::drive::FakeDrive::getTapeAlertCodes() {
   std::vector<uint16_t> empty;
   return empty;
diff --git a/tapeserver/castor/tape/tapeserver/drive/FakeDrive.hpp b/tapeserver/castor/tape/tapeserver/drive/FakeDrive.hpp
index fbadd76acf29f627ab683e0f33aa066b38a7f64a..cdcf6e104b4060f5f318c072a5b16eb5eadfc754 100644
--- a/tapeserver/castor/tape/tapeserver/drive/FakeDrive.hpp
+++ b/tapeserver/castor/tape/tapeserver/drive/FakeDrive.hpp
@@ -72,6 +72,7 @@ namespace drive {
     virtual void positionToLogicalObject(uint32_t blockId) ;
     virtual positionInfo getPositionInfo() ;
     virtual physicalPositionInfo getPhysicalPositionInfo();
+    virtual std::vector<endOfWrapPosition> getEndOfWrapPositions();
     virtual std::vector<uint16_t> getTapeAlertCodes();
     virtual std::vector<std::string> getTapeAlerts(const std::vector<uint16_t>&) ;
     virtual std::vector<std::string> getTapeAlertsCompact(const std::vector<uint16_t>&) ;