Bug 139391 - Verify always non-equal for DVDs written in incremental mode
Summary: Verify always non-equal for DVDs written in incremental mode
Status: RESOLVED FIXED
Alias: None
Product: k3b
Classification: Applications
Component: Verfication (show other bugs)
Version: unspecified
Platform: unspecified Linux
: NOR normal
Target Milestone: ---
Assignee: Sebastian Trueg
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-12-30 11:21 UTC by Dirk Vormann
Modified: 2007-02-15 09:23 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
debugging patch against K3b 1.0rc6 (7.48 KB, patch)
2007-02-12 19:09 UTC, Sebastian Trueg
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dirk Vormann 2006-12-30 11:21:08 UTC
Version:           1.0rc2 (using KDE 3.5.5 "release 45" , openSUSE 10.2)
Compiler:          Target: x86_64-suse-linux
OS:                Linux (x86_64) release 2.6.18.2-34-default

Suse 10.2 K3b-package x86_64 from Packman.

growisofs 7.0 suid root; left untouched by the K3b update from 0.12.17 to 1.0rc2.

Plextor PX-716A Firmware 1.10

Using K3b 1.0rc2 verifying Data-DVDs always fails for disks written in incremental mode. No problem with DAO. When first creating an image file and then writing it the problem is the same. Did not test Video-DVDs.

Md5-sums of the original files (not image files, but individual files) and md5-sums of the files written to DVDs are identical. So I assume the problem being verifying, not writing.

It works with 0.12.17. Never tried 1.0rc1.
Comment 1 Sebastian Trueg 2006-12-30 12:22:02 UTC
try rc3. It should be fixed there. If so, please close the bug.
Comment 2 Dirk Vormann 2006-12-30 17:37:09 UTC
1.0rc3 (build from source) solves the problem for DVD-R.

The bug persists with dual layer DVD-R, both data and video DVD.


After adding files to the project the bar at the bottom of K3b's window shows 7.8 of 8.0 GB used. It remains unchanged until writing finishes. After ejecting and reloading the media to start verifying the bar shows "7.8 GB capacity exceeded by 3.4 GB".
Comment 3 Sebastian Trueg 2006-12-30 20:10:04 UTC
On Saturday 30 December 2006 17:37, Dirk Vormann wrote:
> ------- 1.0rc3 (build from source) solves the problem for DVD-R.


good.

> The bug persists with dual layer DVD-R, both data and video DVD.


not good and weird. I will investigate.

> After adding files to the project the bar at the bottom of K3b's window
> shows 7.8 of 8.0 GB used. It remains unchanged until writing finishes.
> After ejecting and reloading the media to start verifying the bar shows
> "7.8 GB capacity exceeded by 3.4 GB".


that is normal since K3b defaults to 4.4 gb media if no medium is inserted. I 
will try to change it so it is based on the project size.
Comment 4 Sebastian Trueg 2006-12-30 20:37:09 UTC
> The bug persists with dual layer DVD-R, both data and video DVD. 

Is this DVD-Copy or DVD project? And you did test both a Dual layer data project and a video project with 1.0rc3?

BTW: The other thing is changed now.
Comment 5 Dirk Vormann 2006-12-31 13:00:02 UTC
DVD project only. So far I did not try copying. And yes, it is one data and one video project, both dual layer. Need to get new dual layer media, so I cannot test anything for the next few days.
Comment 6 Sebastian Trueg 2007-01-03 13:54:38 UTC
Sadly I cannot reproduce this. Verification of DL media work here.... at least 
DVD+R DL as that is what I tested so far.
Comment 7 Dirk Vormann 2007-01-07 08:17:26 UTC
Tested some more.

There are no problems with DVD+R DL Verbatim 43541. (8x, written at recorders maximum speed of 6x, k3b-speed set to auto)

There are problems with DVD-R DL Verbatim 43543. (set to medium's maximum 4x in k3b) However it is no longer all media which fail verifying, only some. So I need to change the report from 'always' to 'more often than not, unpredictable'.

I am no longer certain it is k3b's fault. Might be erratic firmware. MD5-sums for all files written match, though. I still suppose the error to be with verifying, not writing.

Then again, there actually may be writing errors and I am unable to find any. What exactly does k3b test besides comparing files?
Comment 8 Sebastian Trueg 2007-01-07 16:23:09 UTC
On Sunday 07 January 2007 08:17, Dirk Vormann wrote:
> Then again, there actually may be writing errors and I am unable to find
> any. What exactly does k3b test besides comparing files?


K3b calculates the md5 sum of the complete iso filesystem written to the DVD. 
First it is calculated from the data stream burned to the medium. Then it is 
read back from the medium. So in theory there could be read errors in the 
file system structure parts of the image in which case the files would still 
be the same. But it seems very unlikely that this is the case on a regular 
basis. I will try writing a DVD-R DL, too.

You should do further testing (if possible) with an intermediate image that 
you keep. That way you can compare the original burned image and the one read 
back from the written DVD. That is what I will do.
Comment 9 Sebastian Trueg 2007-01-29 15:25:57 UTC
Any news on this one?
Comment 10 Dirk Vormann 2007-02-11 13:31:46 UTC
RCs are released quicker than I have data for Dual Layer media...


Currently I am writing DVD-R DL Media in three steps.

1) Video (or Data) DVD-project, create image file only. => imagefile1

2) Burn imagefile1 to disk. The verify always succedes. Failed veryfies only happen without intermediate image.

3) Reload written DVD, copy DVD, create image file only. => imagefile2


Result: imagefile1 and imagefile2 differ in size.

This applies to both RC5 and RC6.
Comment 11 Sebastian Trueg 2007-02-12 12:04:31 UTC
> 1) Video (or Data) DVD-project, create image file only. => imagefile1
>
> 2) Burn imagefile1 to disk. The verify always succedes. Failed veryfies
> only happen without intermediate image.
>
> 3) Reload written DVD, copy DVD, create image file only. => imagefile2


Ok, thanks. That helps with finding the problem.

> Result: imagefile1 and imagefile2 differ in size.


this is correct since DVDs are divided in blocks of 16 sectors while the 
images created by k3b are multiples of one sector.
Comment 12 Sebastian Trueg 2007-02-12 19:09:30 UTC
Created attachment 19646 [details]
debugging patch against K3b 1.0rc6

Since I have no way of reproducing the verification problem but others have I
need a way to get more information. Thus, I wrote this patch which hopefully
provides this information.
Please apply it, force a failed verification run, and send me the K3b debugging
output as presented in the debugging window (not the console output, although
both might be best).
Comment 13 Sebastian Trueg 2007-02-15 09:23:03 UTC
SVN commit 633751 by trueg:

* Added more debugging output for better bug hunting
* Fixed Video DVD project size calculation
* Let the MD5 job read all the data and finish gracefully
  instead of stopping it once the verification job "thinks"
  all data is processed.

BUG: 139084, 139391


 M  +26 -5     jobs/k3bdatatrackreader.cpp  
 M  +8 -3      jobs/k3bverificationjob.cpp  
 M  +9 -1      projects/datacd/k3bisoimager.cpp  
 M  +15 -2     projects/videodvd/k3bvideodvdimager.cpp  
 M  +3 -0      projects/videodvd/k3bvideodvdimager.h  
 M  +20 -4     tools/k3bactivepipe.cpp  
 M  +10 -0     tools/k3bactivepipe.h  
 M  +3 -0      tools/k3bmd5job.cpp  


--- trunk/extragear/multimedia/k3b/libk3b/jobs/k3bdatatrackreader.cpp #633750:633751
@@ -184,10 +184,13 @@
   }
 
   emitInfoMessage( i18n("Reading with sector size %1.").arg(m_usedSectorSize), K3bJob::INFO );
-  kdDebug() << "(K3bDataTrackReader::WorkThread) reading sectors " 
-	    << m_firstSector.lba() << " to " << m_lastSector.lba() 
-	    << " (" << (m_lastSector.lba() - m_firstSector.lba() + 1) 
-	    << ") with sector size: " << m_usedSectorSize << endl;
+  emitDebuggingOutput( "K3bDataTrackReader", 
+		       QString("reading sectors %1 to %2 with sector size %3. Length: %4 sectors, %5 bytes.")
+		       .arg( m_firstSector.lba() )
+		       .arg( m_lastSector.lba() )
+		       .arg( m_usedSectorSize )
+		       .arg( m_lastSector.lba() - m_firstSector.lba() + 1 )
+		       .arg( Q_UINT64(m_usedSectorSize) * (Q_UINT64)(m_lastSector.lba() - m_firstSector.lba() + 1) ) );
 
   QFile file;
   if( m_fd == -1 ) {
@@ -236,9 +239,11 @@
   }
 
   kdDebug() << "(K3bDataTrackReader) using buffer size of " << s_bufferSizeSectors << " blocks." << endl;
+  emitDebuggingOutput( "K3bDataTrackReader", QString("using buffer size of %1 blocks.").arg( s_bufferSizeSectors ) );
 
   // 2. get it on
   K3b::Msf currentSector = m_firstSector;
+  K3b::Msf totalReadSectors;
   m_nextReadSector = 0;
   m_errorSectorCount = 0;
   bool writeError = false;
@@ -264,12 +269,17 @@
 	readSectors = maxReadSectors;
     }
 
+    totalReadSectors += readSectors;
+
     int readBytes = readSectors * m_usedSectorSize;
 
     if( m_fd != -1 ) {
       if( ::write( m_fd, reinterpret_cast<void*>(buffer), readBytes ) != readBytes ) {
 	kdDebug() << "(K3bDataTrackReader::WorkThread) error while writing to fd " << m_fd 
 		  << " current sector: " << (currentSector.lba()-m_firstSector.lba()) << endl;
+	emitDebuggingOutput( "K3bDataTrackReader", 
+			     QString("Error while writing to fd %1. Current sector is %2.")
+			     .arg(m_fd).arg(currentSector.lba()-m_firstSector.lba()) );
 	writeError = true;
 	break;
       }
@@ -278,6 +288,9 @@
       if( file.writeBlock( reinterpret_cast<char*>(buffer), readBytes ) != readBytes ) {
 	kdDebug() << "(K3bDataTrackReader::WorkThread) error while writing to file " << m_imagePath
 		  << " current sector: " << (currentSector.lba()-m_firstSector.lba()) << endl;
+	emitDebuggingOutput( "K3bDataTrackReader", 
+			     QString("Error while writing to file %1. Current sector is %2.")
+			     .arg(m_imagePath).arg(currentSector.lba()-m_firstSector.lba()) );
 	writeError = true;
 	break;
       }
@@ -316,6 +329,11 @@
   m_device->close();
   delete [] buffer;
 
+  emitDebuggingOutput( "K3bDataTrackReader", 
+		       QString("Read a total of %1 sectors (%2 bytes)")
+		       .arg(totalReadSectors.lba())
+		       .arg((Q_UINT64)totalReadSectors.lba()*(Q_UINT64)m_usedSectorSize) );
+
   if( m_canceled )
     emitCanceled();
 
@@ -368,7 +386,7 @@
 // here we read every single sector for itself to find the troubleing ones
 bool K3bDataTrackReader::WorkThread::retryRead( unsigned char* buffer, unsigned long startSector, unsigned int len )
 {
-
+  emitDebuggingOutput( "K3bDataTrackReader", QString( "Problem while reading. Retrying from sector %1.").arg(startSector) );
   emitInfoMessage( i18n("Problem while reading. Retrying from sector %1.").arg(startSector), K3bJob::WARNING );
 
   int sectorsRead = -1;
@@ -387,12 +405,15 @@
     if( !success ) {
       if( m_ignoreReadErrors ) {
 	emitInfoMessage( i18n("Ignoring read error in sector %1.").arg(sector), K3bJob::ERROR );
+	emitDebuggingOutput( "K3bDataTrackReader", QString( "Ignoring read error in sector %1.").arg(sector) );
+
 	++m_errorSectorCount;
 	//	  ::memset( &buffer[i], 0, 1 );
 	success = true;
       }
       else {
 	emitInfoMessage( i18n("Error while reading sector %1.").arg(sector), K3bJob::ERROR );
+	emitDebuggingOutput( "K3bDataTrackReader", QString( "Read error in sector %1.").arg(sector) );
 	break;
       }
     }
--- trunk/extragear/multimedia/k3b/libk3b/jobs/k3bverificationjob.cpp #633750:633751
@@ -95,6 +95,8 @@
   d->md5Job = new K3bMd5Job( this );
   connect( d->md5Job, SIGNAL(infoMessage(const QString&, int)), this, SIGNAL(infoMessage(const QString&, int)) );
   connect( d->md5Job, SIGNAL(finished(bool)), this, SLOT(slotMd5JobFinished(bool)) );
+  connect( d->md5Job, SIGNAL(debuggingOutput(const QString&, const QString&)), 
+	   this, SIGNAL(debuggingOutput(const QString&, const QString&)) );
 }
 
 
@@ -255,10 +257,10 @@
       d->dataTrackReader->setSectorRange( d->toc[d->tracks[trackIndex].trackNumber-1].firstSector(),
 					  d->toc[d->tracks[trackIndex].trackNumber-1].firstSector() + d->currentTrackSize -1 );
     
+    d->md5Job->setMaxReadSize( d->currentTrackSize.mode1Bytes() );
+
     d->dataTrackReader->writeToFd( d->pipe.in() );
     d->dataTrackReader->start();
-
-    d->md5Job->setMaxReadSize( d->currentTrackSize.mode1Bytes() );
   }
   else {
     // FIXME: handle audio tracks
@@ -310,7 +312,10 @@
     d->md5Job->cancel();
   else {
     d->alreadyReadSectors += trackLength( d->currentTrackIndex );
-    d->md5Job->stop();
+
+    // close the pipe and let the md5 job finish gracefully
+    d->pipe.closeIn();
+    //    d->md5Job->stop();
   }
 }
 
--- trunk/extragear/multimedia/k3b/libk3b/projects/datacd/k3bisoimager.cpp #633750:633751
@@ -163,6 +163,10 @@
 
   d->pipe->close();
 
+  emit debuggingOutput( "K3bIsoImager", 
+			QString("Pipe throughput: %1 bytes read, %2 bytes written.")
+			.arg(d->pipe->bytesRead()).arg(d->pipe->bytesWritten()) );
+
   if( d->imageFile.isOpen() ) {
     d->imageFile.close();
 
@@ -321,8 +325,8 @@
     s += *it + " ";
   }
   kdDebug() << s << endl << flush;
+  emit debuggingOutput("mkisofs calculate size command:", s);
 
-
   // since output changed during mkisofs version changes we grab both
   // stdout and stderr
 
@@ -404,6 +408,10 @@
       m_mkisofsPrintSizeResult = m_collectedMkisofsPrintSizeStderr.mid( pos+33 ).toInt( &success );
   }
 
+  emit debuggingOutput( "K3bIsoImager", 
+			QString("mkisofs print size result: %1 (%2 bytes)")
+			.arg(m_mkisofsPrintSizeResult)
+			.arg(Q_UINT64(m_mkisofsPrintSizeResult)*2048ULL) );
 
   cleanup();
 
--- trunk/extragear/multimedia/k3b/libk3b/projects/videodvd/k3bvideodvdimager.cpp #633750:633751
@@ -58,6 +58,20 @@
 
 void K3bVideoDvdImager::start()
 {
+  fixVideoDVDSettings();
+  K3bIsoImager::start();
+}
+
+
+void K3bVideoDvdImager::init()
+{
+  fixVideoDVDSettings();
+  K3bIsoImager::init();
+}
+
+
+void K3bVideoDvdImager::fixVideoDVDSettings()
+{
   // Video DVD defaults, we cannot set these in K3bVideoDvdDoc since they
   // will be overwritten in the burn dialog unless we create some K3bVideoDVDIsoOptions
   // class with different defaults. But since the whole Video DVD project is a hack we
@@ -70,13 +84,12 @@
   o.setCreateRockRidge(false); 
   o.setCreateUdf(true); 
   d->doc->setIsoOptions( o ); 
-
-  K3bIsoImager::start();
 }
 
 
 void K3bVideoDvdImager::calculateSize()
 {
+  fixVideoDVDSettings();
   K3bIsoImager::calculateSize();
 }
 
--- trunk/extragear/multimedia/k3b/libk3b/projects/videodvd/k3bvideodvdimager.h #633750:633751
@@ -39,6 +39,7 @@
 
  public slots:
   virtual void start();
+  virtual void init();
   virtual void calculateSize();
 
  protected:
@@ -51,6 +52,8 @@
   virtual void slotReceivedStderr( const QString& );
 
  private:
+  void fixVideoDVDSettings();
+
   class Private;
   Private* d;
 };
--- trunk/extragear/multimedia/k3b/libk3b/tools/k3bactivepipe.cpp #633750:633751
@@ -40,17 +40,20 @@
 
   void run() {
     kdDebug() << "(K3bActivePipe) started thread." << endl;
+    bytesRead = bytesWritten = 0;
     buffer.resize( 10*2048 );
     ssize_t r = 0;
-    ssize_t total = 0;
     while( ( r = m_pipe->read( buffer.data(), buffer.size() ) ) > 0 ) {
 
+      bytesRead += r;
+
       // write it out
       ssize_t w = 0;
       ssize_t ww = 0;
       while( w < r ) {
 	if( ( ww = m_pipe->write( buffer.data()+w, r-w ) ) > 0 ) {
 	  w += ww;
+	  bytesWritten += ww;
 	}
 	else {
 	  kdDebug() << "(K3bActivePipe) write failed." << endl;
@@ -58,10 +61,8 @@
 	  return;
 	}
       }
-
-      total += r;
     }
-    kdDebug() << "(K3bActivePipe) thread done: " << r << " (total bytes: " << total << ")" << endl;
+    kdDebug() << "(K3bActivePipe) thread done: " << r << " (total bytes read/written: " << bytesRead << "/" << bytesWritten << ")" << endl;
     close( closeWhenDone );
   }
 
@@ -115,6 +116,9 @@
   bool closeFdToWriteTo;
 
   QByteArray buffer;
+
+  Q_UINT64 bytesRead;
+  Q_UINT64 bytesWritten;
 };
 
 
@@ -237,3 +241,15 @@
     return false;
   return true;
 }
+
+
+Q_UINT64 K3bActivePipe::bytesRead() const
+{
+  return d->bytesRead;
+}
+
+
+Q_UINT64 K3bActivePipe::bytesWritten() const
+{
+  return d->bytesWritten;
+}
--- trunk/extragear/multimedia/k3b/libk3b/tools/k3bactivepipe.h #633750:633751
@@ -99,6 +99,16 @@
    */
   int out() const;
 
+  /**
+   * The number of bytes that have been read.
+   */
+  Q_UINT64 bytesRead() const;
+
+  /**
+   * The number of bytes that have been written.
+   */
+  Q_UINT64 bytesWritten() const;
+
  protected:
   /**
    * Reads the data from the source.
--- trunk/extragear/multimedia/k3b/libk3b/tools/k3bmd5job.cpp #633750:633751
@@ -204,6 +204,7 @@
 
     if( readSize <= 0 ) {
       //      kdDebug() << "(K3bMd5Job) reached max size of " << d->maxSize << ". Stopping." << endl;
+      emit debuggingOutput( "K3bMd5Job", QString("Reached max read of %1. Stopping after %2 bytes.").arg(d->maxSize).arg(d->readData) );
       stopAll();
       emit percent( 100 );
       jobFinished(true);
@@ -257,6 +258,7 @@
       }
       else if( read == 0 ) {
 	//	kdDebug() << "(K3bMd5Job) read all data. Total size: " << d->readData << ". Stopping." << endl;
+	emit debuggingOutput( "K3bMd5Job", QString("All data read. Stopping after %1 bytes.").arg(d->readData) );
 	stopAll();
 	emit percent( 100 );
 	jobFinished(true);
@@ -301,6 +303,7 @@
 
 void K3bMd5Job::stop()
 {
+  emit debuggingOutput( "K3bMd5Job", QString("Stopped manually after %1 bytes.").arg(d->readData) );
   stopAll();
   jobFinished( true );
 }