New -check_media option async_chunks=

master
Thomas Schmitt 11 years ago
parent 917b487343
commit 6668ab7d32
  1. 16
      xorriso/check_media.c
  2. 5
      xorriso/check_media.h
  3. 588
      xorriso/drive_mgt.c
  4. 9
      xorriso/xorriso.1
  5. 69
      xorriso/xorriso.info
  6. 9
      xorriso/xorriso.texi
  7. 2
      xorriso/xorriso_timestamp.h

@ -571,6 +571,7 @@ int Checkmediajob_new(struct CheckmediajoB **o, int flag)
m->min_lba= -1;
m->max_lba= -1;
m->min_block_size= 0;
m->async_chunks= 0;
m->mode= 0;
m->start_time= time(NULL);
m->time_limit= 28800;
@ -655,6 +656,12 @@ int Xorriso_check_media_setup_job(struct XorrisO *xorriso,
ret= Sfile_str(job->abort_file_path, argv[i] + 11, 0);
if(ret <= 0)
goto ex;
} else if(strncmp(argv[i], "async_chunks=", 13) == 0) {
num= Scanf_io_size(argv[i] + 13, 1);
if(num >= 0 && num <= 1024)
job->async_chunks= num;
else
goto bad_value;
} else if(strncmp(argv[i], "bad_limit=", 10) == 0) {
if(strcmp(argv[i] + 10, "good") == 0)
xorriso->check_media_bad_limit= Xorriso_read_quality_gooD;
@ -689,7 +696,7 @@ int Xorriso_check_media_setup_job(struct XorrisO *xorriso,
if(num >= 2048 || num == 0)
job->min_block_size= num / 2048;
else
goto unknown_value;
goto bad_value;
} else if(strncmp(argv[i], "event=", 6) == 0) {
strncpy(sev_text, argv[i] + 6, 19);
sev_text[19]= 0;
@ -731,7 +738,7 @@ int Xorriso_check_media_setup_job(struct XorrisO *xorriso,
num= -1;
sscanf(argv[i] + 11, "%lf", &num);
if(num > 0x7fffffff || num < 0)
goto unknown_value;
goto bad_value;
job->patch_lba0_msc1= num;
job->patch_lba0= (num >= 32) + (strstr(argv[i] + 11, ":force") != NULL);
} else
@ -815,6 +822,11 @@ unknown_value:;
"-check_media: Unknown value with option %s", argv[i]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
bad_value:;
sprintf(xorriso->info_text,
"-check_media: Unsuitable value with option %s", argv[i]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
} else {
sprintf(xorriso->info_text, "-check_media: Unknown option '%s'", argv[i]);

@ -99,7 +99,10 @@ struct CheckmediajoB {
int max_lba; /* if >=0 : read up to this address, else use mode */
int min_block_size; /* granularity desired by user
*/
*/
int async_chunks; /* >= 2 : run MD5 thread, use given number of chunks
else : synchronous
*/
int mode; /* 0= track by track
1= single sweep over libisoburn medium capacity
2= single sweep over libburn medium capacity

@ -22,6 +22,7 @@
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <pthread.h>
#include "xorriso.h"
@ -2106,6 +2107,312 @@ int Xorriso_check_for_abort(struct XorrisO *xorriso,
}
struct xorriso_md5_state {
/* Resources */
struct XorrisO *xorriso;
void *ctx;
struct SpotlisT *spotlist;
pthread_mutex_t spot_mutex;
/* Checksum tag cursor */
uint32_t md5_start;
uint32_t next_tag;
int chain_broken;
int in_track_gap;
int was_sb_tag;
int md5_spot_value;
uint32_t md5_spot_lba;
/* Asynchronous operation */
int slave_state; /* Operated by slave
0= not yet started
1= slave is started
2= slave has reached its end
3= slave failed to start
*/
int chunk_size;
int num_chunks;
char **chunk;
int *chunk_state; /* 0= content invalid (set by boss at creation time),
1= content readable (set by boss),
2= content was read (set by MD5 slave),
3= end-of-processing (set by boss when done)
*/
int *chunk_fill; /* Actual number of valid bytes in chunk */
uint32_t *chunk_lba;
int chunk_w_idx; /* Write index. Operated by boss */
int chunk_r_idx; /* Read index. Operated by MD5 slave */
off_t w_sleeps;
off_t r_sleeps;
};
int Xorriso__add_spot(struct xorriso_md5_state *state,
int start_lba, int blocks, int quality, int flag)
{
int ret;
if(state->chunk != NULL) {
ret= pthread_mutex_lock(&(state->spot_mutex));
if(ret != 0)
return(0);
}
ret= Spotlist_add_item(state->spotlist, start_lba, blocks, quality, 0);
if(state->chunk != NULL)
pthread_mutex_unlock(&(state->spot_mutex));
return(ret);
}
int Xorriso_chunk_md5(struct XorrisO *xorriso, char *data, int to_read,
uint32_t from_lba, struct xorriso_md5_state *state, int flag)
{
int j, ret= 0, valid, tag_type;
uint32_t lba, pos, range_start, range_size;
char md5[16], tag_md5[16], *tag_type_name= "", *comparison, *sev_text;
void *cloned_ctx= NULL;
for(j= 0; j < to_read; j++) {
lba= j + from_lba;
if(lba < state->md5_start)
continue;
ret= 0;
if(lba > state->md5_start + 16 &&
(state->next_tag == 0 || state->chain_broken || lba == state->next_tag)){
ret= iso_util_decode_md5_tag(data + j * 2048, &tag_type,
&pos, &range_start, &range_size,
&(state->next_tag), tag_md5,
!!state->chain_broken);
}
valid= (ret == 1 || ret == (int) ISO_MD5_AREA_CORRUPTED) && pos == lba;
if(valid && tag_type == 2 && (lba < state->md5_start + 32 ||
state->in_track_gap)){
tag_type_name= "superblock";
state->was_sb_tag= 1;
if(state->in_track_gap && range_start != state->md5_start &&
range_start < lba && lba - range_start <= (uint32_t) j) {
/* Looking for next session : start computing in hindsight.
Session start and superblock tag are supposed to be in the
same 64 kB chunk.
*/
iso_md5_end(&(state->ctx), md5);
ret= iso_md5_start(&(state->ctx));
if(ret < 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
iso_md5_compute(&(state->ctx), data + (j - (lba - range_start)) * 2048,
(lba - range_start) * 2048);
state->md5_start= range_start;
state->in_track_gap= 0;
}
} else if(valid && tag_type == 4 && lba < 32) {
tag_type_name= "relocated 64kB superblock";
}else if(valid && tag_type == 3 && state->was_sb_tag) {
tag_type_name= "tree";
}else if(valid && tag_type == 1) {
/* >>> ??? allow this without superblock and tree tag ? */
tag_type_name= "session";
} else {
tag_type_name= "";
}
if (tag_type_name[0]) {
if(range_start != state->md5_start) {
sprintf(xorriso->info_text,
"Found MD5 %s tag which covers different data range", tag_type_name);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
sprintf(xorriso->info_text, " Expected: %u Found: %u",
(unsigned int) state->md5_start, range_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
state->chain_broken= 1;
valid= 0;
} else {
ret= iso_md5_clone(state->ctx, &cloned_ctx);
if(ret <= 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
iso_md5_end(&cloned_ctx, md5);
if(ret == (int) ISO_MD5_AREA_CORRUPTED) {
comparison= "CORRUPTED";
sev_text= "WARNING";
state->md5_spot_value= Xorriso_read_quality_md5_mismatcH;
state->chain_broken= 1;
} else if(! iso_md5_match(tag_md5, md5)) {
comparison= "NON-MATCHING";
sev_text= "WARNING";
state->md5_spot_value= Xorriso_read_quality_md5_mismatcH;
state->chain_broken= 1;
} else {
comparison= "matching";
sev_text= "UPDATE";
state->md5_spot_value= Xorriso_read_quality_md5_matcH;
}
state->md5_spot_lba= lba;
sprintf(xorriso->info_text,
"Found %s MD5 %s tag: start=%d size=%d",
comparison, tag_type_name, state->md5_start,
lba - state->md5_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, sev_text, 0);
}
if(valid && (tag_type == 1 || (tag_type == 4 && pos == lba && lba < 32))){
if(state->md5_spot_value != Xorriso_read_quality_untesteD) {
ret= Xorriso__add_spot(state, state->md5_start,
state->md5_spot_lba - state->md5_start, state->md5_spot_value, 0);
if(ret <= 0)
goto ex;
}
state->md5_spot_value= Xorriso_read_quality_untesteD;
state->md5_start = lba + 1;
if(state->md5_start % 32)
state->md5_start= state->md5_start + (32 - (state->md5_start % 32));
state->next_tag= 0;
iso_md5_end(&(state->ctx), md5);
ret= iso_md5_start(&(state->ctx));
if(ret < 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
if(tag_type == 1)
state->in_track_gap= 1;
continue;
}
}
iso_md5_compute(state->ctx, data + j * 2048, 2048);
}
ret= 1;
ex:;
return(ret);
}
static void *Xorriso__md5_slave(void *state_pt)
{
struct xorriso_md5_state *state;
int ret, c_state, c_idx;
static int u_wait= 1;
state= state_pt;
state->slave_state= 1;
while(1) {
c_idx= state->chunk_r_idx;
c_state= state->chunk_state[c_idx];
if(c_state == 1) {
ret= Xorriso_chunk_md5(state->xorriso, state->chunk[c_idx],
state->chunk_fill[c_idx], state->chunk_lba[c_idx],
state, 0);
if(ret <= 0)
goto ex;
state->chunk_state[c_idx]= 2;
state->chunk_r_idx= (c_idx + 1) % state->num_chunks;
} else if(c_state == 3) {
goto ex;
} else {
/* >>> have a timeout ? */;
if(u_wait > 0)
usleep(u_wait);
state->r_sleeps++;
}
}
ex:;
state->slave_state= 2;
return NULL;
}
int Xorriso_start_chunk_md5(struct XorrisO *xorriso,
struct xorriso_md5_state *state, int flag)
{
int ret, u_wait= 1000;
pthread_attr_t attr;
pthread_attr_t *attr_pt = NULL;
pthread_t thread;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
attr_pt= &attr;
ret= pthread_create(&thread, attr_pt, Xorriso__md5_slave, state);
if(ret != 0) {
sprintf(xorriso->info_text,
"-check_media: Cannot create thread for MD5 computation");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
ret= 0; goto ex;
}
while(state->slave_state != 1) {
/* >>> have a timeout ? */;
/* >>> if this fails set state->slave_state= 3 */
usleep(u_wait);
}
ret= 1;
ex:;
return(ret);
}
int Xorriso__wait_chunk_md5(struct xorriso_md5_state *state,
int u_wait, int flag)
{
while(state->chunk_state[state->chunk_w_idx] == 1) {
/* >>> have a timeout ? */;
usleep(u_wait);
state->w_sleeps++;
}
return(1);
}
int Xorriso__wait_slave_md5_end(struct xorriso_md5_state *state,
int u_wait, int flag)
{
while(state->slave_state == 1) {
/* >>> have a timeout ? */;
usleep(u_wait);
}
return(1);
}
int Xorriso__end_slave_md5(struct xorriso_md5_state *state,
int u_wait, int flag)
{
int i, ret;
/* Tell slave thread to end */
for(i= 0; i < state->num_chunks; i++) {
ret= Xorriso__wait_chunk_md5(state, 10000, 0);
if(ret <= 0)
return(ret);
state->chunk_state[state->chunk_w_idx]= 3;
state->chunk_w_idx= (state->chunk_w_idx + 1) % state->num_chunks;
}
/* Wait for slave to end */
ret= Xorriso__wait_slave_md5_end(state, 10000, 0);
if(ret <= 0)
return(ret);
return(1);
}
/* @param flag bit0= this is a follow-up session (i.e. on CD: TAO)
bit1= no pacifier messages
bit2= compute stream MD5 and look out for checksum tag
@ -2123,23 +2430,40 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
int start_lba= 0;
struct burn_drive *drive;
struct burn_drive_info *dinfo;
char *data= NULL;
char *data= NULL, *data_pt;
off_t data_count, to_read, read_count= 0, write_amount;
double pre_read_time, post_read_time, time_diff, total_time_diff= 0;
double last_abort_file_time= 0;
void *ctx= NULL, *cloned_ctx= NULL;
char md5[16], tag_md5[16];
uint32_t pos, range_start, range_size, next_tag= 0, lba, md5_spot_lba= 0;
int md5_spot_value= Xorriso_read_quality_untesteD, chain_broken= 0;
int tag_type= 0, valid, was_sb_tag= 0, in_track_gap= 0;
char *comparison= "", *sev_text= "DEBUG", *tag_type_name= "";
void *ctx= NULL;
char md5[16];
size_t data_size;
struct xorriso_md5_state state;
int num_chunks, async_md5;
static off_t chunks_limit= 256 * 1024 * 1024;
memset(&state, 0, sizeof(state));
state.chunk= NULL;
state.chunk_state= NULL;
state.chunk_fill= NULL;
state.chunk_lba= NULL;
state.spotlist= spotlist;
if(read_chunk > 1024)
read_chunk= 1024;
else if(read_chunk < 1)
read_chunk= 1;
Xorriso_alloc_meM(data, char, 2 * read_chunk * 1024);
num_chunks= job->async_chunks;
if(((off_t) num_chunks) * ((off_t) read_chunk) > chunks_limit)
num_chunks= chunks_limit / read_chunk;
async_md5= (num_chunks >= 2);
if(async_md5)
data_size= num_chunks * read_chunk * 2048;
else
data_size= read_chunk * 2048;
Xorriso_alloc_meM(data, char, data_size);
data_pt= data;
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to check media readability",
@ -2171,6 +2495,50 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
}
}
state.xorriso= xorriso;
state.ctx= ctx;
state.spotlist= spotlist;
state.md5_start= md5_start;
state.next_tag= 0;
state.chain_broken= 0;
state.in_track_gap= 0;
state.was_sb_tag= 0;
state.md5_spot_value= Xorriso_read_quality_untesteD;
state.md5_spot_lba= 0;
state.slave_state= 0;
state.chunk_size= read_chunk;
if(async_md5) {
state.num_chunks= num_chunks;
Xorriso_alloc_meM(state.chunk, char *, num_chunks);
Xorriso_alloc_meM(state.chunk_state, int, num_chunks);
Xorriso_alloc_meM(state.chunk_fill, int, num_chunks);
Xorriso_alloc_meM(state.chunk_lba, uint32_t, num_chunks);
for(i= 0; i < state.num_chunks; i++) {
state.chunk[i]= data + read_chunk * i * 2048;
state.chunk_state[i]= 0;
state.chunk_fill[i]= 0;
state.chunk_lba[i]= 0;
}
ret= pthread_mutex_init(&(state.spot_mutex), NULL);
if(ret != 0) {
sprintf(xorriso->info_text,
"-check_media: Cannot initialize thread mutex");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
goto ex;
}
} else
state.num_chunks= 0;
state.chunk_w_idx= 0;
state.chunk_r_idx= 0;
state.w_sleeps= 0;
state.r_sleeps= 0;
if(async_md5) {
ret= Xorriso_start_chunk_md5(xorriso, &state, 0);
if(ret <= 0)
goto ex;
}
start_lba= from_lba;
to_read= read_chunk;
post_read_time= Sfile_microtime(0);
@ -2195,12 +2563,12 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
abort_check:;
if(prev_quality >= 0) {
ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba,
ret= Xorriso__add_spot(&state, start_lba, i + from_lba - start_lba,
prev_quality, 0);
if(ret <= 0)
goto ex;
}
ret= Spotlist_add_item(spotlist, i + from_lba, block_count - i,
ret= Xorriso__add_spot(&state, i + from_lba, block_count - i,
Xorriso_read_quality_untesteD, 0);
if(ret > 0)
ret= 2;
@ -2249,8 +2617,16 @@ abort_check:;
} else {
data_count= 0;
pre_read_time= Sfile_microtime(0);
ret= burn_read_data(drive, ((off_t) (i + from_lba)) * (off_t) 2048, data,
to_read * (off_t) 2048, &data_count, 4 * !retry);
if(async_md5) {
ret= Xorriso__wait_chunk_md5(&state, 1, 0);
if(ret <= 0)
goto ex;
data_pt= state.chunk[state.chunk_w_idx];
}
ret= burn_read_data(drive, ((off_t) (i + from_lba)) * (off_t) 2048,
data_pt, to_read * (off_t) 2048, &data_count, 4 * !retry);
post_read_time= Sfile_microtime(0);
time_diff= post_read_time - pre_read_time;
total_time_diff+= time_diff;
@ -2260,12 +2636,12 @@ abort_check:;
if(data_count / 2048 < to_read) {
if(data_count > 0 && retry) {
if(prev_quality >= 0) {
ret= Spotlist_add_item(spotlist, start_lba,
ret= Xorriso__add_spot(&state, start_lba,
i + from_lba - start_lba, prev_quality, 0);
if(ret <= 0)
goto ex;
}
ret= Spotlist_add_item(spotlist, i + from_lba, data_count / 2048,
ret= Xorriso__add_spot(&state, i + from_lba, data_count / 2048,
Xorriso_read_quality_partiaL, 0);
if(ret <= 0)
goto ex;
@ -2289,120 +2665,18 @@ abort_check:;
/* MD5 checksumming */
if(ctx != NULL) {
for(j= 0; j < to_read; j++) {
lba= i + j + from_lba;
if(lba < (uint32_t) md5_start)
continue;
ret= 0;
if(lba > (uint32_t) (md5_start) + 16 &&
(next_tag == 0 || chain_broken || lba == next_tag)) {
ret= iso_util_decode_md5_tag(data + j * 2048, &tag_type,
&pos, &range_start, &range_size,
&next_tag, tag_md5, !!chain_broken);
}
valid= (ret == 1 || ret == (int) ISO_MD5_AREA_CORRUPTED) &&
pos == lba;
if(valid && tag_type == 2 && (lba < ((uint32_t) md5_start) + 32 ||
in_track_gap)) {
tag_type_name= "superblock";
was_sb_tag= 1;
if(in_track_gap && range_start != ((uint32_t) md5_start) &&
range_start < lba && lba - range_start <= (uint32_t) j) {
/* Looking for next session : start computing in hindsight.
Session start and superblock tag are supposed to be in the
same 64 kB chunk.
*/
iso_md5_end(&ctx, md5);
ret= iso_md5_start(&ctx);
if(ret < 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
iso_md5_compute(&ctx, data + (j - (lba - range_start)) * 2048,
(lba - range_start) * 2048);
md5_start= range_start;
in_track_gap= 0;
}
} else if(valid && tag_type == 4 && lba < 32) {
tag_type_name= "relocated 64kB superblock";
}else if(valid && tag_type == 3 && was_sb_tag) {
tag_type_name= "tree";
}else if(valid && tag_type == 1) {
if(async_md5) {
state.chunk_fill[state.chunk_w_idx]= to_read;
state.chunk_lba[state.chunk_w_idx]= i + from_lba;
state.chunk_state[state.chunk_w_idx]= 1;
/* The MD5 thread will call Xorriso_chunk_md5() */
/* >>> ??? allow this without superblock and tree tag ? */
tag_type_name= "session";
} else {
tag_type_name= "";
}
if (tag_type_name[0]) {
if(range_start != (uint32_t) md5_start) {
sprintf(xorriso->info_text,
"Found MD5 %s tag which covers different data range",
tag_type_name);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
sprintf(xorriso->info_text,
" Expected: %u Found: %u",
(unsigned int) md5_start, range_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
chain_broken= 1;
valid= 0;
} else {
ret= iso_md5_clone(ctx, &cloned_ctx);
if(ret <= 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
iso_md5_end(&cloned_ctx, md5);
if(ret == (int) ISO_MD5_AREA_CORRUPTED) {
comparison= "CORRUPTED";
sev_text= "WARNING";
md5_spot_value= Xorriso_read_quality_md5_mismatcH;
chain_broken= 1;
} else if(! iso_md5_match(tag_md5, md5)) {
comparison= "NON-MATCHING";
sev_text= "WARNING";
md5_spot_value= Xorriso_read_quality_md5_mismatcH;
chain_broken= 1;
} else {
comparison= "matching";
sev_text= "UPDATE";
md5_spot_value= Xorriso_read_quality_md5_matcH;
}
md5_spot_lba= lba;
sprintf(xorriso->info_text,
"Found %s MD5 %s tag: start=%d size=%d",
comparison, tag_type_name, md5_start, lba - md5_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
sev_text, 0);
}
if(valid && (tag_type == 1 ||
(tag_type == 4 && pos == lba && lba < 32))) {
if(md5_spot_value != Xorriso_read_quality_untesteD) {
ret= Spotlist_add_item(spotlist, md5_start,
md5_spot_lba - md5_start, md5_spot_value, 0);
if(ret <= 0)
goto ex;
}
md5_spot_value= Xorriso_read_quality_untesteD;
md5_start = lba + 1;
if (md5_start % 32)
md5_start= md5_start + (32 - (md5_start % 32));
next_tag= 0;
iso_md5_end(&ctx, md5);
ret= iso_md5_start(&ctx);
if(ret < 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
if(tag_type == 1)
in_track_gap= 1;
continue;
}
}
iso_md5_compute(ctx, data + j * 2048, 2048);
state.chunk_w_idx= (state.chunk_w_idx + 1) % state.num_chunks;
} else {
ret= Xorriso_chunk_md5(xorriso, data_pt, to_read,
(uint32_t) (i + from_lba), &state, 0);
if(ret <= 0)
goto ex;
}
}
@ -2426,7 +2700,7 @@ failed_to_write:;
"FAILURE", 0);
{ret= 0; goto ex;}
}
ret= write(job->data_to_fd, data, write_amount);
ret= write(job->data_to_fd, data_pt, write_amount);
if(ret == -1)
goto failed_to_write;
}
@ -2434,8 +2708,8 @@ failed_to_write:;
}
if(quality != prev_quality) {
if(prev_quality >= 0) {
ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba,
prev_quality, 0);
ret= Xorriso__add_spot(&state, start_lba,
i + from_lba - start_lba, prev_quality, 0);
if(ret <= 0)
goto ex;
}
@ -2452,7 +2726,7 @@ failed_to_write:;
}
}
if(prev_quality >= 0) {
ret= Spotlist_add_item(spotlist, start_lba,
ret= Xorriso__add_spot(&state, start_lba,
block_count + from_lba - start_lba, prev_quality, 0);
if(ret <= 0)
goto ex;
@ -2467,28 +2741,48 @@ failed_to_write:;
/* MD5 checksumming : register result */
if(async_md5) {
ret= Xorriso__end_slave_md5(&state, 10000, 0);
if(ret <= 0)
goto ex;
}
/* >>> ??? allow chain_broken to be a match ? */
if(next_tag > 0) {
if(state.next_tag > 0) {
sprintf(xorriso->info_text, "Missing announced MD5 tag: start=%d pos=%d",
md5_start, next_tag);
state.md5_start, state.next_tag);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
md5_spot_value= Xorriso_read_quality_md5_mismatcH;
md5_spot_lba= next_tag;
state.md5_spot_value= Xorriso_read_quality_md5_mismatcH;
state.md5_spot_lba= state.next_tag;
}
if(md5_spot_value != Xorriso_read_quality_untesteD) {
ret= Spotlist_add_item(spotlist, md5_start, md5_spot_lba - md5_start,
md5_spot_value, 0);
if(state.md5_spot_value != Xorriso_read_quality_untesteD) {
ret= Xorriso__add_spot(&state, state.md5_start,
state.md5_spot_lba - state.md5_start, state.md5_spot_value, 0);
if(ret <= 0)
goto ex;
}
ret= 1;
ex:
if(ctx != NULL)
iso_md5_end(&ctx, md5);
ex:;
if(async_md5) {
Xorriso__end_slave_md5(&state, 10000, 0);
sprintf(xorriso->info_text,
"async_chunks=%d , chunk_size=%d , w_sleeps: %.f , r_sleeps: %.f",
state.num_chunks, read_chunk, (double) state.w_sleeps,
(double) state.r_sleeps);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
if(state.chunk != NULL)
pthread_mutex_destroy(&(state.spot_mutex));
Xorriso_free_meM(state.chunk);
Xorriso_free_meM(state.chunk_state);
Xorriso_free_meM(state.chunk_fill);
Xorriso_free_meM(state.chunk_lba);
}
Xorriso_free_meM(data);
if(state.ctx != NULL)
iso_md5_end(&(state.ctx), md5);
return(ret);
}
@ -2519,10 +2813,11 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
if(ret<=0)
goto ex;
/* >>> determine medium type dependent blocking factor:
32 kB for CD (with 2kB retry) and DVD, 64 kB for BD
eventually adjust read_chunk
*/;
ret = burn_disc_get_profile(drive, &profile_no, profile_name);
if(ret <= 0)
profile_no= 0;
if(profile_no >= 0x40 && profile_no <= 0x43) /* BD-ROM, BD-R, BD-RE */
read_chunk= 32;
if(job->min_block_size != 0)
read_chunk= job->min_block_size;
@ -2568,9 +2863,6 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
ret= burn_get_read_capacity(drive, &read_capacity, 0);
if(ret <= 0)
read_capacity= -1;
ret = burn_disc_get_profile(drive, &profile_no, profile_name);
if(ret <= 0)
profile_no= 0;
if(job->max_lba >= 0) {
blocks= job->max_lba + 1 - start_lba;

@ -9,7 +9,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH XORRISO 1 "Version 1.2.3, Apr 02, 2012"
.TH XORRISO 1 "Version 1.2.3, Mai 01, 2012"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -3549,7 +3549,7 @@ abort_file=/var/opt/xorriso/do_abort_check_media
.br
sector_map='' map_with_volid=off patch_lba0=off report=blocks
.br
bad_limit=valid slow_limit=1.0 chunk_size=0s
bad_limit=valid slow_limit=1.0 chunk_size=0s async_chunks=0
.br
Option "reset=now" restores these startup defaults.
.br
@ -3657,6 +3657,11 @@ slow. This may be a fractional number like 0.1 or 1.5.
\fBchunk_size=size\fR
sets the number of bytes to be read in one read operation.
This gets rounded down to full blocks of 2048 bytes. 0 means automatic size.
.br
\fBasync_chunks=number\fR
enables asynchronous MD5 processing if number is 2 or larger.
In this case the given number of read chunks is allocated as fifo buffer.
On very fast MMC drives try: chunk_size=32s async_chunks=16.
.TP
\fB\-check_md5\fR severity iso_rr_path [***]
Compare the data content of the given files in the loaded image with their

@ -3128,7 +3128,7 @@ transmission errors.
time_limit=28800 item_limit=100000 data_to=" event=ALL
abort_file=/var/opt/xorriso/do_abort_check_media
sector_map=" map_with_volid=off patch_lba0=off report=blocks
bad_limit=valid slow_limit=1.0 chunk_size=0s
bad_limit=valid slow_limit=1.0 chunk_size=0s async_chunks=0
Option "reset=now" restores these startup defaults.
Non-default options are:
@ -3224,6 +3224,11 @@ transmission errors.
sets the number of bytes to be read in one read operation.
This gets rounded down to full blocks of 2048 bytes. 0 means
automatic size.
async_chunks=number
enables asynchronous MD5 processing if number is 2 or larger.
In this case the given number of read chunks is allocated as
fifo buffer. On very fast MMC drives try: chunk_size=32s
async_chunks=16.
-check_md5 severity iso_rr_path [***]
Compare the data content of the given files in the loaded image
@ -4381,8 +4386,8 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top
* -cdx sets working directory on disk: Navigate. (line 16)
* -changes_pending overrides change status: Writing. (line 13)
* -charset sets input/output character set: Charset. (line 43)
* -check_md5 verifies file checksum: Verify. (line 148)
* -check_md5_r verifies file tree checksums: Verify. (line 164)
* -check_md5 verifies file checksum: Verify. (line 153)
* -check_md5_r verifies file tree checksums: Verify. (line 169)
* -check_media reads media block by block: Verify. (line 21)
* -check_media_defaults sets -check_media options: Verify. (line 41)
* -chgrp sets group in ISO image: Manip. (line 50)
@ -4813,8 +4818,8 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top
* Verify, compare ISO and disk file, -compare: Navigate. (line 146)
* Verify, compare ISO and disk tree, -compare_r: Navigate. (line 159)
* Verify, compare ISO and disk, -compare_l: Navigate. (line 164)
* Verify, file checksum, -check_md5: Verify. (line 148)
* Verify, file tree checksums, -check_md5_r: Verify. (line 164)
* Verify, file checksum, -check_md5: Verify. (line 153)
* Verify, file tree checksums, -check_md5_r: Verify. (line 169)
* Verify, preset -check_media, -check_media_defaults: Verify. (line 41)
* Write, block size, -dvd_obs: SetWrite. (line 265)
* Write, bootability, -boot_image: Bootable. (line 26)
@ -4871,32 +4876,32 @@ Node: DialogCtl139832
Node: Inquiry142429
Node: Navigate147295
Node: Verify155556
Node: Restore164245
Node: Emulation171154
Node: Scripting180965
Node: Frontend188125
Node: Examples189425
Node: ExDevices190602
Node: ExCreate191261
Node: ExDialog192546
Node: ExGrowing193811
Node: ExModifying194616
Node: ExBootable195120
Node: ExCharset195672
Node: ExPseudo196493
Node: ExCdrecord197391
Node: ExMkisofs197708
Node: ExGrowisofs199048
Node: ExException200183
Node: ExTime200637
Node: ExIncBackup201096
Node: ExRestore205087
Node: ExRecovery206047
Node: Files206617
Node: Seealso207916
Node: Bugreport208639
Node: Legal209220
Node: CommandIdx210150
Node: ConceptIdx225738
Node: Restore164522
Node: Emulation171431
Node: Scripting181242
Node: Frontend188402
Node: Examples189702
Node: ExDevices190879
Node: ExCreate191538
Node: ExDialog192823
Node: ExGrowing194088
Node: ExModifying194893
Node: ExBootable195397
Node: ExCharset195949
Node: ExPseudo196770
Node: ExCdrecord197668
Node: ExMkisofs197985
Node: ExGrowisofs199325
Node: ExException200460
Node: ExTime200914
Node: ExIncBackup201373
Node: ExRestore205364
Node: ExRecovery206324
Node: Files206894
Node: Seealso208193
Node: Bugreport208916
Node: Legal209497
Node: CommandIdx210427
Node: ConceptIdx226015

End Tag Table

@ -50,7 +50,7 @@
@c man .\" First parameter, NAME, should be all caps
@c man .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
@c man .\" other parameters are allowed: see man(7), man(1)
@c man .TH XORRISO 1 "Version 1.2.3, Apr 02, 2012"
@c man .TH XORRISO 1 "Version 1.2.3, Mai 01, 2012"
@c man .\" Please adjust this date whenever revising the manpage.
@c man .\"
@c man .\" Some roff macros, for reference:
@ -4199,7 +4199,7 @@ abort_file=/var/opt/xorriso/do_abort_check_media
@*
sector_map='' map_with_volid=off patch_lba0=off report=blocks
@*
bad_limit=valid slow_limit=1.0 chunk_size=0s
bad_limit=valid slow_limit=1.0 chunk_size=0s async_chunks=0
@*
Option "reset=now" restores these startup defaults.
@*
@ -4309,6 +4309,11 @@ slow. This may be a fractional number like 0.1 or 1.5.
@item chunk_size=size
sets the number of bytes to be read in one read operation.
This gets rounded down to full blocks of 2048 bytes. 0 means automatic size.
@*
@item async_chunks=number
enables asynchronous MD5 processing if number is 2 or larger.
In this case the given number of read chunks is allocated as fifo buffer.
On very fast MMC drives try: chunk_size=32s async_chunks=16.
@end table
@c man .TP
@kindex -check_md5 verifies file checksum

@ -1 +1 @@
#define Xorriso_timestamP "2012.04.28.161532"
#define Xorriso_timestamP "2012.05.01.075022"

Loading…
Cancel
Save