static int Open(DC_ProcedureCtx *ctx) { int r; int open_flags; ReadPriv *priv = ctx->priv; // Setting context if (!strcmp(priv->api_str, "ata")) priv->api = Api_eAta; else if (!strcmp(priv->api_str, "posix")) priv->api = Api_ePosix; else return 1; if (priv->api == Api_eAta && !ctx->dev->ata_capable) return 1; ctx->blk_size = BLK_SIZE; priv->current_lba = priv->start_lba; priv->end_lba = ctx->dev->capacity / 512; priv->lba_to_process = priv->end_lba - priv->start_lba; if (priv->lba_to_process <= 0) return 1; ctx->progress.den = priv->lba_to_process / SECTORS_AT_ONCE; if (priv->lba_to_process % SECTORS_AT_ONCE) ctx->progress.den++; if (priv->api == Api_eAta) { open_flags = O_RDWR; } else { r = posix_memalign(&priv->buf, sysconf(_SC_PAGESIZE), ctx->blk_size); if (r) return 1; open_flags = O_RDONLY | O_DIRECT | O_LARGEFILE | O_NOATIME; } priv->fd = open(ctx->dev->dev_path, open_flags); if (priv->fd == -1) { dc_log(DC_LOG_FATAL, "open %s fail\n", ctx->dev->dev_path); return 1; } lseek(priv->fd, 512 * priv->start_lba, SEEK_SET); r = ioctl(priv->fd, BLKFLSBUF, NULL); if (r == -1) dc_log(DC_LOG_WARNING, "Flushing block device buffers failed\n"); r = ioctl(priv->fd, BLKRAGET, &priv->old_readahead); if (r == -1) dc_log(DC_LOG_WARNING, "Getting block device readahead setting failed\n"); r = ioctl(priv->fd, BLKRASET, 0); if (r == -1) dc_log(DC_LOG_WARNING, "Disabling block device readahead setting failed\n"); return 0; }
void debug_console::init() { initscr(); start_color(); keypad(stdscr, TRUE); intrflush(stdscr, FALSE); noecho(); nonl(); refresh(); nodelay(stdscr, FALSE); meta(stdscr, TRUE); /* enable 8-bit input */ idlok(stdscr, TRUE); /* may give a little clunky screenredraw */ idcok(stdscr, TRUE); /* may give a little clunky screenredraw */ leaveok(stdscr, FALSE); init_pair(C_WHITE, COLOR_WHITE, COLOR_BLACK); init_pair(C_CYAN, COLOR_CYAN, COLOR_BLACK); init_pair(C_MAGENTA, COLOR_MAGENTA, COLOR_BLACK); init_pair(C_BLUE, COLOR_BLUE, COLOR_BLACK); init_pair(C_YELLOW, COLOR_YELLOW, COLOR_BLACK); init_pair(C_GREEN, COLOR_GREEN, COLOR_BLACK); init_pair(C_RED, COLOR_RED, COLOR_BLACK); recreate_terminal(); dc_log("Calibrating..."); wnoutrefresh(win_logs); doupdate(); nc = true; }
static void Close(DC_ProcedureCtx *ctx) { ReadPriv *priv = ctx->priv; int r = ioctl(priv->fd, BLKRASET, priv->old_readahead); if (r == -1) dc_log(DC_LOG_WARNING, "Restoring block device readahead setting failed\n"); free(priv->buf); close(priv->fd); }
static int Open(DC_ProcedureCtx *ctx) { HpaSetPriv *priv = ctx->priv; dc_dev_set_max_lba(ctx->dev->dev_path, ctx->dev->native_capacity / 512 - 1); int ret = dc_dev_set_max_lba(ctx->dev->dev_path, priv->max_lba); if (ret) dc_log(DC_LOG_ERROR, "Command SET MAX ADDRESS EXT failed"); return 0; }
int dc_init(void) { int r; DC_Ctx *ctx = calloc(1, sizeof(*ctx)); if (!ctx) return 1; dc_ctx_global = ctx; dc_log_set_callback(dc_log_default_func, NULL); dc_log_set_level(DC_LOG_INFO); struct timespec dummy; #ifdef CLOCK_MONOTONIC_RAW /* determine best available clock */ DC_BEST_CLOCK = CLOCK_MONOTONIC_RAW; r = clock_gettime(DC_BEST_CLOCK, &dummy); if (r) { dc_log(DC_LOG_WARNING, "CLOCK_MONOTONIC_RAW unavailable, using CLOCK_MONOTONIC\n"); DC_BEST_CLOCK = CLOCK_MONOTONIC; } #else DC_BEST_CLOCK = CLOCK_MONOTONIC; #endif r = clock_gettime(DC_BEST_CLOCK, &dummy); if (r) { dc_log(DC_LOG_ERROR, "Monotonic POSIX clock unavailable\n"); return 1; } dc_realtime_scheduling_enable_with_prio(0); #define PROCEDURE_REGISTER(x) { \ extern DC_Procedure x; \ dc_procedure_register(&x); } PROCEDURE_REGISTER(hpa_set); PROCEDURE_REGISTER(posix_write_zeros); PROCEDURE_REGISTER(copy); PROCEDURE_REGISTER(read_test); PROCEDURE_REGISTER(smart_show); #undef PROCEDURE_REGISTER return 0; }
void Splitter::load (const SettingFile& file) { Droplet::load(file); // 部品となる Droplet の情報を読み込む std::list<std::string> name_list = file.get_string_list(get_name(), "Parts"); std::list<std::string>::iterator it; for( it = name_list.begin(); it != name_list.end(); ++it ) { dc_log("物体 '%s'('Droplet') を 'Splitter' の部品として構築します", it->c_str()); Droplet *dp = new Droplet (get_manager()); dp->set_name(*it); // オブジェクト名を設定する dp->load(file); // データを読み込む add(dp); } }
static void dev_modelname_fill(DC_Dev *dev) { // fill model name, if exists char *model_file_name; int ret; ret = asprintf(&model_file_name, "/sys/block/%s/device/model", dev->dev_fs_name); assert(ret != -1 && model_file_name); FILE *model_file = fopen(model_file_name, "r"); free(model_file_name); if (!model_file) return; char model[256]; int r; r = fscanf(model_file, "%256[^\n]", model); if (r != 1) { dc_log(DC_LOG_ERROR, "Outrageous error at scanning model name\n"); return; } dev->model_str = strdup(model); assert(dev->model_str); }
/* * try all things in /proc/partitions that look like a full disk * Taken from util-linux-2.19.1/fdisk/fdisk.c tryprocpt() */ static void dev_list_build(DC_DevList *dc_devlist) { int is_whole_disk(const char *name) { // taken from util-linux-2.19.1/lib/wholedisk.c while (*name) name++; return !isdigit(name[-1]); } FILE *procpt; char line[128], ptname[128]; int ma, mi; unsigned long long sz; int ret; procpt = fopen("/proc/partitions", "r"); if (procpt == NULL) { dc_log(DC_LOG_FATAL, "cannot open /proc/partitions\n"); return; } while (fgets(line, sizeof(line), procpt)) { if (sscanf (line, " %d %d %llu %128[^\n ]", &ma, &mi, &sz, ptname) != 4) continue; if (is_whole_disk(ptname)) { DC_Dev *dc_dev = calloc(1, sizeof(*dc_dev)); assert(dc_dev); dc_dev->dev_fs_name = strdup(ptname); assert(dc_dev->dev_fs_name); ret = asprintf(&dc_dev->dev_path, "/dev/%s", ptname); assert(ret != -1 && dc_dev->dev_path); dc_dev->capacity = sz * 1024; dc_dev->next = dc_devlist->arr; dc_devlist->arr = dc_dev; dc_devlist->arr_size++; } } fclose(procpt); }
int datacore_prio (const char *dev, int sg_fd, char * args) { int k; char vendor[8]; char product[32]; char luname[32]; char wwpn[32]; char sdsname[32]; unsigned char inqCmdBlk[INQ_CMD_LEN] = { INQ_CMD_CODE, 0, 0, 0, INQ_REPLY_LEN, 0 }; unsigned char inqBuff[INQ_REPLY_LEN]; unsigned char *inqBuffp = inqBuff; unsigned char sense_buffer[32]; sg_io_hdr_t io_hdr; int timeout = 2000; char preferredsds_buff[255] = ""; char * preferredsds = &preferredsds_buff[0]; if (!args) { dc_log(0, "need prio_args with preferredsds set"); return 0; } if (sscanf(args, "timeout=%i preferredsds=%s", &timeout, preferredsds) == 2) {} else if (sscanf(args, "preferredsds=%s timeout=%i", preferredsds, &timeout) == 2) {} else if (sscanf(args, "preferredsds=%s", preferredsds) == 1) {} else { dc_log(0, "unexpected prio_args format"); return 0; } // on error just return prio 0 if (strlen(preferredsds) <= 1) { dc_log(0, "prio args: preferredsds too short (1 character min)"); return 0; } if ((timeout < 500) || (timeout > 20000)) { dc_log(0, "prio args: timeout out of bounds [500:20000]"); return 0; } if ((ioctl(sg_fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) return 0; memset (&io_hdr, 0, sizeof (sg_io_hdr_t)); io_hdr.interface_id = 'S'; io_hdr.cmd_len = sizeof (inqCmdBlk); io_hdr.mx_sb_len = sizeof (sense_buffer); io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; io_hdr.dxfer_len = INQ_REPLY_LEN; io_hdr.dxferp = inqBuff; io_hdr.cmdp = inqCmdBlk; io_hdr.sbp = sense_buffer; io_hdr.timeout = timeout; // on error just return prio 0 if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) return 0; if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) return 0; snprintf(vendor, 8, "%.8s\n", inqBuffp + 8); snprintf(product, 17, "%.16s", inqBuffp + 16); snprintf(luname, 21, "%.19s", inqBuffp + 36); snprintf(wwpn, 17, "%.16s", inqBuffp + 96); snprintf(sdsname, 17, "%.16s", inqBuffp + 112); if (strstr(sdsname , preferredsds)) return 1; return 0; }
int main() { int r; r = global_init(); if (r) { fprintf(stderr, "init fail\n"); return r; } // get list of devices DC_DevList *devlist = dc_dev_list(); assert(devlist); while (1) { // draw menu of device choice DC_Dev *chosen_dev = menu_choose_device(devlist); if (!chosen_dev) { break; } // draw procedures menu DC_Procedure *act = menu_choose_procedure(chosen_dev); if (!act) continue; if (act->flags & DC_PROC_FLAG_INVASIVE) { char *ask; r = asprintf(&ask, "This operation is invasive, i.e. it may make your data unreachable or even destroy it completely. Are you sure you want to proceed it on %s (%s)?", chosen_dev->dev_fs_name, chosen_dev->model_str); assert(r != -1); dialog_vars.default_button = 1; // Focus on "No" r = dialog_yesno("Confirmation", ask, 0, 0); // Yes = 0 (FALSE), No = 1, Escape = -1 free(ask); if (/* No */ r) continue; if (chosen_dev->mounted) { dialog_vars.default_button = 1; // Focus on "No" r = dialog_yesno("Confirmation", "This disk is mounted. Are you really sure you want to proceed?", 0, 0); if (r) continue; } } DC_OptionSetting *option_set = calloc(act->options_num + 1, sizeof(DC_OptionSetting)); int i; r = 0; for (i = 0; i < act->options_num; i++) { option_set[i].name = act->options[i].name; r = act->suggest_default_value(chosen_dev, &option_set[i]); if (r) { dc_log(DC_LOG_ERROR, "Failed to get default value suggestion on '%s'", option_set[i].name); break; } r = ask_option_value(act, &option_set[i], &act->options[i]); if (r) break; } if (r) continue; // Show relaxing banner when copying with journal. Copy journal processing takes some time. if (!strcmp(act->name, "copy")) { int uses_journal = 0; for (i = 0; i < act->options_num; i++) { if (!strcmp(option_set[i].name, "use_journal")) { uses_journal = 1; break; } } if (uses_journal) dialog_msgbox("Info", "Please wait while operation journal is processed", 0, 0, 0 /* non-pausing */); } DC_ProcedureCtx *actctx; r = dc_procedure_open(act, chosen_dev, &actctx, option_set); if (r) { dialog_msgbox("Error", "Procedure init fail", 0, 0, 1); continue; } if (!act->perform) continue; DC_Renderer *renderer; if (!strcmp(act->name, "copy")) renderer = dc_find_renderer("whole_space"); else renderer = dc_find_renderer("sliding_window"); render_procedure(actctx, renderer); } // while(1) return 0; }
// // name: inet_prio // @param // @return prio int iet_prio(const char *dev, char * args) { char preferredip_buff[255] = ""; char *preferredip = &preferredip_buff[0]; // Phase 1 : checks. If anyone fails, return prio 0. // check if args exists if (!args) { dc_log(0, "need prio_args with preferredip set"); return 0; } // check if args format is OK if (sscanf(args, "preferredip=%s", preferredip) ==1) {} else { dc_log(0, "unexpected prio_args format"); return 0; } // check if ip is not too short if (strlen(preferredip) <= 7) { dc_log(0, "prio args: preferredip too short"); return 0; } // Phase 2 : find device in /dev/disk/by-path to match device/ip DIR *dir_p; struct dirent *dir_entry_p; enum { BUFFERSIZE = 1024 }; char buffer[BUFFERSIZE]; char fullpath[BUFFERSIZE] = "/dev/disk/by-path/"; dir_p = opendir(fullpath); // loop to find device in /dev/disk/by-path while( NULL != (dir_entry_p = readdir(dir_p))) { if (dir_entry_p->d_name[0] != '.') { char path[BUFFERSIZE] = "/dev/disk/by-path/"; strcat(path,dir_entry_p->d_name); ssize_t nchars = readlink(path, buffer, sizeof(buffer)-1); if (nchars != -1) { char *device; buffer[nchars] = '\0'; device = find_regex(buffer,"(sd[a-z]+)"); // if device parsed is the right one if (device!=NULL && strncmp(device, dev, strlen(device)) == 0) { char *ip; ip = find_regex(dir_entry_p->d_name,"([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})"); // if prefferedip and ip fetched matches if (ip!=NULL && strncmp(ip, preferredip, strlen(ip)) == 0) { // high prio free(ip); free(device); closedir(dir_p); return 20; } free(ip); } free(device); } else { printf("error\n"); } } } // nothing found, low prio closedir(dir_p); return 10; }
int main() { printf(WHDD_ABOUT); printf("\nATTENTION! whdd-cli utility is purposed for development debugging, and as a fallback if whdd utility somehow fails to work. In other cases, consider using whdd utility, which should provide better usage experience.\n"); int r; char *char_ret; // init libdevcheck r = dc_init(); assert(!r); // get list of devices DC_DevList *devlist = dc_dev_list(); assert(devlist); // show list of devices if (dc_dev_list_size(devlist) == 0) { printf("No devices found, go buy some :)\n"); return 0; } while (1) { DC_Dev *chosen_dev = request_and_get_device(); if (!chosen_dev) { printf("Invalid choice\n"); break; } DC_Procedure *act = request_and_get_cli_action(); if (!act) break; printf("Going to perform test %s (%s)\n", act->name, act->display_name); if (act->flags & DC_PROC_FLAG_INVASIVE) { printf("This operation is invasive, i.e. it may make your data unreachable or even destroy it completely. Are you sure you want to proceed it on %s (%s)? (y/n)\n", chosen_dev->dev_fs_name, chosen_dev->model_str); char ans[10] = "n"; char_ret = fgets(ans, sizeof(ans), stdin); if (!char_ret || ans[0] != 'y') continue; if (chosen_dev->mounted) { printf("This disk is mounted. Are you really sure you want to proceed? (y/n)"); char_ret = fgets(ans, sizeof(ans), stdin); if (!char_ret || ans[0] != 'y') continue; } } DC_OptionSetting *option_set = calloc(act->options_num + 1, sizeof(DC_OptionSetting)); int i; r = 0; for (i = 0; i < act->options_num; i++) { option_set[i].name = act->options[i].name; r = act->suggest_default_value(chosen_dev, &option_set[i]); if (r) { dc_log(DC_LOG_ERROR, "Failed to get default value suggestion on '%s'", option_set[i].name); break; } r = ask_option_value(&option_set[i], &act->options[i]); if (r) break; } if (r) continue; DC_ProcedureCtx *actctx; r = dc_procedure_open(act, chosen_dev, &actctx, option_set); if (r) { printf("Procedure init fail\n"); continue; } if (!act->perform) continue; printf("Performing on device %s with block size %"PRId64"\n", chosen_dev->dev_path, actctx->blk_size); procedure_perform_until_interrupt(actctx, proc_render_cb, NULL); } // while(1) return 0; }
void debug_console::tick(processor *p) { n_ticks++; if (!refresh_limit_valid) { double now_ts = get_ts(); double t_diff = now_ts - start_ts; // first second: ignore as the cpu might need to come out of // reduced clock frequency (linux: "ondemand" scaling governor) if (t_diff >= 1.0) refresh_limit++; if (t_diff >= 1.0 + 1.0 / double(SCREEN_REFRESHES_PER_SECOND)) { dc_log("Refresh screen every %d instructions", refresh_limit); refresh_limit_valid = true; } } uint64_t PC = p -> is_delay_slot() ? p -> get_delay_slot_PC() : p -> get_PC(); uint32_t instruction = -1; bool r_ok = true; try { p -> get_mem_32b(PC, &instruction); } catch(processor_exception & pe) { dc_log("EXCEPTION %d at/for %016llx, PC: %016llx (3), sr: %08x", pe.get_cause(), pe.get_BadVAddr(), pe.get_EPC(), pe.get_status()); r_ok = false; } std::string logline = p -> da_logline(instruction); dolog(logline.c_str()); std::string decoded = p -> decode_to_text(instruction); #ifdef _DEBUG unsigned int space = decoded.find(' '); if (space == std::string::npos) space = decoded.length(); std::string instruction_name = decoded.substr(0, space); std::map<std::string, long int>::iterator found = instruction_counts.find(instruction_name); if (found != instruction_counts.end()) found -> second++; else instruction_counts.insert(std::pair<std::string, long int>(instruction_name, 1)); #endif if ((++refresh_counter >= refresh_limit && refresh_limit_valid == true) || single_step) { double now_ts = get_ts(); if (term_change) recreate_terminal(); int x = -1, y = -1; for(int registers=0; registers<32; registers++) { if (registers < 16) { x = 0; y = registers; } else { x = 22; y = registers - 16; } mvwprintw(win_regs, y, x, "%s %016llx", registers == 0 ? "0 " : processor::reg_to_name(registers), p -> get_register_64b_unsigned(registers)); } mvwprintw(win_regs, 0, 44, "PC: %016llx %c", PC, p -> is_delay_slot() ? 'D' : '.'); mvwprintw(win_regs, 1, 44, "LO: %016llx", p -> get_LO()); mvwprintw(win_regs, 2, 44, "HI: %016llx", p -> get_HI()); mvwprintw(win_regs, 3, 44, "SR: %016llx", p -> get_SR()); mvwprintw(win_regs, 4, 44, "mem: %d/%08x", r_ok, instruction); int opcode = (instruction >> 26) & MASK_6B; int function = instruction & MASK_6B; int sa = processor::get_SA(instruction); int rd = processor::get_RD(instruction); int rt = processor::get_RT(instruction); int rs = processor::get_RS(instruction); int immediate = processor::get_immediate(instruction); int b18_signed_offset = processor::get_SB18(instruction); mvwprintw(win_regs, 5, 44, "op: %02x rs: %02x", opcode, rs); mvwprintw(win_regs, 6, 44, "rt: %02x rd: %02x", rt, rd); mvwprintw(win_regs, 7, 44, "sa: %02x fu: %02d", sa, function); mvwprintw(win_regs, 8, 44, "im: %04x of: %d", immediate, b18_signed_offset); mvwprintw(win_regs, 9, 44, "> "); mvwprintw(win_regs, 9, 44, "> %s", decoded.c_str()); double t_diff = now_ts - start_ts; if (t_diff) { double i_per_s = double(n_ticks) / t_diff; if (i_per_s >= 1000000000.0) mvwprintw(win_regs, 10, 44, "I/S: %6.2fG", i_per_s / 1000000000.0); else if (i_per_s >= 1000000.0) mvwprintw(win_regs, 10, 44, "I/S: %6.2fM", i_per_s / 1000000.0); else if (i_per_s >= 1000.0) mvwprintw(win_regs, 10, 44, "I/S: %6.2fk", i_per_s / 1000.0); else mvwprintw(win_regs, 10, 44, "I/S: %6.2f", i_per_s); } if (n_ticks >= 1000000000) mvwprintw(win_regs, 11, 44, "cnt: %7.2fG", double(n_ticks) / 1000000000.0); else if (n_ticks >= 1000000) mvwprintw(win_regs, 11, 44, "cnt: %7.2fM", double(n_ticks) / 1000000.0); else if (n_ticks >= 1000) mvwprintw(win_regs, 11, 44, "cnt: %7.2fk", double(n_ticks) / 1000.0); else mvwprintw(win_regs, 11, 44, "cnt: %lld", n_ticks); mvwprintw(win_regs, 11, 44, "cnt: %lld", n_ticks); const memory_bus *pmb = p -> get_memory_bus(); mvwprintw(win_regs, 12, 44, "I_S: %016x", pmb -> get_cur_segment_i()); mvwprintw(win_regs, 13, 44, "D_S: %016x", pmb -> get_cur_segment()); if (had_logging) { wnoutrefresh(win_logs); had_logging = false; } wnoutrefresh(win_regs); doupdate(); if (refresh_limit_valid) refresh_counter = 0; }