#include <string.h>
#include "global.h"
#include "analyze.h"
#include "misc.h"
#include "menu_analyze.h"
#include "param.h"
int
a_read(void)
{
if (!(cur_flags & DISK_FORMATTED)) {
err_print("Current Disk is unformatted.\n");
return (-1);
}
if (check(
"Ready to analyze (won't harm SunOS). This takes a long time, \n"
"but is interruptible with CTRL-C. Continue"))
return (-1);
return (do_scan(SCAN_VALID, F_NORMAL));
}
int
a_refresh(void)
{
if (!(cur_flags & DISK_FORMATTED)) {
err_print("Current Disk is unformatted.\n");
return (-1);
}
if (check(
"Ready to analyze (won't harm data). This takes a long time, \n"
"but is interruptible with CTRL-C. Continue"))
return (-1);
return (do_scan(SCAN_VALID | SCAN_WRITE, F_NORMAL));
}
int
a_test(void)
{
if (!(cur_flags & DISK_FORMATTED)) {
err_print("Current Disk is unformatted.\n");
return (-1);
}
if (check(
"Ready to analyze (won't harm data). This takes a long time, \n"
"but is interruptible with CTRL-C. Continue"))
return (-1);
return (do_scan(SCAN_VALID | SCAN_PATTERN | SCAN_WRITE, F_NORMAL));
}
int
a_write(void)
{
if (!(cur_flags & DISK_FORMATTED)) {
err_print("Current Disk is unformatted.\n");
return (-1);
}
if (check(
"Ready to analyze (will corrupt data). This takes a long time, \n"
"but is interruptible with CTRL-C. Continue"))
return (-1);
return (do_scan(SCAN_PATTERN, F_NORMAL));
}
int
a_compare(void)
{
if (!(cur_flags & DISK_FORMATTED)) {
err_print("Current Disk is unformatted.\n");
return (-1);
}
if (check(
"Ready to analyze (will corrupt data). This takes a long time, \n"
"but is interruptible with CTRL-C. Continue"))
return (-1);
return (do_scan(SCAN_PATTERN | SCAN_COMPARE, F_NORMAL));
}
int
a_print(void)
{
int i, j, lines, nomore = 0;
int c, one_line = 0;
int tty_lines = get_tty_lines();
if (option_f || (!isatty(0)) || (!isatty(1)))
nomore++;
else {
enter_critical();
echo_off();
charmode_on();
exit_critical();
}
lines = 0;
for (i = 0; i < scan_size * cur_blksz / sizeof (int); i += 6) {
for (j = 0; j < 6; j++)
if (i + j < scan_size * cur_blksz / sizeof (int))
fmt_print("0x%08x ",
*((int *)((int *)cur_buf + i + j)));
fmt_print("\n");
lines++;
if (one_line ||
(!nomore && (lines % (tty_lines - 1) == 0))) {
if (lines < (tty_lines -1))
continue;
(void) printf("- hit space for more - ");
c = getchar();
(void) printf("\015");
one_line = 0;
if (c == '\012') {
one_line++;
}
if (c == 'q') {
(void) printf(
" \015");
goto PRINT_EXIT;
}
if (c == '\004')
fullabort();
}
}
PRINT_EXIT:
if (!nomore) {
enter_critical();
charmode_off();
echo_on();
exit_critical();
}
return (0);
}
int
a_setup(void)
{
int deflt;
uint64_t size;
u_ioparam_t ioparam;
deflt = !scan_entire;
ioparam.io_charlist = confirm_list;
scan_entire = !input(FIO_MSTR, "Analyze entire disk", '?',
&ioparam, &deflt, DATA_INPUT);
if (!scan_entire) {
ioparam.io_bounds.lower = 0;
if ((cur_ctype->ctype_flags & CF_SCSI) &&
(cur_disk->label_type == L_TYPE_SOLARIS)) {
ioparam.io_bounds.upper = datasects() - 1;
} else if (cur_disk->label_type == L_TYPE_SOLARIS) {
ioparam.io_bounds.upper = physsects() - 1;
} else if (cur_disk->label_type == L_TYPE_EFI) {
ioparam.io_bounds.upper = cur_parts->etoc->efi_last_lba;
}
scan_lower = (diskaddr_t)input(FIO_BN,
"Enter starting block number", ':',
&ioparam, (int *)&scan_lower, DATA_INPUT);
ioparam.io_bounds.lower = scan_lower;
if (scan_upper < scan_lower)
scan_upper = scan_lower;
scan_upper = (diskaddr_t)input(FIO_BN,
"Enter ending block number", ':',
&ioparam, (int *)&scan_upper, DATA_INPUT);
}
deflt = !scan_loop;
ioparam.io_charlist = confirm_list;
scan_loop = !input(FIO_MSTR, "Loop continuously", '?',
&ioparam, &deflt, DATA_INPUT);
if (!scan_loop) {
ioparam.io_bounds.lower = 1;
ioparam.io_bounds.upper = 100;
scan_passes = input(FIO_INT, "Enter number of passes", ':',
&ioparam, &scan_passes, DATA_INPUT);
}
deflt = !scan_correct;
ioparam.io_charlist = confirm_list;
scan_correct = !input(FIO_MSTR, "Repair defective blocks", '?',
&ioparam, &deflt, DATA_INPUT);
deflt = !scan_stop;
ioparam.io_charlist = confirm_list;
scan_stop = !input(FIO_MSTR, "Stop after first error", '?',
&ioparam, &deflt, DATA_INPUT);
deflt = !scan_random;
ioparam.io_charlist = confirm_list;
scan_random = !input(FIO_MSTR, "Use random bit patterns", '?',
&ioparam, &deflt, DATA_INPUT);
ioparam.io_bounds.lower = 1;
if ((scan_entire) && (cur_disk->label_type == L_TYPE_SOLARIS)) {
size = physsects() - 1;
} else if ((scan_entire) && (cur_disk->label_type == L_TYPE_EFI)) {
size = cur_parts->etoc->efi_last_lba;
} else {
size = scan_upper - scan_lower + 1;
}
ioparam.io_bounds.upper = min(size, BUF_SECTS);
if (scan_size > ioparam.io_bounds.upper)
scan_size = ioparam.io_bounds.upper;
scan_size = input(FIO_INT, "Enter number of blocks per transfer", ':',
&ioparam, (int *)&scan_size, DATA_INPUT);
deflt = !scan_auto;
ioparam.io_charlist = confirm_list;
scan_auto = !input(FIO_MSTR, "Verify media after formatting", '?',
&ioparam, &deflt, DATA_INPUT);
deflt = !option_msg;
ioparam.io_charlist = confirm_list;
option_msg = !input(FIO_MSTR, "Enable extended messages", '?',
&ioparam, &deflt, DATA_INPUT);
deflt = !scan_restore_defects;
ioparam.io_charlist = confirm_list;
scan_restore_defects = !input(FIO_MSTR, "Restore defect list", '?',
&ioparam, &deflt, DATA_INPUT);
deflt = !scan_restore_label;
ioparam.io_charlist = confirm_list;
scan_restore_label = !input(FIO_MSTR, "Restore disk label", '?',
&ioparam, &deflt, DATA_INPUT);
fmt_print("\n");
return (0);
}
int
a_config(void)
{
fmt_print(" Analyze entire disk? ");
fmt_print(scan_entire ? "yes\n" : "no\n");
if (!scan_entire) {
fmt_print(" Starting block number: %llu (", scan_lower);
pr_dblock(fmt_print, scan_lower);
fmt_print(")\n Ending block number: %llu (", scan_upper);
pr_dblock(fmt_print, scan_upper);
fmt_print(")\n");
}
fmt_print(" Loop continuously? ");
fmt_print(scan_loop ? "yes\n" : "no\n");
if (!scan_loop) {
fmt_print(" Number of passes: %d\n", scan_passes);
}
fmt_print(" Repair defective blocks? ");
fmt_print(scan_correct ? "yes\n" : "no\n");
fmt_print(" Stop after first error? ");
fmt_print(scan_stop ? "yes\n" : "no\n");
fmt_print(" Use random bit patterns? ");
fmt_print(scan_random ? "yes\n" : "no\n");
fmt_print(" Number of blocks per transfer: %d (", scan_size);
pr_dblock(fmt_print, (diskaddr_t)scan_size);
fmt_print(")\n");
fmt_print(" Verify media after formatting? ");
fmt_print(scan_auto ? "yes\n" : "no\n");
fmt_print(" Enable extended messages? ");
fmt_print(option_msg ? "yes\n" : "no\n");
fmt_print(" Restore defect list? ");
fmt_print(scan_restore_defects ? "yes\n" : "no\n");
fmt_print(" Restore disk label? ");
fmt_print(scan_restore_label ? "yes\n" : "no\n");
fmt_print("\n");
return (0);
}
int
a_purge(void)
{
int status = 0;
if (!(cur_flags & DISK_FORMATTED)) {
err_print("Current Disk is unformatted.\n");
return (-1);
}
if (scan_random) {
fmt_print("The purge command does not write random data\n");
scan_random = 0;
}
if (!scan_loop && (scan_passes <= NPPATTERNS)) {
if (scan_passes < NPPATTERNS) {
fmt_print("The purge command runs for a minimum of ");
fmt_print("%d passes plus a last pass if the\n",
NPPATTERNS);
fmt_print("first %d passes were successful.\n",
NPPATTERNS);
}
scan_passes = NPPATTERNS + 1;
}
if (check(
"Ready to purge (will corrupt data). This takes a long time, \n"
"but is interruptible with CTRL-C. Continue"))
return (-1);
status = do_scan(SCAN_PATTERN | SCAN_PURGE, F_NORMAL);
return (status);
}
int
a_verify(void)
{
if (!(cur_flags & DISK_FORMATTED)) {
err_print("Current Disk is unformatted.\n");
return (-1);
}
if (scan_random) {
fmt_print("The verify command does not write random data\n");
scan_random = 0;
}
if (scan_passes < 2 && !scan_loop) {
scan_passes = 2;
fmt_print("The verify command runs minimum of 2 passes, one"
" for writing and \nanother for reading and verfying."
" Resetting the number of passes to 2.\n");
}
if (check("Ready to verify (will corrupt data). This takes a long time,"
"\nbut is interruptible with CTRL-C. Continue")) {
return (-1);
}
return (do_scan(SCAN_WRITE | SCAN_VERIFY, F_NORMAL));
}