New -check_media option async_chunks=
This commit is contained in:
@ -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;
|
||||
|
Reference in New Issue
Block a user