/* *************************************************************************** * Read CIFS-mount directories stats from /proc/fs/cifs/Stats. * * IN: * @curr Index in array for current sample statistics. *************************************************************************** */ void read_cifs_stat(int curr) { FILE *fp; char line[256]; char aux[32]; int start = 0; char cifs_name[MAX_NAME_LEN]; char name_tmp[MAX_NAME_LEN]; struct cifs_stats scifs; /* Every CIFS entry is potentially unregistered */ set_entries_inactive(); if ((fp = fopen(CIFSSTATS, "r")) == NULL) return; sprintf(aux, "%%*d) %%%ds", MAX_NAME_LEN < 200 ? MAX_NAME_LEN - 1 : 200); while (fgets(line, 256, fp) != NULL) { /* Read CIFS directory name */ if (isdigit((unsigned char) line[0]) && sscanf(line, aux , name_tmp) == 1) { if (start) { save_stats(cifs_name, curr, &scifs); } else { start = 1; } strcpy(cifs_name, name_tmp); } else { if (!strncmp(line, "Reads:", 6)) { sscanf(line, "Reads: %llu Bytes: %llu", &scifs.rd_ops, &scifs.rd_bytes); } if (!strncmp(line, "Writes:", 7)) { sscanf(line, "Writes: %llu Bytes: %llu", &scifs.wr_ops, &scifs.wr_bytes); } if (!strncmp(line, "Opens:", 6)) { sscanf(line, "Opens: %llu Closes:%llu Deletes: %llu", &scifs.fopens, &scifs.fcloses, &scifs.fdeletes); } } } if (start) { save_stats(cifs_name, curr, &scifs); } fclose(fp); /* Free structures corresponding to unregistered filesystems */ free_inactive_entries(); }
/* *************************************************************************** * Read sysfs stat for current block device or partition. * * IN: * @curr Index in array for current sample statistics. * @filename File name where stats will be read. * @dev_name Device or partition name. * * RETURNS: * 0 if file couldn't be opened, 1 otherwise. *************************************************************************** */ int read_sysfs_file_stat(int curr, char *filename, char *dev_name) { FILE *fp; struct io_stats sdev; int i; unsigned int ios_pgr, tot_ticks, rq_ticks, wr_ticks; unsigned long rd_ios, rd_merges_or_rd_sec, wr_ios, wr_merges; unsigned long rd_sec_or_wr_ios, wr_sec, rd_ticks_or_wr_sec; /* Try to read given stat file */ if ((fp = fopen(filename, "r")) == NULL) return 0; i = fscanf(fp, "%lu %lu %lu %lu %lu %lu %lu %u %u %u %u", &rd_ios, &rd_merges_or_rd_sec, &rd_sec_or_wr_ios, &rd_ticks_or_wr_sec, &wr_ios, &wr_merges, &wr_sec, &wr_ticks, &ios_pgr, &tot_ticks, &rq_ticks); if (i == 11) { /* Device or partition */ sdev.rd_ios = rd_ios; sdev.rd_merges = rd_merges_or_rd_sec; sdev.rd_sectors = rd_sec_or_wr_ios; sdev.rd_ticks = (unsigned int) rd_ticks_or_wr_sec; sdev.wr_ios = wr_ios; sdev.wr_merges = wr_merges; sdev.wr_sectors = wr_sec; sdev.wr_ticks = wr_ticks; sdev.ios_pgr = ios_pgr; sdev.tot_ticks = tot_ticks; sdev.rq_ticks = rq_ticks; } else if (i == 4) { /* Partition without extended statistics */ sdev.rd_ios = rd_ios; sdev.rd_sectors = rd_merges_or_rd_sec; sdev.wr_ios = rd_sec_or_wr_ios; sdev.wr_sectors = rd_ticks_or_wr_sec; } if ((i == 11) || !DISPLAY_EXTENDED(flags)) { /* * In fact, we _don't_ save stats if it's a partition without * extended stats and yet we want to display ext stats. */ save_stats(dev_name, curr, &sdev, iodev_nr, st_hdr_iodev); } fclose(fp); return 1; }
void test_algorithm() { int score, move[2]; while(NUM_MOVES_REMAINING) { score = do_move_manual(move); score = do_move_algorithm(move); printf("%d %d\n", move[0], move[1]); } printf("%d", our_area()); //print_board(); if(score <= 500000) save_stats(score); }
/* *************************************************************************** * Compute stats for device groups using stats of every device belonging * to each of these groups. * * IN: * @curr Index in array for current sample statistics. *************************************************************************** */ void compute_device_groups_stats(int curr) { struct io_stats gdev, *ioi; struct io_hdr_stats *shi = st_hdr_iodev; int i, nr_disks; memset(&gdev, 0, IO_STATS_SIZE); nr_disks = 0; for (i = 0; i < iodev_nr; i++, shi++) { if (shi->used && (shi->status == DISK_REGISTERED)) { ioi = st_iodev[curr] + i; if (!DISPLAY_UNFILTERED(flags)) { if (!ioi->rd_ios && !ioi->wr_ios) continue; } gdev.rd_ios += ioi->rd_ios; gdev.rd_merges += ioi->rd_merges; gdev.rd_sectors += ioi->rd_sectors; gdev.rd_ticks += ioi->rd_ticks; gdev.wr_ios += ioi->wr_ios; gdev.wr_merges += ioi->wr_merges; gdev.wr_sectors += ioi->wr_sectors; gdev.wr_ticks += ioi->wr_ticks; gdev.ios_pgr += ioi->ios_pgr; gdev.tot_ticks += ioi->tot_ticks; gdev.rq_ticks += ioi->rq_ticks; nr_disks++; } else if (shi->status == DISK_GROUP) { save_stats(shi->name, curr, &gdev, iodev_nr, st_hdr_iodev); shi->used = nr_disks; nr_disks = 0; memset(&gdev, 0, IO_STATS_SIZE); } } }
/* *************************************************************************** * Read stats from /proc/diskstats. * * IN: * @curr Index in array for current sample statistics. *************************************************************************** */ void read_diskstats_stat(int curr) { FILE *fp; char line[256], dev_name[MAX_NAME_LEN]; char *dm_name; struct io_stats sdev; int i; unsigned int ios_pgr, tot_ticks, rq_ticks, wr_ticks; unsigned long rd_ios, rd_merges_or_rd_sec, rd_ticks_or_wr_sec, wr_ios; unsigned long wr_merges, rd_sec_or_wr_ios, wr_sec; char *ioc_dname; unsigned int major, minor; /* Every I/O device entry is potentially unregistered */ set_entries_unregistered(iodev_nr, st_hdr_iodev); if ((fp = fopen(DISKSTATS, "r")) == NULL) return; while (fgets(line, sizeof(line), fp) != NULL) { /* major minor name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq */ i = sscanf(line, "%u %u %s %lu %lu %lu %lu %lu %lu %lu %u %u %u %u", &major, &minor, dev_name, &rd_ios, &rd_merges_or_rd_sec, &rd_sec_or_wr_ios, &rd_ticks_or_wr_sec, &wr_ios, &wr_merges, &wr_sec, &wr_ticks, &ios_pgr, &tot_ticks, &rq_ticks); if (i == 14) { /* Device or partition */ if (!dlist_idx && !DISPLAY_PARTITIONS(flags) && !is_device(dev_name, ACCEPT_VIRTUAL_DEVICES)) continue; sdev.rd_ios = rd_ios; sdev.rd_merges = rd_merges_or_rd_sec; sdev.rd_sectors = rd_sec_or_wr_ios; sdev.rd_ticks = (unsigned int) rd_ticks_or_wr_sec; sdev.wr_ios = wr_ios; sdev.wr_merges = wr_merges; sdev.wr_sectors = wr_sec; sdev.wr_ticks = wr_ticks; sdev.ios_pgr = ios_pgr; sdev.tot_ticks = tot_ticks; sdev.rq_ticks = rq_ticks; } else if (i == 7) { /* Partition without extended statistics */ if (DISPLAY_EXTENDED(flags) || (!dlist_idx && !DISPLAY_PARTITIONS(flags))) continue; sdev.rd_ios = rd_ios; sdev.rd_sectors = rd_merges_or_rd_sec; sdev.wr_ios = rd_sec_or_wr_ios; sdev.wr_sectors = rd_ticks_or_wr_sec; } else /* Unknown entry: Ignore it */ continue; if ((ioc_dname = ioc_name(major, minor)) != NULL) { if (strcmp(dev_name, ioc_dname) && strcmp(ioc_dname, K_NODEV)) { /* * No match: Use name generated from sysstat.ioconf data * (if different from "nodev") works around known issues * with EMC PowerPath. */ strncpy(dev_name, ioc_dname, MAX_NAME_LEN - 1); dev_name[MAX_NAME_LEN - 1] = '\0'; } } if ((DISPLAY_DEVMAP_NAME(flags)) && (major == dm_major)) { /* * If the device is a device mapper device, try to get its * assigned name of its logical device. */ dm_name = transform_devmapname(major, minor); if (dm_name) { strncpy(dev_name, dm_name, MAX_NAME_LEN - 1); dev_name[MAX_NAME_LEN - 1] = '\0'; } } save_stats(dev_name, curr, &sdev, iodev_nr, st_hdr_iodev); } fclose(fp); /* Free structures corresponding to unregistered devices */ free_unregistered_entries(iodev_nr, st_hdr_iodev); }
/* *************************************************************************** * Read NFS-mount directories stats from /proc/self/mountstats. * * IN: * @curr Index in array for current sample statistics. *************************************************************************** */ void read_nfs_stat(int curr) { FILE *fp; int sw = 0; char line[256]; char *xprt_line; char *mount_part; char nfs_name[MAX_NAME_LEN]; char mount[10], on[10], prefix[10], aux[32]; char operation[16]; struct io_nfs_stats snfs; long int v1; /* Every I/O NFS entry is potentially unregistered */ set_entries_inactive(); if ((fp = fopen(NFSMOUNTSTATS, "r")) == NULL) return; sprintf(aux, "%%%ds", MAX_NAME_LEN < 200 ? MAX_NAME_LEN-1 : 200); while (fgets(line, 256, fp) != NULL) { /* Read NFS directory name */ if (!strncmp(line, "device", 6)) { sw = 0; sscanf(line + 6, aux, nfs_name); mount_part = strchr(line + 7, ' '); if (mount_part != NULL) { sscanf(mount_part, "%9s %9s", mount, on); if ((!strncmp(mount, "mounted", 7)) && (!strncmp(on, "on", 2))) { sw = 1; } } } sscanf(line, "%9s", prefix); if (sw && (!strncmp(prefix, "bytes:", 6))) { /* Read the stats for the last NFS-mounted directory */ sscanf(strstr(line, "bytes:") + 6, "%llu %llu %llu %llu %llu %llu", &snfs.rd_normal_bytes, &snfs.wr_normal_bytes, &snfs.rd_direct_bytes, &snfs.wr_direct_bytes, &snfs.rd_server_bytes, &snfs.wr_server_bytes); sw = 2; } if ((sw == 2) && (!strncmp(prefix, "xprt:", 5))) { /* * Read extended statistic for the last NFS-mounted directory * - number of sent rpc requests. */ xprt_line = (strstr(line, "xprt:") + 6); /* udp, tcp or rdma data */ if (!strncmp(xprt_line, "udp", 3)) { /* port bind_count sends recvs (bad_xids req_u bklog_u) */ sscanf(strstr(xprt_line, "udp") + 4, "%*u %*u %lu", &snfs.rpc_sends); } if (!strncmp(xprt_line, "tcp", 3)) { /* * port bind_counter connect_count connect_time idle_time * sends recvs (bad_xids req_u bklog_u) */ sscanf(strstr(xprt_line, "tcp") + 4, "%*u %*u %*u %*u %*d %lu", &snfs.rpc_sends); } if (!strncmp(xprt_line,"rdma", 4)) { /* * 0(port) bind_count connect_count connect_time idle_time * sends recvs (bad_xids req_u bklog_u...) */ sscanf(strstr(xprt_line, "rdma") + 5, "%*u %*u %*u %*u %*d %lu", &snfs.rpc_sends); } sw = 3; } if ((sw == 3) && (!strncmp(prefix, "per-op", 6))) { sw = 4; while (sw == 4) { fgets(line, 256, fp); sscanf(line, "%15s %lu", operation, &v1); if (!strncmp(operation, "READ:", 5)) { snfs.nfs_rops = v1; } else if (!strncmp(operation, "WRITE:", 6)) { snfs.nfs_wops = v1; save_stats(nfs_name, curr, &snfs); sw = 0; } } } } fclose(fp); /* Free structures corresponding to unregistered filesystems */ free_inactive_entries(); }
/** *************************************************************************** * main() ;-) * */ int main(int argc, char * argv[]) { stats_main_start = get_current_time_millis(); int rv = 0; pthread_key_create(&thread_name, NULL); pthread_setspecific(thread_name, (char *)"[MAIN] "); pthread_key_create(&duplicate_path_buffer, NULL); rv = process_args(argc, argv); LOG(L_PROGRESS, "Log level: %s\n", log_level_name[log_level]); // If process_args returns non-zero it means we need to exit right away // with an exit code one less than the returned value. Need to exit via // the DONE section both to free any memory that may have been allocated // already and also to properly return (not exit) from main (see below). if (rv) { rv--; goto DONE; } // If bad --path values given, don't try to process them. Arguably one // could process the good ones (if any) but better to flag the path // error up front instead of spending time doing a partial scan. if (start_path_state == START_PATH_ERROR) { rv = 1; goto DONE; } LOG(L_INFO, "Claimed CPU cores: %d\n", cpu_cores()); max_open_files = get_file_limit() - 10; LOG(L_INFO, "Max open files: %d\n", max_open_files); signal(SIGUSR1, &handle_signal); signal(SIGUSR2, &handle_signal); switch (operation) { case COMMAND_scan: scan(); break; case COMMAND_refresh: operation_refresh(); break; case COMMAND_report: operation_report(); break; case COMMAND_uniques: operation_uniques(); break; case COMMAND_license: show_license(); break; case COMMAND_version: printf(DUPD_VERSION "\n"); break; case COMMAND_dups: operation_dups(); break; case COMMAND_file: operation_file(); break; case COMMAND_ls: operation_ls(); break; case COMMAND_rmsh: operation_shell_script(); break; case COMMAND_validate: rv = operation_validate(); break; case COMMAND_usage: show_usage(); break; case COMMAND_man: show_usage(); break; case COMMAND_help: show_help(); break; case COMMAND_testing: testing(); break; case COMMAND_hash: operation_hash_file(); break; case OPTGEN_NO_COMMAND: show_help(); rv = 1; break; default: // LCOV_EXCL_START printf("error: unknown operation [%d]\n", operation); rv = 1; } // LCOV_EXCL_STOP DONE: if (free_file_path) { free(file_path); } if (free_db_path) { free(db_path); } if (free_cache_db_path) { free(cache_db_path); } if (path_sep_string) { free(path_sep_string); } free_size_tree(); free_size_list(); free_path_block(); free_filecompare(); free_scanlist(); free_start_paths(); free_read_list(); free_dirtree(); free_path_buffer(); stats_time_total = get_current_time_millis() - stats_main_start; LOG(L_PROGRESS, "Total time: %ld ms\n", stats_time_total); if (stats_file != NULL) { save_stats(); } if (log_level >= 0) { if (operation == COMMAND_scan || operation == COMMAND_refresh || operation == COMMAND_license || operation == COMMAND_version || operation == COMMAND_validate || operation == COMMAND_usage || operation == COMMAND_man || operation == COMMAND_help) { if (!strcmp("dev", DUPD_VERSION + strlen(DUPD_VERSION) - 3)) { if (isatty(fileno(stdout))) { fprintf(stdout, "\nNote: This is a development version of dupd (" DUPD_VERSION ") (" GITHASH ")\n"); fprintf(stdout, "May contain known bugs or unstable work in progress!\n"); fprintf(stdout, "If stability is desired, use a release version of dupd.\n"); } } } } // Call return() instead of exit() just to make valgrind mark as // an error any reachable allocations. That makes them show up // when running the tests. return(rv); }