New -check_media option async_chunks=

This commit is contained in:
Thomas Schmitt 2012-05-01 07:49:46 +00:00
parent 917b487343
commit 6668ab7d32
7 changed files with 510 additions and 188 deletions

View File

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

View File

@ -99,7 +99,10 @@ struct CheckmediajoB {
int max_lba; /* if >=0 : read up to this address, else use mode */ int max_lba; /* if >=0 : read up to this address, else use mode */
int min_block_size; /* granularity desired by user 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 int mode; /* 0= track by track
1= single sweep over libisoburn medium capacity 1= single sweep over libisoburn medium capacity
2= single sweep over libburn medium capacity 2= single sweep over libburn medium capacity

View File

@ -22,6 +22,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <pthread.h>
#include "xorriso.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) /* @param flag bit0= this is a follow-up session (i.e. on CD: TAO)
bit1= no pacifier messages bit1= no pacifier messages
bit2= compute stream MD5 and look out for checksum tag 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; int start_lba= 0;
struct burn_drive *drive; struct burn_drive *drive;
struct burn_drive_info *dinfo; struct burn_drive_info *dinfo;
char *data= NULL; char *data= NULL, *data_pt;
off_t data_count, to_read, read_count= 0, write_amount; 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 pre_read_time, post_read_time, time_diff, total_time_diff= 0;
double last_abort_file_time= 0; double last_abort_file_time= 0;
void *ctx= NULL, *cloned_ctx= NULL; void *ctx= NULL;
char md5[16], tag_md5[16]; char md5[16];
uint32_t pos, range_start, range_size, next_tag= 0, lba, md5_spot_lba= 0; size_t data_size;
int md5_spot_value= Xorriso_read_quality_untesteD, chain_broken= 0; struct xorriso_md5_state state;
int tag_type= 0, valid, was_sb_tag= 0, in_track_gap= 0; int num_chunks, async_md5;
char *comparison= "", *sev_text= "DEBUG", *tag_type_name= ""; 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) if(read_chunk > 1024)
read_chunk= 1024; read_chunk= 1024;
else if(read_chunk < 1) else if(read_chunk < 1)
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, ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to check media readability", "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; start_lba= from_lba;
to_read= read_chunk; to_read= read_chunk;
post_read_time= Sfile_microtime(0); 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); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
abort_check:; abort_check:;
if(prev_quality >= 0) { 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); prev_quality, 0);
if(ret <= 0) if(ret <= 0)
goto ex; 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); Xorriso_read_quality_untesteD, 0);
if(ret > 0) if(ret > 0)
ret= 2; ret= 2;
@ -2249,8 +2617,16 @@ abort_check:;
} else { } else {
data_count= 0; data_count= 0;
pre_read_time= Sfile_microtime(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); post_read_time= Sfile_microtime(0);
time_diff= post_read_time - pre_read_time; time_diff= post_read_time - pre_read_time;
total_time_diff+= time_diff; total_time_diff+= time_diff;
@ -2260,12 +2636,12 @@ abort_check:;
if(data_count / 2048 < to_read) { if(data_count / 2048 < to_read) {
if(data_count > 0 && retry) { if(data_count > 0 && retry) {
if(prev_quality >= 0) { 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); i + from_lba - start_lba, prev_quality, 0);
if(ret <= 0) if(ret <= 0)
goto ex; 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); Xorriso_read_quality_partiaL, 0);
if(ret <= 0) if(ret <= 0)
goto ex; goto ex;
@ -2289,120 +2665,18 @@ abort_check:;
/* MD5 checksumming */ /* MD5 checksumming */
if(ctx != NULL) { if(ctx != NULL) {
for(j= 0; j < to_read; j++) { if(async_md5) {
lba= i + j + from_lba; state.chunk_fill[state.chunk_w_idx]= to_read;
if(lba < (uint32_t) md5_start) state.chunk_lba[state.chunk_w_idx]= i + from_lba;
continue; state.chunk_state[state.chunk_w_idx]= 1;
ret= 0; /* The MD5 thread will call Xorriso_chunk_md5() */
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) {
/* >>> ??? allow this without superblock and tree tag ? */ state.chunk_w_idx= (state.chunk_w_idx + 1) % state.num_chunks;
} else {
tag_type_name= "session"; ret= Xorriso_chunk_md5(xorriso, data_pt, to_read,
} else { (uint32_t) (i + from_lba), &state, 0);
tag_type_name= ""; if(ret <= 0)
} goto ex;
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);
} }
} }
@ -2426,7 +2700,7 @@ failed_to_write:;
"FAILURE", 0); "FAILURE", 0);
{ret= 0; goto ex;} {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) if(ret == -1)
goto failed_to_write; goto failed_to_write;
} }
@ -2434,8 +2708,8 @@ failed_to_write:;
} }
if(quality != prev_quality) { if(quality != prev_quality) {
if(prev_quality >= 0) { if(prev_quality >= 0) {
ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba, ret= Xorriso__add_spot(&state, start_lba,
prev_quality, 0); i + from_lba - start_lba, prev_quality, 0);
if(ret <= 0) if(ret <= 0)
goto ex; goto ex;
} }
@ -2452,7 +2726,7 @@ failed_to_write:;
} }
} }
if(prev_quality >= 0) { 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); block_count + from_lba - start_lba, prev_quality, 0);
if(ret <= 0) if(ret <= 0)
goto ex; goto ex;
@ -2467,28 +2741,48 @@ failed_to_write:;
/* MD5 checksumming : register result */ /* 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 ? */ /* >>> ??? 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", 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); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
md5_spot_value= Xorriso_read_quality_md5_mismatcH; state.md5_spot_value= Xorriso_read_quality_md5_mismatcH;
md5_spot_lba= next_tag; state.md5_spot_lba= state.next_tag;
} }
if(md5_spot_value != Xorriso_read_quality_untesteD) { if(state.md5_spot_value != Xorriso_read_quality_untesteD) {
ret= Spotlist_add_item(spotlist, md5_start, md5_spot_lba - md5_start, ret= Xorriso__add_spot(&state, state.md5_start,
md5_spot_value, 0); state.md5_spot_lba - state.md5_start, state.md5_spot_value, 0);
if(ret <= 0) if(ret <= 0)
goto ex; goto ex;
} }
ret= 1; ret= 1;
ex: ex:;
if(ctx != NULL) if(async_md5) {
iso_md5_end(&ctx, 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); Xorriso_free_meM(data);
if(state.ctx != NULL)
iso_md5_end(&(state.ctx), md5);
return(ret); return(ret);
} }
@ -2519,10 +2813,11 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
if(ret<=0) if(ret<=0)
goto ex; goto ex;
/* >>> determine medium type dependent blocking factor: ret = burn_disc_get_profile(drive, &profile_no, profile_name);
32 kB for CD (with 2kB retry) and DVD, 64 kB for BD if(ret <= 0)
eventually adjust read_chunk 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) if(job->min_block_size != 0)
read_chunk= job->min_block_size; 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); ret= burn_get_read_capacity(drive, &read_capacity, 0);
if(ret <= 0) if(ret <= 0)
read_capacity= -1; read_capacity= -1;
ret = burn_disc_get_profile(drive, &profile_no, profile_name);
if(ret <= 0)
profile_no= 0;
if(job->max_lba >= 0) { if(job->max_lba >= 0) {
blocks= job->max_lba + 1 - start_lba; blocks= job->max_lba + 1 - start_lba;

View File

@ -9,7 +9,7 @@
.\" First parameter, NAME, should be all caps .\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1) .\" 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. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" Some roff macros, for reference:
@ -3549,7 +3549,7 @@ abort_file=/var/opt/xorriso/do_abort_check_media
.br .br
sector_map='' map_with_volid=off patch_lba0=off report=blocks sector_map='' map_with_volid=off patch_lba0=off report=blocks
.br .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 .br
Option "reset=now" restores these startup defaults. Option "reset=now" restores these startup defaults.
.br .br
@ -3657,6 +3657,11 @@ slow. This may be a fractional number like 0.1 or 1.5.
\fBchunk_size=size\fR \fBchunk_size=size\fR
sets the number of bytes to be read in one read operation. 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. 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 .TP
\fB\-check_md5\fR severity iso_rr_path [***] \fB\-check_md5\fR severity iso_rr_path [***]
Compare the data content of the given files in the loaded image with their Compare the data content of the given files in the loaded image with their

View File

@ -3128,7 +3128,7 @@ transmission errors.
time_limit=28800 item_limit=100000 data_to=" event=ALL time_limit=28800 item_limit=100000 data_to=" event=ALL
abort_file=/var/opt/xorriso/do_abort_check_media abort_file=/var/opt/xorriso/do_abort_check_media
sector_map=" map_with_volid=off patch_lba0=off report=blocks 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. Option "reset=now" restores these startup defaults.
Non-default options are: Non-default options are:
@ -3224,6 +3224,11 @@ transmission errors.
sets the number of bytes to be read in one read operation. sets the number of bytes to be read in one read operation.
This gets rounded down to full blocks of 2048 bytes. 0 means This gets rounded down to full blocks of 2048 bytes. 0 means
automatic size. 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 [***] -check_md5 severity iso_rr_path [***]
Compare the data content of the given files in the loaded image 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) * -cdx sets working directory on disk: Navigate. (line 16)
* -changes_pending overrides change status: Writing. (line 13) * -changes_pending overrides change status: Writing. (line 13)
* -charset sets input/output character set: Charset. (line 43) * -charset sets input/output character set: Charset. (line 43)
* -check_md5 verifies file checksum: Verify. (line 148) * -check_md5 verifies file checksum: Verify. (line 153)
* -check_md5_r verifies file tree checksums: Verify. (line 164) * -check_md5_r verifies file tree checksums: Verify. (line 169)
* -check_media reads media block by block: Verify. (line 21) * -check_media reads media block by block: Verify. (line 21)
* -check_media_defaults sets -check_media options: Verify. (line 41) * -check_media_defaults sets -check_media options: Verify. (line 41)
* -chgrp sets group in ISO image: Manip. (line 50) * -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 file, -compare: Navigate. (line 146)
* Verify, compare ISO and disk tree, -compare_r: Navigate. (line 159) * Verify, compare ISO and disk tree, -compare_r: Navigate. (line 159)
* Verify, compare ISO and disk, -compare_l: Navigate. (line 164) * Verify, compare ISO and disk, -compare_l: Navigate. (line 164)
* Verify, file checksum, -check_md5: Verify. (line 148) * Verify, file checksum, -check_md5: Verify. (line 153)
* Verify, file tree checksums, -check_md5_r: Verify. (line 164) * Verify, file tree checksums, -check_md5_r: Verify. (line 169)
* Verify, preset -check_media, -check_media_defaults: Verify. (line 41) * Verify, preset -check_media, -check_media_defaults: Verify. (line 41)
* Write, block size, -dvd_obs: SetWrite. (line 265) * Write, block size, -dvd_obs: SetWrite. (line 265)
* Write, bootability, -boot_image: Bootable. (line 26) * Write, bootability, -boot_image: Bootable. (line 26)
@ -4871,32 +4876,32 @@ Node: DialogCtl139832
Node: Inquiry142429 Node: Inquiry142429
Node: Navigate147295 Node: Navigate147295
Node: Verify155556 Node: Verify155556
Node: Restore164245 Node: Restore164522
Node: Emulation171154 Node: Emulation171431
Node: Scripting180965 Node: Scripting181242
Node: Frontend188125 Node: Frontend188402
Node: Examples189425 Node: Examples189702
Node: ExDevices190602 Node: ExDevices190879
Node: ExCreate191261 Node: ExCreate191538
Node: ExDialog192546 Node: ExDialog192823
Node: ExGrowing193811 Node: ExGrowing194088
Node: ExModifying194616 Node: ExModifying194893
Node: ExBootable195120 Node: ExBootable195397
Node: ExCharset195672 Node: ExCharset195949
Node: ExPseudo196493 Node: ExPseudo196770
Node: ExCdrecord197391 Node: ExCdrecord197668
Node: ExMkisofs197708 Node: ExMkisofs197985
Node: ExGrowisofs199048 Node: ExGrowisofs199325
Node: ExException200183 Node: ExException200460
Node: ExTime200637 Node: ExTime200914
Node: ExIncBackup201096 Node: ExIncBackup201373
Node: ExRestore205087 Node: ExRestore205364
Node: ExRecovery206047 Node: ExRecovery206324
Node: Files206617 Node: Files206894
Node: Seealso207916 Node: Seealso208193
Node: Bugreport208639 Node: Bugreport208916
Node: Legal209220 Node: Legal209497
Node: CommandIdx210150 Node: CommandIdx210427
Node: ConceptIdx225738 Node: ConceptIdx226015
 
End Tag Table End Tag Table

View File

@ -50,7 +50,7 @@
@c man .\" First parameter, NAME, should be all caps @c man .\" First parameter, NAME, should be all caps
@c man .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection @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 .\" 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 .\" Please adjust this date whenever revising the manpage.
@c man .\" @c man .\"
@c man .\" Some roff macros, for reference: @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 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. 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 @item chunk_size=size
sets the number of bytes to be read in one read operation. 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. 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 @end table
@c man .TP @c man .TP
@kindex -check_md5 verifies file checksum @kindex -check_md5 verifies file checksum

View File

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