From 2c43e3ae7688e1c574bf2636118ce5423168ddce Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Wed, 30 Sep 2009 09:25:34 +0000 Subject: [PATCH] New -check_media sub options bad_limit=, slow_limit=, chunk_size= --- libisoburn/trunk/xorriso/xorriso.1 | 13 +- libisoburn/trunk/xorriso/xorriso.c | 152 ++++++++++++++----- libisoburn/trunk/xorriso/xorriso_private.h | 15 +- libisoburn/trunk/xorriso/xorriso_timestamp.h | 2 +- libisoburn/trunk/xorriso/xorrisoburn.c | 31 +++- 5 files changed, 161 insertions(+), 52 deletions(-) diff --git a/libisoburn/trunk/xorriso/xorriso.1 b/libisoburn/trunk/xorriso/xorriso.1 index b9b20371..2e444423 100644 --- a/libisoburn/trunk/xorriso/xorriso.1 +++ b/libisoburn/trunk/xorriso/xorriso.1 @@ -2,7 +2,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 "Sep 27, 2009" +.TH XORRISO 1 "Sep 29, 2009" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -2619,6 +2619,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 Option "reset=now" restores these startup defaults. .br Non-default options are: @@ -2689,6 +2690,16 @@ have an -indev and a loaded image. ":force" may be appended after the number. .br "use=sector_map" does not read any media but loads the file given by option sector_map= and processes this virtual outcome. +.br +"bad_limit=" sets the highest quality which shall be considered as damage. +Choose one of "good", "md5_match", "slow", "partial", "valid", "untested", +"invalid", "tao_end", "off_track", "md5_mismatch", "unreadable". +.br +"slow_limit=" sets the time threshold for a single read chunk to considered +slow. This may be a fractional number like 0.1 or 1.5. +.br +"chunk_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. .TP \fB\-check_md5\fR severity iso_rr_path [***] Compare the data content of the given files in the loaded image with their diff --git a/libisoburn/trunk/xorriso/xorriso.c b/libisoburn/trunk/xorriso/xorriso.c index 70d8f6e7..4f197a12 100644 --- a/libisoburn/trunk/xorriso/xorriso.c +++ b/libisoburn/trunk/xorriso/xorriso.c @@ -4193,8 +4193,9 @@ int Spotlist_add_item(struct SpotlisT *o, int start_lba, int blocks, (o->list_count)++; if(debug_verbous) {char quality_name[80]; - fprintf(stderr, "debug: lba %10d , size %10d , quality %s\n", - start_lba, blocks, Spotlist__quality_name(quality, quality_name, 0)); + fprintf(stderr, "debug: lba %10d , size %10d , quality '%s'\n", + start_lba, blocks, Spotlist__quality_name(quality, quality_name, + Xorriso_read_quality_invaliD, 0) + 2); } return(1); @@ -4262,32 +4263,41 @@ int Spotlist_get_item(struct SpotlisT *o, int idx, } -char *Spotlist__quality_name(int quality, char name[80], int flag) +char *Spotlist__quality_name(int quality, char name[80], int bad_limit, + int flag) { - if(quality == Xorriso_read_quality_gooD) - strcpy(name, "+ good"); - else if(quality == Xorriso_read_quality_md5_matcH) - strcpy(name, "+ md5_match"); - else if(quality == Xorriso_read_quality_sloW) - strcpy(name, "+ slow"); - else if(quality == Xorriso_read_quality_partiaL) - strcpy(name, "+ partial"); - else if(quality == Xorriso_read_quality_valiD) - strcpy(name, "+ valid"); - else if(quality == Xorriso_read_quality_untesteD) - strcpy(name, "0 untested"); - else if(quality == Xorriso_read_quality_invaliD) - strcpy(name, "- invalid"); - else if(quality == Xorriso_read_quality_tao_enD) - strcpy(name, "0 tao end"); - else if(quality == Xorriso_read_quality_off_tracK) - strcpy(name, "0 off track"); - else if(quality == Xorriso_read_quality_md5_mismatcH) - strcpy(name, "- md5_mismatch"); - else if(quality == Xorriso_read_quality_unreadablE) - strcpy(name, "- unreadable"); + if(quality == Xorriso_read_quality_untesteD || + quality == Xorriso_read_quality_tao_enD || + quality == Xorriso_read_quality_off_tracK) + strcpy(name, "0 "); + else if(quality <= bad_limit) + strcpy(name, "- "); else - sprintf(name, "0x%8.8X", (unsigned) quality); + strcpy(name, "+ "); + if(quality == Xorriso_read_quality_gooD) + strcat(name, "good"); + else if(quality == Xorriso_read_quality_md5_matcH) + strcat(name, "md5_match"); + else if(quality == Xorriso_read_quality_sloW) + strcat(name, "slow"); + else if(quality == Xorriso_read_quality_partiaL) + strcat(name, "partial"); + else if(quality == Xorriso_read_quality_valiD) + strcat(name, "valid"); + else if(quality == Xorriso_read_quality_untesteD) + strcat(name, "untested"); + else if(quality == Xorriso_read_quality_invaliD) + strcat(name, "invalid"); + else if(quality == Xorriso_read_quality_tao_enD) + strcat(name, "tao_end"); + else if(quality == Xorriso_read_quality_off_tracK) + strcat(name, "off_track"); + else if(quality == Xorriso_read_quality_md5_mismatcH) + strcat(name, "md5_mismatch"); + else if(quality == Xorriso_read_quality_unreadablE) + strcat(name, "unreadable"); + else + sprintf(name, "0 0x%8.8X", (unsigned int) quality); return(name); } @@ -4625,7 +4635,7 @@ int Checkmediajob_new(struct CheckmediajoB **o, int flag) m->use_dev= 0; m->min_lba= -1; m->max_lba= -1; - m->min_block_size= 16; + m->min_block_size= 0; m->mode= 0; m->start_time= time(NULL); m->time_limit= 28800; @@ -4643,6 +4653,8 @@ int Checkmediajob_new(struct CheckmediajoB **o, int flag) m->retry= 0; m->report_mode= 0; strcpy(m->event_severity, "ALL"); + m->slow_threshold_seq= 1.0; + m->untested_valid= 0; return(1); } @@ -4683,6 +4695,8 @@ int Checkmediajob_copy(struct CheckmediajoB *from, struct CheckmediajoB *to, to->retry= from->retry; to->report_mode= from->report_mode; strcpy(to->event_severity, from->event_severity); + to->slow_threshold_seq= from->slow_threshold_seq; + to->untested_valid= from->untested_valid; return(1); } @@ -4788,6 +4802,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->no_volset_present= 0; m->in_sector_map= NULL; m->check_media_default= NULL; + m->check_media_bad_limit= Xorriso_read_quality_invaliD; m->outdev[0]= 0; m->out_drive_handle= NULL; m->out_charset= NULL; @@ -6360,10 +6375,41 @@ 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], "bad_limit=", 10) == 0) { + if(strcmp(argv[i] + 10, "good") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_gooD; + else if(strcmp(argv[i] + 10, "md5_match") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_md5_matcH; + else if(strcmp(argv[i] + 10, "slow") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_sloW; + else if(strcmp(argv[i] + 10, "partial") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_partiaL; + else if(strcmp(argv[i] + 10, "valid") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_valiD; + else if(strcmp(argv[i] + 10, "untested") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_untesteD; + else if(strcmp(argv[i] + 10, "invalid") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_invaliD; + else if(strcmp(argv[i] + 10, "tao_end") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_tao_enD; + else if(strcmp(argv[i] + 10, "off_track") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_off_tracK; + else if(strcmp(argv[i] + 10, "md5_mismatch") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_md5_mismatcH; + else if(strcmp(argv[i] + 10, "unreadable") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_unreadablE; + else + goto unknown_value; } else if(strncmp(argv[i], "data_to=", 8) == 0) { ret= Sfile_str(job->data_to_path, argv[i] + 8, 0); if(ret <= 0) goto ex; + } else if(strncmp(argv[i], "chunk_size=", 11) == 0) { + num= Scanf_io_size(argv[i] + 11, 1); + if(num >= 2048 || num == 0) + job->min_block_size= num / 2048; + else + goto unknown_value; } else if(strncmp(argv[i], "event=", 6) == 0) { strncpy(sev_text, argv[i] + 6, 19); sev_text[19]= 0; @@ -6429,6 +6475,7 @@ int Xorriso_check_media_setup_job(struct XorrisO *xorriso, } Checkmediajob_copy(default_job, job, 0); Checkmediajob_destroy(&default_job, 0); + xorriso->check_media_bad_limit= Xorriso_read_quality_invaliD; } else if(strncmp(argv[i], "retry=", 6) == 0) { if(strcmp(argv[i] + 6, "on") == 0) job->retry= 1; @@ -6442,6 +6489,8 @@ int Xorriso_check_media_setup_job(struct XorrisO *xorriso, ret= Sfile_str(job->sector_map_path, argv[i] + 11, 0); if(ret <= 0) goto ex; + } else if(strncmp(argv[i], "slow_limit=", 11) == 0) { + sscanf(argv[i] + 11, "%lf", &(job->slow_threshold_seq)); } else if(strncmp(argv[i], "time_limit=", 11) == 0 || strncmp(argv[i], "item_limit=", 11) == 0 ) { num= -1; @@ -6452,6 +6501,18 @@ int Xorriso_check_media_setup_job(struct XorrisO *xorriso, job->time_limit= num; else job->item_limit= num; + +#ifdef NIX + } else if(strncmp(argv[i], "untested=", 9) == 0) { + if(strcmp(argv[i] + 9, "damaged") == 0) + job->untested_valid= 0; + if(strcmp(argv[i] + 9, "undamaged") == 0 || + strcmp(argv[i] + 9, "ok") == 0) + job->untested_valid= 1; + else + goto unknown_value; +#endif + } else if(strncmp(argv[i], "use=", 4) == 0) { if(strcmp(argv[i] + 4, "outdev") == 0) job->use_dev= 1; @@ -6494,7 +6555,7 @@ int Xorriso_check_media_list_job(struct XorrisO *xorriso, char *report, int flag) { int all, ret; - char default_report[161]; + char default_report[161], quality_name[80]; struct CheckmediajoB *dflt= NULL; all= !(flag&1); @@ -6557,6 +6618,14 @@ int Xorriso_check_media_list_job(struct XorrisO *xorriso, sprintf(report + strlen(report), " report=%s", job->report_mode == 0 ? "blocks" : job->report_mode == 1 ? "files" : "blocks_files"); + if(all || job->slow_threshold_seq != dflt->slow_threshold_seq) + sprintf(report + strlen(report), " slow_limit=%f", job->slow_threshold_seq); + if(all || xorriso->check_media_bad_limit != Xorriso_read_quality_invaliD) + sprintf(report + strlen(report), " bad_limit=%s", + Spotlist__quality_name(xorriso->check_media_bad_limit, quality_name, + Xorriso_read_quality_invaliD, 0) + 2); + if(all || job->min_block_size != dflt->min_block_size) + sprintf(report + strlen(report), " chunk_size=%ds", job->min_block_size); if(all || strcmp(job->event_severity, "ALL") != 0) sprintf(report + strlen(report), " event=%s", job->event_severity); if(strlen(report) > 4 * SfileadrL) @@ -11833,7 +11902,7 @@ int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso, int flag) { struct SectorbitmaP *m; - int map_sectors= -1, map_sector_size= -1; + int map_sectors= -1, map_sector_size= -1, valid; int list_sectors, list_blocks, sector_size, sector_blocks; int replace_map= 0, count, i, lba, blocks, quality, ret, pass; @@ -11875,20 +11944,21 @@ int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso, } count= Spotlist_count(spotlist, 0); - /* first set good bits, then eventueally override by bad bits */ + /* first set good bits, then eventually override by bad bits */ for(pass= 0; pass < 2; pass++) { for(i= 0; i < count; i++) { ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0); if(ret <= 0) continue; - if(quality == Xorriso_read_quality_untesteD && !(flag & 1)) + valid= quality > xorriso->check_media_bad_limit; + if(quality == Xorriso_read_quality_untesteD && (flag & 1)) + valid= 1; + else if(pass == 0 && !valid) continue; - if(pass == 0 && quality < Xorriso_read_quality_untesteD) - continue; - else if(pass == 1 && quality >= Xorriso_read_quality_untesteD) + else if(pass == 1 && valid) continue; Sectorbitmap_set_range(m, lba / sector_blocks, blocks / sector_blocks, - quality >= Xorriso_read_quality_untesteD); + valid); } } if(replace_map) { @@ -13905,7 +13975,8 @@ int Xorriso_option_check_media(struct XorrisO *xorriso, continue; sprintf(xorriso->result_line, "%s: %10d , %10d , %s\n", pass == 0 ? "Media region " : "MD5 tag range", - lba, blocks, Spotlist__quality_name(quality, quality_name, 0)); + lba, blocks, Spotlist__quality_name(quality, quality_name, + xorriso->check_media_bad_limit, 0)); Xorriso_result(xorriso,0); } } @@ -14437,7 +14508,7 @@ int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv, /* only allow directories if they actually represent split data files */ ret= 0; if(xorriso->do_concat_split) - ret= Xorriso_is_split(xorriso, eff_origin, NULL, 2); + ret= Xorriso_is_split(xorriso, eff_origin, NULL, 0); if(ret<0) goto problem_handler; if(ret==0) { @@ -16147,7 +16218,8 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " retry=on|off|default , data_to=filepath ,", " sector_map=filepath , map_with_volid=on|off ,", " patch_lba0=on|off|force|blockadr[:force] ,", -" report=blocks|files|blocks_files event=severity", +" report=blocks|files|blocks_files event=severity ,", +" bad_limit=quality , slow_limit=seconds , chunk_size=bytes", " -check_media_defaults [options] --", " Preset options for runs of -check_media and -extract_cut.", "", @@ -19836,10 +19908,6 @@ next_command:; } else if(strcmp(cmd,"test")==0) { /* This option does not exist. */ /* install temporary test code here */; - (*idx)++; - fprintf(stderr, "xorriso_DEBUG: Xorriso_is_split(%s)= %d\n", - arg1, Xorriso_is_split(xorriso, arg1, NULL, 2)); - } else if(strcmp(cmd,"toc")==0) { Xorriso_option_toc(xorriso, 0); diff --git a/libisoburn/trunk/xorriso/xorriso_private.h b/libisoburn/trunk/xorriso/xorriso_private.h index 0f535322..d7ab2297 100644 --- a/libisoburn/trunk/xorriso/xorriso_private.h +++ b/libisoburn/trunk/xorriso/xorriso_private.h @@ -224,6 +224,7 @@ struct XorrisO { /* the global context of xorriso */ int no_volset_present; /* set to 1 on first failure */ struct CheckmediajoB *check_media_default; + int check_media_bad_limit; /* values defined as Xorriso_read_quality_* */ struct SectorbitmaP *in_sector_map; /* eventual sector validity bitmap */ @@ -1202,7 +1203,8 @@ int Spotlist_sector_size(struct SpotlisT *o, int read_chunk, int flag); int Spotlist_get_item(struct SpotlisT *o, int idx, int *start_lba, int *blocks, int *quality, int flag); -char *Spotlist__quality_name(int quality, char name[80], int flag); +char *Spotlist__quality_name(int quality, char name[80], int bad_limit, + int flag); #define Xorriso_read_quality_gooD 0x7fffffff @@ -1224,8 +1226,7 @@ struct CheckmediajoB { int min_lba; /* if >=0 : begin checking at this address */ int max_lba; /* if >=0 : read up to this address, else use mode */ - int min_block_size; /* >>> not yet implemented: - granularity desired by user + int min_block_size; /* granularity desired by user */ int mode; /* 0= track by track 1= single sweep over libisoburn media capacity @@ -1264,6 +1265,14 @@ struct CheckmediajoB { discovered. */ + double slow_threshold_seq; /* Time limit in seconds for the decision whether + a read operation is considered slow. This does + not apply to thr first read of an interval. + */ + + int untested_valid; /* 1= mark untested data blocks as valid when calling + Xorriso_spotlist_to_sectormap() + */ }; int Checkmediajob_new(struct CheckmediajoB **o, int flag); diff --git a/libisoburn/trunk/xorriso/xorriso_timestamp.h b/libisoburn/trunk/xorriso/xorriso_timestamp.h index f1d3490e..a214c171 100644 --- a/libisoburn/trunk/xorriso/xorriso_timestamp.h +++ b/libisoburn/trunk/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.09.28.173322" +#define Xorriso_timestamP "2009.09.30.092640" diff --git a/libisoburn/trunk/xorriso/xorrisoburn.c b/libisoburn/trunk/xorriso/xorrisoburn.c index 22097a2c..b2f373c3 100644 --- a/libisoburn/trunk/xorriso/xorrisoburn.c +++ b/libisoburn/trunk/xorriso/xorrisoburn.c @@ -9612,10 +9612,8 @@ abort_check:; goto ex; } else { quality= Xorriso_read_quality_gooD; - - /* >>> find better threshold than 1.0 */ - - if(time_diff > 1.0 && i > 0) + if(time_diff > job->slow_threshold_seq && job->slow_threshold_seq > 0 && + i > 0) quality= Xorriso_read_quality_sloW; } @@ -9827,6 +9825,7 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist, int media_blocks= 0, read_chunk= 16, ret, mode, start_lba= 0; int blocks, os_errno, i, j, last_track_end= -1, track_blocks, track_lba; int num_sessions, num_tracks, declare_untested= 0, md5_start; + int read_capacity= -1, end_lba, hret, count, quality; char *toc_info= NULL; struct burn_drive *drive; struct burn_drive_info *dinfo; @@ -9849,6 +9848,8 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist, 32 kB for CD (with 2kB retry) and DVD, 64 kB for BD eventually adjust read_chunk */; + if(job->min_block_size != 0) + read_chunk= job->min_block_size; ret= Spotlist_new(spotlist, 0); if(ret <= 0) @@ -9881,6 +9882,10 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist, if(ret <= 0) goto ex; } + ret= burn_get_read_capacity(drive, &read_capacity, 0); + if(ret <= 0) + read_capacity= -1; + if(job->max_lba >= 0) { blocks= job->max_lba + 1 - start_lba; xorriso->pacifier_total= blocks; @@ -9984,13 +9989,29 @@ ex:; if(job->data_to_fd != -1) close(job->data_to_fd); job->data_to_fd= -1; + + if(read_capacity >= 0) { + count= Spotlist_count(*spotlist, 0); + end_lba= 0; + for(i= 0; i < count; i++) { + Spotlist_get_item(*spotlist, i, &start_lba, &blocks, &quality, 0); + if(start_lba + blocks > end_lba) + end_lba= start_lba + blocks; + } + if(read_capacity > end_lba) { + hret= Spotlist_add_item(*spotlist, end_lba, read_capacity - end_lba, + Xorriso_read_quality_untesteD, 0); + if(hret < ret) + ret= hret; + } + } if(ret > 0) ret= Xorriso_update_in_sector_map(xorriso, *spotlist, read_chunk, job, 0); if(ret > 0) { ret= Xorriso_spotlist_to_sectormap(xorriso, *spotlist, read_chunk, - &(job->sector_map), 0); + &(job->sector_map), !!job->untested_valid); if(ret > 0 && job->sector_map_path[0]) { ret= Sectorbitmap_to_file(job->sector_map, job->sector_map_path, toc_info, xorriso->info_text, &os_errno, 0);