2
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
4
Copyright 2007-2010 Thomas Schmitt, <scdbackup@gmx.net>
6
Provided under GPL version 2 or later.
8
This file contains the implementation of classes SpotlistiteM, SectorbitmaP,
9
CheckmediajoB which perform verifying runs on media resp. images.
13
#include "../config.h"
17
#include <sys/types.h>
29
#include "xorriso_private.h"
30
#include "xorrisoburn.h"
33
/* ------------------------------ SpotlisT -------------------------------- */
40
struct SpotlistiteM *next;
44
int Spotlistitem_new(struct SpotlistiteM **o, int start_lba, int blocks,
45
int quality, int flag)
47
struct SpotlistiteM *m;
49
m= TSOB_FELD(struct SpotlistiteM,1);
53
m->start_lba= start_lba;
61
int Spotlistitem_destroy(struct SpotlistiteM **o, int flag)
72
struct SpotlistiteM *list_start;
73
struct SpotlistiteM *list_end;
75
struct SpotlistiteM *current_item;
80
int Spotlist_new(struct SpotlisT **o, int flag)
84
m= TSOB_FELD(struct SpotlisT,1);
91
m->current_item= NULL;
97
int Spotlist_destroy(struct SpotlisT **o, int flag)
100
struct SpotlistiteM *li, *next_li;
105
for(li= m->list_start; li != NULL; li= next_li) {
107
Spotlistitem_destroy(&li, 0);
115
int Spotlist_add_item(struct SpotlisT *o, int start_lba, int blocks,
116
int quality, int flag)
119
struct SpotlistiteM *li;
120
static int debug_verbous= 0;
122
ret= Spotlistitem_new(&li, start_lba, blocks, quality, 0);
125
if(o->list_end != NULL)
126
o->list_end->next= li;
128
if(o->list_start == NULL)
132
if(debug_verbous) {char quality_name[80];
133
fprintf(stderr, "debug: lba %10d , size %10d , quality '%s'\n",
134
start_lba, blocks, Spotlist__quality_name(quality, quality_name,
135
Xorriso_read_quality_invaliD, 0) + 2);
142
int Spotlist_count(struct SpotlisT *o, int flag)
144
return o->list_count;
148
int Spotlist_block_count(struct SpotlisT *o, int flag)
151
struct SpotlistiteM *li;
153
for(li= o->list_start; li != NULL; li= li->next) {
154
if(li->start_lba + li->blocks > list_blocks)
155
list_blocks= li->start_lba + li->blocks;
161
int Spotlist_sector_size(struct SpotlisT *o, int read_chunk, int flag)
164
struct SpotlistiteM *li;
166
sector_size= read_chunk * 2048;
167
for(li= o->list_start; li != NULL; li= li->next) {
168
if((li->start_lba % read_chunk) || (li->blocks % read_chunk)) {
177
int Spotlist_get_item(struct SpotlisT *o, int idx,
178
int *start_lba, int *blocks, int *quality, int flag)
181
struct SpotlistiteM *li;
183
if(idx < 0 || idx > o->list_count)
185
if(idx == o->current_idx && o->current_item != NULL)
187
else if(idx == o->current_idx + 1 && o->current_item != NULL) {
188
li= o->current_item->next;
191
for(i= 0; i < idx; i++)
196
*start_lba= li->start_lba;
198
*quality= li->quality;
203
char *Spotlist__quality_name(int quality, char name[80], int bad_limit,
206
if(quality == Xorriso_read_quality_untesteD ||
207
quality == Xorriso_read_quality_tao_enD ||
208
quality == Xorriso_read_quality_off_tracK)
210
else if(quality <= bad_limit)
214
if(quality == Xorriso_read_quality_gooD)
215
strcat(name, "good");
216
else if(quality == Xorriso_read_quality_md5_matcH)
217
strcat(name, "md5_match");
218
else if(quality == Xorriso_read_quality_sloW)
219
strcat(name, "slow");
220
else if(quality == Xorriso_read_quality_partiaL)
221
strcat(name, "partial");
222
else if(quality == Xorriso_read_quality_valiD)
223
strcat(name, "valid");
224
else if(quality == Xorriso_read_quality_untesteD)
225
strcat(name, "untested");
226
else if(quality == Xorriso_read_quality_invaliD)
227
strcat(name, "invalid");
228
else if(quality == Xorriso_read_quality_tao_enD)
229
strcat(name, "tao_end");
230
else if(quality == Xorriso_read_quality_off_tracK)
231
strcat(name, "off_track");
232
else if(quality == Xorriso_read_quality_md5_mismatcH)
233
strcat(name, "md5_mismatch");
234
else if(quality == Xorriso_read_quality_unreadablE)
235
strcat(name, "unreadable");
237
sprintf(name, "0 0x%8.8X", (unsigned int) quality);
242
/* ---------------------------- End SpotlisT ------------------------------ */
244
/* ---------------------------- SectorbitmaP ------------------------------ */
246
int Sectorbitmap_new(struct SectorbitmaP **o, int sectors, int sector_size,
249
struct SectorbitmaP *m;
251
m= TSOB_FELD(struct SectorbitmaP,1);
256
m->sector_size= sector_size;
258
m->map_size= sectors / 8 + 1;
260
m->map= calloc(m->map_size, 1);
265
Sectorbitmap_destroy(o, 0);
270
int Sectorbitmap_destroy(struct SectorbitmaP **o, int flag)
274
if((*o)->map != NULL)
275
free((char *) (*o)->map);
282
int Sectorbitmap_from_file(struct SectorbitmaP **o, char *path, char *msg,
283
int *os_errno, int flag)
285
int ret, fd= -1, sectors, sector_size, i, todo, map_size, skip;
287
unsigned char buf[1024];
292
fd= open(path, O_RDONLY);
296
strcpy(msg, "Cannot open path ");
297
Text_shellsafe(path, msg+strlen(msg), 0);
301
ret= read(fd, buf, 32);
307
strcpy(msg, "Not a sector bitmap file: ");
308
Text_shellsafe(path, msg+strlen(msg), 0);
312
if(strncmp((char *) buf, "xorriso sector bitmap v1 ", 32) == 0)
314
else if(strncmp((char *) buf, "xorriso sector bitmap v2 ", 25) == 0) {
316
sscanf(((char *) buf) + 25, "%d", &skip);
318
{ret= 0; goto wrong_filetype;}
319
for(i= 0; i < skip; i+= sizeof(buf)) {
323
ret= read(fd, buf, todo);
328
{ret= 0; goto wrong_filetype;}
329
ret= read(fd, buf, 8);
332
sectors= (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
333
sector_size= (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
334
if(sectors <= 0 || sector_size <= 0)
336
ret= Sectorbitmap_new(o, sectors, sector_size, 0);
339
sprintf(msg, "Cannot allocate bitmap memory for %d sectors", sectors);
343
map_size= (*o)->map_size;
344
for(i= 0; i < map_size; i+= sizeof(buf)) {
346
if(i + todo > map_size)
348
ret= read(fd, buf, todo);
351
memcpy(map + i, buf, todo);
358
Sectorbitmap_destroy(o, 0);
363
int Sectorbitmap_to_file(struct SectorbitmaP *o, char *path, char *info,
364
char *msg, int *os_errno, int flag)
366
int ret, fd= -1, j, l;
367
unsigned char buf[40];
370
fd= open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
374
strcpy(msg, "Cannot open path ");
375
Text_shellsafe(path, msg+strlen(msg), 0);
384
strcpy(msg, "Info string is longer than 999999 bytes");
387
sprintf((char *) buf, "xorriso sector bitmap v2 %-6d\n", l);
389
ret= write(fd, buf, 32);
394
strcpy(msg, "Cannot write to ");
395
Text_shellsafe(path, msg+strlen(msg), 0);
400
ret= write(fd, info, l);
405
for(j= 0; j < 4; j++) {
406
buf[j]= o->sectors >> (24 - j * 8);
407
buf[j+4]= o->sector_size >> (24 - j * 8);
409
ret= write(fd, buf, 8);
412
ret= write(fd, o->map, o->map_size);
413
if(ret != o->map_size)
424
/* @param flag bit0= sector bit value
426
int Sectorbitmap_set(struct SectorbitmaP *o, int sector, int flag)
428
if(sector < 0 || sector >= o->sectors)
431
o->map[sector / 8]|= 1 << (sector % 8);
433
o->map[sector / 8]&= ~(1 << (sector % 8));
438
/* @param flag bit0= sector bit value
440
int Sectorbitmap_set_range(struct SectorbitmaP *o,
441
int start_sector, int sectors, int flag)
443
int start_i, end_i, i;
446
if(start_sector < 0 || start_sector + sectors > o->sectors || sectors < 1)
452
start_i= start_sector / 8;
453
end_i= (start_sector + sectors - 1) / 8;
454
for(i= start_sector; i / 8 == start_i && i < start_sector + sectors; i++)
455
Sectorbitmap_set(o, i, flag & 1);
456
for(i= start_i + 1; i < end_i; i++)
459
for(i= end_i * 8; i < start_sector + sectors; i++)
460
Sectorbitmap_set(o, i, flag & 1);
465
int Sectorbitmap_is_set(struct SectorbitmaP *o, int sector, int flag)
467
if(sector < 0 || sector >= o->sectors)
469
return(!! (o->map[sector / 8] & (1 << (sector % 8))));
473
int Sectorbitmap_bytes_are_set(struct SectorbitmaP *o,
474
off_t start_byte, off_t end_byte, int flag)
478
end_sector= end_byte / o->sector_size;
479
for(i= start_byte / o->sector_size; i <= end_sector; i++)
480
if(!Sectorbitmap_is_set(o, i, 0))
486
int Sectorbitmap_get_layout(struct SectorbitmaP *o,
487
int *sectors, int *sector_size, int flag)
489
*sectors= o->sectors;
490
*sector_size= o->sector_size;
495
int Sectorbitmap_copy(struct SectorbitmaP *from, struct SectorbitmaP *to,
498
int i, run_start, run_value, start_sec, limit_sec, start_aligned;
501
if(((off_t) from->sectors) * ((off_t) from->sector_size) >
502
((off_t) to->sectors) * ((off_t) to->sector_size))
504
if(from->sector_size == to->sector_size) {
505
for(i= 0; i < from->map_size; i++)
506
to->map[i]= from->map[i];
510
run_value= Sectorbitmap_is_set(from, 0, 0);
511
for(i= 1; i <= from->sectors; i++) {
512
if(i < from->sectors)
513
if(Sectorbitmap_is_set(from, i, 0) == run_value)
515
start_sec= run_start * from->sector_size / to->sector_size;
517
(start_sec * to->sector_size == run_start * from->sector_size);
518
limit_sec= i * from->sector_size / to->sector_size;
519
end_complete= (limit_sec * to->sector_size == i * from->sector_size);
527
if(start_sec < limit_sec)
528
Sectorbitmap_set_range(to, start_sec, limit_sec - 1 - start_sec,
530
run_value= !run_value;
537
int Sectorbitmap_clone(struct SectorbitmaP *from, struct SectorbitmaP **clone,
542
ret= Sectorbitmap_new(clone, from->sectors, from->sector_size, 0);
545
ret= Sectorbitmap_copy(from, *clone, 0);
547
Sectorbitmap_destroy(clone, 0);
552
/* -------------------------- End SectorbitmaP ---------------------------- */
554
/* ---------------------------- CheckmediajoB ----------------------------- */
556
int Checkmediajob_new(struct CheckmediajoB **o, int flag)
558
struct CheckmediajoB *m;
560
m= TSOB_FELD(struct CheckmediajoB,1);
567
m->min_block_size= 0;
569
m->start_time= time(NULL);
570
m->time_limit= 28800;
571
m->item_limit= 100000;
572
strcpy(m->abort_file_path, "/var/opt/xorriso/do_abort_check_media");
573
m->data_to_path[0]= 0;
575
m->data_to_offset= 0;
576
m->data_to_limit= -1;
578
m->patch_lba0_msc1= -1;
579
m->sector_map_path[0]= 0;
581
m->map_with_volid= 0;
584
strcpy(m->event_severity, "ALL");
585
m->slow_threshold_seq= 1.0;
586
m->untested_valid= 0;
591
int Checkmediajob_destroy(struct CheckmediajoB **o, int flag)
595
if((*o)->data_to_fd != -1)
596
close((*o)->data_to_fd);
597
Sectorbitmap_destroy(&((*o)->sector_map), 0);
604
int Checkmediajob_copy(struct CheckmediajoB *from, struct CheckmediajoB *to,
607
to->use_dev= from->use_dev;
608
to->min_lba= from->min_lba;
609
to->max_lba= from->max_lba;
610
to->min_block_size= from->min_block_size;
611
to->mode= from->mode;
612
to->time_limit= from->time_limit;
613
to->item_limit= from->item_limit;
614
strcpy(to->abort_file_path, from->abort_file_path);
615
strcpy(to->data_to_path, from->data_to_path);
616
/* not copied: data_to_fd */
617
to->data_to_offset= from->data_to_offset;
618
to->data_to_limit= from->data_to_limit;
619
to->patch_lba0= from->patch_lba0;
620
to->patch_lba0_msc1= from->patch_lba0_msc1;
621
strcpy(to->sector_map_path, from->sector_map_path);
622
/* not copied: sector_map */
623
to->map_with_volid= from->map_with_volid;
624
to->retry= from->retry;
625
to->report_mode= from->report_mode;
626
strcpy(to->event_severity, from->event_severity);
627
to->slow_threshold_seq= from->slow_threshold_seq;
628
to->untested_valid= from->untested_valid;
633
/* -------------------------- End CheckmediajoB --------------------------- */
636
int Xorriso_check_media_setup_job(struct XorrisO *xorriso,
637
struct CheckmediajoB *job,
638
char **argv, int old_idx, int end_idx, int flag)
642
struct CheckmediajoB *default_job;
645
if(xorriso->check_media_default != NULL)
646
Checkmediajob_copy(xorriso->check_media_default, job, 0);
647
for(i= old_idx; i < end_idx; i++) {
648
if(strncmp(argv[i], "abort_file=", 11) == 0) {
649
ret= Sfile_str(job->abort_file_path, argv[i] + 11, 0);
652
} else if(strncmp(argv[i], "bad_limit=", 10) == 0) {
653
if(strcmp(argv[i] + 10, "good") == 0)
654
xorriso->check_media_bad_limit= Xorriso_read_quality_gooD;
655
else if(strcmp(argv[i] + 10, "md5_match") == 0)
656
xorriso->check_media_bad_limit= Xorriso_read_quality_md5_matcH;
657
else if(strcmp(argv[i] + 10, "slow") == 0)
658
xorriso->check_media_bad_limit= Xorriso_read_quality_sloW;
659
else if(strcmp(argv[i] + 10, "partial") == 0)
660
xorriso->check_media_bad_limit= Xorriso_read_quality_partiaL;
661
else if(strcmp(argv[i] + 10, "valid") == 0)
662
xorriso->check_media_bad_limit= Xorriso_read_quality_valiD;
663
else if(strcmp(argv[i] + 10, "untested") == 0)
664
xorriso->check_media_bad_limit= Xorriso_read_quality_untesteD;
665
else if(strcmp(argv[i] + 10, "invalid") == 0)
666
xorriso->check_media_bad_limit= Xorriso_read_quality_invaliD;
667
else if(strcmp(argv[i] + 10, "tao_end") == 0)
668
xorriso->check_media_bad_limit= Xorriso_read_quality_tao_enD;
669
else if(strcmp(argv[i] + 10, "off_track") == 0)
670
xorriso->check_media_bad_limit= Xorriso_read_quality_off_tracK;
671
else if(strcmp(argv[i] + 10, "md5_mismatch") == 0)
672
xorriso->check_media_bad_limit= Xorriso_read_quality_md5_mismatcH;
673
else if(strcmp(argv[i] + 10, "unreadable") == 0)
674
xorriso->check_media_bad_limit= Xorriso_read_quality_unreadablE;
677
} else if(strncmp(argv[i], "data_to=", 8) == 0) {
678
ret= Sfile_str(job->data_to_path, argv[i] + 8, 0);
681
} else if(strncmp(argv[i], "chunk_size=", 11) == 0) {
682
num= Scanf_io_size(argv[i] + 11, 1);
683
if(num >= 2048 || num == 0)
684
job->min_block_size= num / 2048;
687
} else if(strncmp(argv[i], "event=", 6) == 0) {
688
strncpy(sev_text, argv[i] + 6, 19);
690
ret= Xorriso__text_to_sev(sev_text, &sev, 0);
692
strcpy(xorriso->info_text, "-check_media event=");
693
Text_shellsafe(sev_text, xorriso->info_text, 1);
694
strcat(xorriso->info_text, " : Not a known severity name");
695
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
698
strcpy(job->event_severity, sev_text);
699
} else if(strncmp(argv[i], "map_with_volid=", 15) == 0) {
700
if(strcmp(argv[i] + 15, "on") == 0)
701
job->map_with_volid= 1;
702
else if(strcmp(argv[i] + 15, "off") == 0)
703
job->map_with_volid= 0;
706
} else if(strncmp(argv[i], "max_lba=", 8) == 0 ||
707
strncmp(argv[i], "min_lba=", 8) == 0) {
709
sscanf(argv[i] + 8, "%lf", &num);
710
if(num > 0x7fffffff || num < 0)
712
if(strncmp(argv[i], "max_lba=", 8) == 0)
716
} else if(strncmp(argv[i], "patch_lba0=", 11) == 0) {
717
job->patch_lba0_msc1= -1;
718
if(strcmp(argv[i] + 11, "on") == 0)
720
else if(strcmp(argv[i] + 11, "off") == 0)
722
else if(strcmp(argv[i] + 11, "force") == 0)
724
else if(argv[i][11] >= '1' && argv[i][11] <= '9') {
726
sscanf(argv[i] + 11, "%lf", &num);
727
if(num > 0x7fffffff || num < 0)
729
job->patch_lba0_msc1= num;
730
job->patch_lba0= (num >= 32) + (strstr(argv[i] + 11, ":force") != NULL);
733
} else if(strncmp(argv[i], "report=", 7) == 0) {
734
if(strcmp(argv[i] + 7, "blocks") == 0)
736
else if(strcmp(argv[i] + 7, "files") == 0)
738
else if(strcmp(argv[i] + 7, "blocks_files") == 0)
742
} else if(strcmp(argv[i], "reset=now") == 0) {
743
ret= Checkmediajob_new(&default_job, 0);
745
sprintf(xorriso->info_text,
746
"-check_media: Cannot reset options due to lack of resources");
747
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
750
Checkmediajob_copy(default_job, job, 0);
751
Checkmediajob_destroy(&default_job, 0);
752
xorriso->check_media_bad_limit= Xorriso_read_quality_invaliD;
753
} else if(strncmp(argv[i], "retry=", 6) == 0) {
754
if(strcmp(argv[i] + 6, "on") == 0)
756
else if(strcmp(argv[i] + 6, "off") == 0)
758
else if(strcmp(argv[i] + 6, "default") == 0)
762
} else if(strncmp(argv[i], "sector_map=", 11) == 0) {
763
ret= Sfile_str(job->sector_map_path, argv[i] + 11, 0);
766
} else if(strncmp(argv[i], "slow_limit=", 11) == 0) {
767
sscanf(argv[i] + 11, "%lf", &(job->slow_threshold_seq));
768
} else if(strncmp(argv[i], "time_limit=", 11) == 0 ||
769
strncmp(argv[i], "item_limit=", 11) == 0 ) {
771
sscanf(argv[i] + 11, "%lf", &num);
772
if(num > 0x7fffffff || num < 0)
774
if(strncmp(argv[i], "time_limit=", 11) == 0)
775
job->time_limit= num;
777
job->item_limit= num;
780
} else if(strncmp(argv[i], "untested=", 9) == 0) {
781
if(strcmp(argv[i] + 9, "damaged") == 0)
782
job->untested_valid= 0;
783
if(strcmp(argv[i] + 9, "undamaged") == 0 ||
784
strcmp(argv[i] + 9, "ok") == 0)
785
job->untested_valid= 1;
790
} else if(strncmp(argv[i], "use=", 4) == 0) {
791
if(strcmp(argv[i] + 4, "outdev") == 0)
793
else if(strcmp(argv[i] + 4, "indev") == 0)
795
else if(strcmp(argv[i] + 4, "sector_map") == 0)
799
} else if(strncmp(argv[i], "what=", 5) == 0) {
800
if(strcmp(argv[i]+5, "tracks") == 0)
802
else if(strcmp(argv[i]+5, "disc")== 0)
806
sprintf(xorriso->info_text,
807
"-check_media: Unknown value with option %s", argv[i]);
808
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
812
sprintf(xorriso->info_text, "-check_media: Unknown option '%s'", argv[i]);
813
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
823
/* @param report Buffer of at least 10*SfileadrL
824
@param flag bit0= only report non-default settings
825
@return <=0 error , 1 ok , 2 with bit0: every option is on default setting
827
int Xorriso_check_media_list_job(struct XorrisO *xorriso,
828
struct CheckmediajoB *job,
829
char *report, int flag)
832
char default_report[161], quality_name[80];
833
struct CheckmediajoB *dflt= NULL;
837
ret= Checkmediajob_new(&dflt, 0);
840
sprintf(report, "-check_media_defaults");
842
strcat(report, " reset=now");
843
if(all || job->use_dev != dflt->use_dev)
844
sprintf(report + strlen(report), " use=%s",
845
job->use_dev == 1 ? "outdev" :
846
job->use_dev == 2 ? "sector_map" : "indev");
847
if(all || job->mode != dflt->mode)
848
sprintf(report + strlen(report), " what=%s",
849
job->mode == 1 ? "disc" : "tracks");
850
if(all || job->min_lba != dflt->min_lba)
851
sprintf(report + strlen(report), " min_lba=%d", job->min_lba);
852
if(all || job->max_lba != dflt->max_lba)
853
sprintf(report + strlen(report), " max_lba=%d", job->max_lba);
854
if(all || job->retry != dflt->retry)
855
sprintf(report + strlen(report), " retry=%s",
856
job->retry == 1 ? "on" : job->retry == -1 ? "off" : "default");
857
if(all || job->time_limit != dflt->time_limit)
858
sprintf(report + strlen(report), " time_limit=%d", job->time_limit);
859
if(all || job->item_limit != dflt->item_limit)
860
sprintf(report + strlen(report), " item_limit=%d", job->item_limit);
861
if(all || strcmp(job->abort_file_path, dflt->abort_file_path)) {
862
strcat(report, " abort_file=");
863
Text_shellsafe(job->abort_file_path, report + strlen(report), 0);
865
if(strlen(report) > 4 * SfileadrL)
867
if(all || strcmp(job->data_to_path, dflt->data_to_path)) {
868
strcat(report, " data_to=");
869
Text_shellsafe(job->data_to_path, report + strlen(report), 0);
871
if(strlen(report) > 4 * SfileadrL)
873
if(all || strcmp(job->sector_map_path, dflt->sector_map_path)) {
874
strcat(report, " sector_map=");
875
Text_shellsafe(job->sector_map_path, report + strlen(report), 0);
877
if(all || job->map_with_volid != dflt->map_with_volid)
878
sprintf(report + strlen(report), " map_with_volid=%s",
879
job->map_with_volid == 1 ? "on" : "off");
880
if(all || job->patch_lba0 != dflt->patch_lba0) {
881
sprintf(report + strlen(report), " patch_lba0=");
882
if(job->patch_lba0 == 0)
883
sprintf(report + strlen(report), "off");
884
else if(job->patch_lba0_msc1 >= 0)
885
sprintf(report + strlen(report), "%d%s",
886
job->patch_lba0_msc1, job->patch_lba0 == 2 ? ":force" : "");
888
sprintf(report + strlen(report), "%s",
889
job->patch_lba0 == 2 ? "force" : "on");
891
if(all || job->report_mode != dflt->report_mode)
892
sprintf(report + strlen(report), " report=%s",
893
job->report_mode == 0 ? "blocks" :
894
job->report_mode == 1 ? "files" : "blocks_files");
895
if(all || job->slow_threshold_seq != dflt->slow_threshold_seq)
896
sprintf(report + strlen(report), " slow_limit=%f", job->slow_threshold_seq);
897
if(all || xorriso->check_media_bad_limit != Xorriso_read_quality_invaliD)
898
sprintf(report + strlen(report), " bad_limit=%s",
899
Spotlist__quality_name(xorriso->check_media_bad_limit, quality_name,
900
Xorriso_read_quality_invaliD, 0) + 2);
901
if(all || job->min_block_size != dflt->min_block_size)
902
sprintf(report + strlen(report), " chunk_size=%ds", job->min_block_size);
903
if(all || strcmp(job->event_severity, "ALL") != 0)
904
sprintf(report + strlen(report), " event=%s", job->event_severity);
905
if(strlen(report) > 4 * SfileadrL)
910
strcat(report, xorriso->list_delimiter);
911
Checkmediajob_destroy(&dflt, 0);
912
sprintf(default_report, "-check_media_defaults reset=now %s",
913
xorriso->list_delimiter);
914
if(ret > 0 && strcmp(report, default_report) == 0)
920
int Xorriso_sectormap_to_spotlist(struct XorrisO *xorriso,
921
struct CheckmediajoB *job,
922
struct SpotlisT **spotlist,
925
struct SectorbitmaP *map;
926
int ret, i, sectors, sector_size, value, old_value= -1, old_start= -1;
928
map= job->sector_map;
931
ret= Spotlist_new(spotlist, 0);
934
Sectorbitmap_get_layout(map, §ors, §or_size, 0);
936
if(job->max_lba >= 0)
937
sectors= (job->max_lba + 1) / sector_size;
939
if(job->min_lba >= 0)
940
i= job->min_lba / sector_size;
941
for(; i < sectors; i++) {
942
value= Sectorbitmap_is_set(map, i, 0);
943
if(value == old_value)
946
ret= Spotlist_add_item(*spotlist, old_start, i * sector_size - old_start,
947
(old_value ? Xorriso_read_quality_valiD :
948
Xorriso_read_quality_invaliD), 0);
951
if(job->item_limit > 0 &&
952
Spotlist_count(*spotlist, 0) + 1 >= job->item_limit) {
953
sprintf(xorriso->info_text, "-check_media: Reached item_limit=%d",
955
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
956
if(sectors - i > 1) {
957
ret= Spotlist_add_item(*spotlist, i * sector_size,
958
(sectors - i - 1) * sector_size,
959
Xorriso_read_quality_untesteD, 0);
967
old_start= i * sector_size;
970
ret= Spotlist_add_item(*spotlist, old_start, i * sector_size - old_start,
971
(old_value ? Xorriso_read_quality_valiD :
972
Xorriso_read_quality_invaliD), 0);
979
Spotlist_destroy(spotlist, 0);
984
/* @param flag bit0= mark untested areas as valid
986
int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso,
987
struct SpotlisT *spotlist,
989
struct SectorbitmaP **map,
992
struct SectorbitmaP *m;
993
int map_sectors= -1, map_sector_size= -1, valid;
994
int list_sectors, list_blocks, sector_size, sector_blocks;
995
int replace_map= 0, count, i, lba, blocks, quality, ret, pass;
997
sector_size= Spotlist_sector_size(spotlist, read_chunk, 0);
998
sector_blocks= sector_size / 2048;
1000
Sectorbitmap_get_layout(*map, &map_sectors, &map_sector_size, 0);
1002
count= Spotlist_count(spotlist, 0);
1003
list_blocks= Spotlist_block_count(spotlist, 0);
1005
/* >>> ??? insist in list_blocks % sector_blocks == 0 */
1007
list_sectors= list_blocks / sector_blocks;
1008
if(list_sectors * sector_blocks < list_blocks)
1010
if(*map != NULL && map_sectors * (map_sector_size / 2048) >= list_blocks &&
1011
map_sector_size == sector_size)
1015
if(((off_t) (*map)->sectors) * ((off_t) (*map)->sector_size) >
1016
((off_t) list_sectors) * ((off_t) sector_size))
1017
list_sectors= (((off_t) (*map)->sectors) *
1018
((off_t) (*map)->sector_size)) / ((off_t) sector_size)
1021
ret= Sectorbitmap_new(&m, list_sectors, sector_size, 0);
1026
ret= Sectorbitmap_copy(*map, m, 0);
1028
Sectorbitmap_destroy(&m, 0);
1034
count= Spotlist_count(spotlist, 0);
1035
/* first set good bits, then eventually override by bad bits */
1036
for(pass= 0; pass < 2; pass++) {
1037
for(i= 0; i < count; i++) {
1038
ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0);
1041
valid= quality > xorriso->check_media_bad_limit;
1042
if(quality == Xorriso_read_quality_untesteD && (flag & 1))
1044
else if(pass == 0 && !valid)
1046
else if(pass == 1 && valid)
1048
Sectorbitmap_set_range(m, lba / sector_blocks, blocks / sector_blocks,
1053
Sectorbitmap_destroy(map, 0);
1060
int Xorriso_open_job_data_to(struct XorrisO *xorriso,
1061
struct CheckmediajoB *job, int flag)
1063
char sfe[5*SfileadrL];
1065
if(job->data_to_path[0] == 0)
1067
job->data_to_fd= open(job->data_to_path, O_RDWR | O_CREAT,
1069
if(job->data_to_fd == -1) {
1070
sprintf(xorriso->info_text, "Cannot open path %s",
1071
Text_shellsafe(job->data_to_path, sfe, 0));
1072
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
1079
int Xorriso_update_in_sector_map(struct XorrisO *xorriso,
1080
struct SpotlisT *spotlist, int read_chunk,
1081
struct CheckmediajoB *job, int flag)
1083
int sectors, sector_size, sector_blocks, ret;
1084
struct SectorbitmaP *map;
1086
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
1087
if(job->use_dev == 1)
1089
map= job->sector_map;
1090
sectors= Spotlist_block_count(spotlist, 0);
1093
sector_size= Spotlist_sector_size(spotlist, read_chunk, 0);
1094
sector_blocks= sector_size / 2048;
1095
if(sector_blocks > 1)
1096
sectors= sectors / sector_blocks + !!(sectors % sector_blocks);
1097
ret= Sectorbitmap_new(&(xorriso->in_sector_map), sectors, sector_size, 0);
1101
Sectorbitmap_copy(map, xorriso->in_sector_map, 0);
1102
ret= Xorriso_spotlist_to_sectormap(xorriso, spotlist, read_chunk,
1103
&(xorriso->in_sector_map), 1);