diff --git a/lsscsi.c b/lsscsi.c index f00e144..4ae382f 100644 --- a/lsscsi.c +++ b/lsscsi.c @@ -215,8 +215,8 @@ int string_get_size(u64 size, const enum string_size_units units, } } - snprintf(buf, len, "%lld%s", (unsigned long long)size, - units_str[units][i]); + snprintf(buf, len, "%lld%s%s", (unsigned long long)size, + tmp, units_str[units][i]); return 0; } @@ -248,8 +248,6 @@ struct item_t { static struct item_t non_sg; static struct item_t aa_sg; static struct item_t aa_first; -static struct item_t aa_sd; -static struct item_t aa_block; static struct item_t enclosure_device; static char sas_low_phy[NAME_LEN_MAX]; @@ -337,48 +335,104 @@ first_scandir_select(const struct dirent * s) return 1; } +static int +sub_scandir_select(const struct dirent * s) +{ + if (s->d_type == DT_LNK) + return 1; + + if (s->d_type == DT_DIR && s->d_name[0] != '.') + return 1; + + return 0; +} + +static int +sd_scandir_select(const struct dirent * s) +{ + if (s->d_type != DT_LNK && s->d_type != DT_DIR) + return 0; + + if (s->d_name[0] == '.') + return 0; + + if (strstr(s->d_name, "scsi_disk")) + return 1; + + return 0; +} + /* Return 1 for directory entry that is link or directory (other than a * directory name starting with dot) that contains "block". Else return 0. */ static int block_scandir_select(const struct dirent * s) { - if ((DT_LNK != s->d_type) && - ((DT_DIR != s->d_type) || ('.' == s->d_name[0]))) - return 0; - if (strstr(s->d_name, "block")){ - strncpy(aa_block.name, s->d_name, NAME_LEN_MAX); - aa_block.ft = FT_CHAR; /* dummy */ - aa_block.d_type = s->d_type; - } - return 1; + if (s->d_type != DT_LNK && s->d_type != DT_DIR) + return 0; + + if (s->d_name[0] == '.') + return 0; + + if (strstr(s->d_name, "block")) + return 1; + + return 0; } -/* scan for scsi_disk directory in /sys/bus/scsi/devices/ */ +typedef int (* dirent_select_fn) (const struct dirent *); + static int -block_scan(const char * dir_name, const struct lsscsi_opt_coll * opts) +sub_scan(char * dir_name, const char * sub_str, dirent_select_fn fn) { - char name[NAME_LEN_MAX]; - struct dirent ** namelist; - int num, k; + struct dirent ** namelist; + int num, i; - num = scandir(dir_name, &namelist, block_scandir_select, NULL); - if (num < 0) { - if (opts->verbose > 0) { - snprintf(name, NAME_LEN_MAX, "scandir: %s", dir_name); - perror(name); - } - return -1; - } - for (k = 0; k < num; ++k) - free(namelist[k]); - free(namelist); - /* Add bdev name if path is block/sda instead of block:sda (2.6.34+) */ - if (num && strstr(aa_block.name, ":") == 0) { - strcat(aa_block.name, "/"); - strcat(aa_block.name, aa_first.name); + num = scandir(dir_name, &namelist, fn, NULL); + if (num <= 0) + return 0; + + strcat(dir_name, "/"); + strcat(dir_name, namelist[0]->d_name); + + for (i = 0; i < num; i++) + free(namelist[i]); + free(namelist); + + if (num && strstr(dir_name, sub_str) == 0) { + + num = scandir(dir_name, &namelist, sub_scandir_select, NULL); + + if (num <= 0) + return 0; + + strcat(dir_name, "/"); + strcat(dir_name, namelist[0]->d_name); + + for (i = 0; i < num; i++) + free(namelist[i]); + free(namelist); } - return num; + + return 1; +} + +/* Scan for block:sdN or block/sdN directory in + * /sys/bus/scsi/devices/h:c:i:l + */ +static int +block_scan(char * dir_name) +{ + return sub_scan(dir_name, "block:", block_scandir_select); +} + +/* Scan for scsi_disk:h:c:i:l or scsi_disk/h:c:i:l directory in + * /sys/bus/scsi/devices/h:c:i:l + */ +static int +sd_scan(char * dir_name) +{ + return sub_scan(dir_name, "scsi_disk:", sd_scandir_select); } static int @@ -421,42 +475,6 @@ enclosure_device_scan(const char * dir_name, const struct lsscsi_opt_coll * opts return num; } - -static int -sd_scandir_select(const struct dirent * s) -{ - if ((DT_LNK != s->d_type) && - ((DT_DIR != s->d_type) || ('.' == s->d_name[0]))) - return 0; - if (strstr(s->d_name, "scsi_disk")){ - strncpy(aa_sd.name, s->d_name, NAME_LEN_MAX); - aa_sd.ft = FT_CHAR; /* dummy */ - aa_sd.d_type = s->d_type; - } - return 1; -} - -static int -sd_scan(const char * dir_name, const struct lsscsi_opt_coll * opts) -{ - char name[NAME_LEN_MAX]; - struct dirent ** namelist; - int num, k; - - num = scandir(dir_name, &namelist, sd_scandir_select, NULL); - if (num < 0) { - if (opts->verbose > 0) { - snprintf(name, NAME_LEN_MAX, "scandir: %s", dir_name); - perror(name); - } - return -1; - } - for (k = 0; k < num; ++k) - free(namelist[k]); - free(namelist); - return num; -} - /* scan for directory entry that is either a symlink or a directory */ static int scan_for_first(const char * dir_name, const struct lsscsi_opt_coll * opts) @@ -2151,7 +2169,7 @@ one_sdev_entry(const char * dir_name, const char * devname, } } } else - printf("- "); + printf("%-9s", "-"); if (opts->generic) { if (if_directory_ch2generic(buff)) { @@ -2168,7 +2186,7 @@ one_sdev_entry(const char * dir_name, const char * devname, else if (!get_dev_node(wd, dev_node, CHR_DEV)) snprintf(dev_node, NAME_MAX, "-"); - printf(" %s", dev_node); + printf(" %-9s", dev_node); if (opts->dev_maj_min) { if (get_value(wd, "dev", value, NAME_LEN_MAX)) @@ -2179,99 +2197,72 @@ one_sdev_entry(const char * dir_name, const char * devname, } } else - printf(" -"); - } - - if (opts->protection) { - int kernel_dif_support = 0; - if (sd_scan(buff,opts)) { - if (if_directory_chdir(buff,aa_sd.name)) { - char value[NAME_LEN_MAX]; - char sddir[NAME_LEN_MAX]; - strncpy(sddir, buff, NAME_LEN_MAX); - strcat(sddir,"/"); - strcat(sddir, aa_sd.name); - if (!get_value(sddir, "protection_type", value, - NAME_LEN_MAX)) { - /* kernel < 2.6.27 */ - if (opts->verbose) - printf("No Data Integrity " - "Support\n"); - } else { - kernel_dif_support = 1; - if (strncmp(value, "0", 1)) - printf(" DIF/Type%1s ", value); - else - printf(" - "); - } - } else { - printf(" - "); - } - } - - if (kernel_dif_support && block_scan(buff,opts)) { - if (if_directory_chdir(buff,aa_block.name)) { - char value[NAME_LEN_MAX]; - char blkdir[NAME_LEN_MAX]; - strncpy(blkdir,buff,NAME_LEN_MAX); - strcat(blkdir,"/"); - strcat(blkdir,aa_block.name); - if (if_directory_chdir(blkdir,"integrity")) { - if (!get_value(".", "format", value, - NAME_LEN_MAX)) { - if (opts->verbose) - printf(" No Data " - "Integrity " - "Support\n"); - } else { - printf(" %-17s",value); - } - } else { - printf(" %-17s","- "); - } - } - } + printf(" %-9s", "-"); } - if (opts->protmode) { - if (sd_scan(buff,opts)) { - if (if_directory_chdir(buff,aa_sd.name)) { - char value[NAME_LEN_MAX]; - char sddir[NAME_LEN_MAX]; - strncpy(sddir, buff, NAME_LEN_MAX); - strcat(sddir, "/"); - strcat(sddir, aa_sd.name); - if (!get_value(sddir, "protection_mode", value, - NAME_LEN_MAX)) { - /* kernel < 2.6.37 */ - if (opts->verbose) - printf("Kernel too old\n"); - } else { - if (!strcmp(value, "none")) - printf(" %-4s ", "-"); - else - printf(" %-4s ", value); - } - } else { - printf(" - "); - } - } + if (opts->protection) { + char sddir[NAME_LEN_MAX]; + char blkdir[NAME_LEN_MAX]; + + strncpy(sddir, buff, NAME_LEN_MAX); + strncpy(blkdir, buff, NAME_LEN_MAX); + + if (sd_scan(sddir) && + if_directory_chdir(sddir, ".") && + get_value(".", "protection_type", value, NAME_LEN_MAX)) { + + if (!strncmp(value, "0", 1)) + printf(" %-9s", "-"); + else + printf(" DIF/Type%1s", value); + + } else + printf(" %-9s", "-"); + + if (block_scan(blkdir) && + if_directory_chdir(blkdir, "integrity") && + get_value(".", "format", value, NAME_LEN_MAX)) + printf(" %-16s", value); + else + printf(" %-16s", "-"); } - if (opts->size && block_scan(buff, opts) && - if_directory_chdir(buff, aa_block.name)) { - char value[NAME_LEN_MAX]; + if (opts->protmode) { + char sddir[NAME_LEN_MAX]; - if (get_value(".", "size", value, NAME_LEN_MAX)) { - u64 blocks = atol(value); + strncpy(sddir, buff, NAME_LEN_MAX); - if (!string_get_size(blocks << 9, STRING_UNITS_2, - value, NAME_LEN_MAX)) { - value[strlen(value)-2] = '\0'; - printf(" %8s", value); - } else - printf(" %8s", "-"); - } + if (sd_scan(sddir) && + if_directory_chdir(sddir, ".") && + get_value(sddir, "protection_mode", value, NAME_LEN_MAX)) { + + if (!strcmp(value, "none")) + printf(" %-4s", "-"); + else + printf(" %-4s", value); + } else + printf(" %-4s", "-"); + } + + if (opts->size) { + char blkdir[NAME_LEN_MAX]; + + strncpy(blkdir, buff, NAME_LEN_MAX); + + if (type == 0 && + block_scan(blkdir) && + if_directory_chdir(blkdir, ".") && + get_value(".", "size", value, NAME_LEN_MAX)) { + u64 blocks = atol(value) << 9; + + if (blocks > 0 && + !string_get_size(blocks, STRING_UNITS_10, value, + NAME_LEN_MAX)) { + printf(" %6s", value); + } else + printf(" %6s", "-"); + } else + printf(" %6s", "-"); } printf("\n");