如何在Linux中检查USB记忆棒的物理状态?


85

如何检查U盘的健康状态?

我怎么知道USB损坏无法修复或无法修复?


12
把它扔掉。您投资的时间比购买新的时间要贵。
mailq 2012年

1
我必须同意@mailq。这些天,您可以花2.00美元购买一个不错的4 GB拇指驱动器。
iglvzx 2012年

17
@iglvzx好吧,这个问题并不能说明,它是便宜的,还是一些+ 32Gb快速加密的人……
varesa 2012年

Answers:


69

无法查询USB记忆棒以获取类似SMART的参数。我不知道有哪支记忆棒甚至可以通过公开可用的专有软件来支持。最好的办法是使用来检查是否可以成功读写整个设备 badblocks

https://zh.wikipedia.org/wiki/Badblocks

您要指定一种写测试,这将擦除存储棒上的所有数据。首先进行备份。

dmesg插入USB记忆棒后,通过查看查找设备;您会看到设备名称(很可能是sd_,即sdc,sdd等)和制造商信息。确保您使用的设备正确!

如果使用有效的文件系统格式化记忆棒,则可能必须unmount先将其格式化。

示例语法,对于枚举为/ dev / sdz的USB记忆棒,输出进度信息,并将破坏数据的写入测试和错误日志写入usbstick.log:

sudo badblocks -w -s -o usbstick.log /dev/sdz

假设它通过了,则需要重新分区并重新格式化。该测试将擦拭棍子上的所有东西。任何故障都表明设备的内存控制器发生故障,或者它用完了备用块以重新映射发生故障的块。在这种情况下,设备的任何区域都不能被信任。


21
badblocks可能是最好的选择。说“不值得”的评论完全错过了一些非常需
要这样做的

2
正如链接的Wikipedia文章中所指出的那样,还有e2fsck -c一种使用badblocks并有效地从文件系统中隐藏那些坏块,从而避免损坏的写入。但是,应该注意的是,如果磁盘上有新的坏块,则可能会损坏它,而以后可能会出现新的坏块,这意味着它的寿命正在缩短,您应该考虑更换它。
igorsantos14年

1
我建议也添加-v标志,以在终端窗口中看到错误。(如果你让它例如运行过夜的日志文件不是一个快速认为有用的东西不好。
的Tilo

@BeeDee,我们应该使用整个设备还是仅使用某些分区,还是没关系?我的意思是/ dev / sdz或/ dev / sdz1?
P先生

1
@Pisek您应该使用整个设备,因为这是设备故障,而不仅仅是分区。
Hi-Angel

21

通过[ubuntu]错误检查USB闪存盘,我最终发现了这一点,这可能会有所帮助:

我到达了Fight Flash Fraud和SOSFakeFlash博客,它们推荐了H2testw软件(请参见此处或此处)来测试闪存。我下载了H2testw,发现它有两个问题:(1)仅适用于Windows,(2)不是开源的。但是,它的作者很友好,可以包含一个说明其功能的文本文件。本页介绍了我对该算法的GPLv3实现。
我的实现简单可靠,而且我从不运行H2testw,所以我不确切知道F3与H2testw的比较。我将实现称为F3,这是Fight Flash Fraud或Fight Fake Flash的缩写。

@pbhj的附录:F3在Ubuntu仓库中。它分为两个部分,f3write将1GB文件写入设备,f3read随后尝试读取它们。通过这种方式,可以测试写入和有效读取数据的能力和能力。


4
F3相对于F3有什么优势badblocks吗?
Zaz 2014年


14

我想这取决于故障模式。它们便宜是有原因的。

作为USB设备,通过Windows中的设备管理器或Linux中dmesg的输出查看总线将告诉您该设备是否甚至被识别为已插入。如果不是,则说明板载控制器或物理连接坏了。

如果设备被识别为已插入,但没有被识别为磁盘控制器(并且我不知道该怎么发生,但是...),则控制器被射击。

如果将其识别为磁盘驱动器,但无法挂载,则可以通过fdisk对其进行修复并重写分区表,然后制作另一个文件系统。

如果您正在寻找等效的SMART,那么您将找不到它。Thumbdrive控制器很便宜。它们是商品存储,并不意味着具有现代驱动器所具有的常规故障保险和智能功能。


2

直到今天,该主题引发了一些问题。

- 这将花费多长时间(通过讨论使其过夜运行而暗示)。

我目前正在使用进行USB 3.0 128G Sandisk测试sudo badblocks -w -s -o,它已连接到较旧的Athlon 64x2中的USB 3 / USBC PCIe卡。因此,将USB3转换为PCIe上的USB3应该很快。

这是完成率33%的控制台命令行:

Testing with pattern 0xaa: 33.35% done, 49:47 elapsed. (0/0/0 errors)

再后来:

Testing with pattern 0xaa: 54.10% done, 1:17:04 elapsed. (0/0/0 errors)

接下来是该段:

Reading and comparing: 43.42% done, 2:23:44 elapsed. (0/0/0 errors)

使用oxaa重复此过程,然后是0x55、0xff,最后是0x00。

ArchLinux给出了不合格的声明:

For some devices this will take a couple of days to complete.

注意:测试大约在晚上8:30开始,第二天上午8:45之前已经完成测试,我的情况大约在12小时内完成。

- 破坏性测试不是唯一可能的方法。

维基百科提供了以下声明:

badblocks -nvs /dev/sdb This would check the drive "sdb" in non-destructive read-write mode and display progress by writing out the block numbers as they are checked.

我当前的发行手册页确认-n无损。

-n Use non-destructive read-write mode. By default only a non- destructive read-only test is done.

最后, 这是不值得的。声明。

根据闪存芯片中数十亿个存储位置的情况,总结性的说法是,故障是已经写入和擦除数万次的单元,现在正在发生故障。而且,当一项测试显示某个单元发生故障时,请记住,您添加和删除的每个文件都在运行这些周期。

这里的想法是,当1个单元发生故障时,更多的单元也将到达同一故障点。今天,一个单元发生了故障,但是您通常会使用一段时间,然后再有3个单元出现故障,然后又有24个单元出现故障,然后是183个,在不知不觉中,内存阵列到处都是坏点。在可用容量开始下降,最终迅速下降之前,只有这么多的单元会死亡。您如何知道更多的电池发生故障?因此,这里的帖子通过说出一旦单元发生故障来保护您的数据,就可信赖的存储而言,您已经完成了许多工作。您的使用情况可能还会给您几个月的时间。

是您的数据。

高温超导


1

许多故障要么是完整的,要么是允许一个位置支持多个位置。我编写了一个随机写读取程序,该程序将质数用于伪随机数生成器,同时用于模式和地址。读取在写入之后错开了足够的页面,以确保我没有在系统上测试ram缓存。它尚未参数化,仅在我的系统上使用8G ram设置为64G设备。随时批评,参数化,使其更智能。

这是一个强大的检查功能,并且比从下至上执行每个字节都要快,但是它还是一个很棒的交换生成器(将几乎所有其他内容都推出了)。我暂时将交换率设置为1,它变慢了,但对其他应用程序的容忍度更高。关于如何调整掉出的任何提示也将不胜感激:

$ sudo ksh -c'回显1> / proc / sys / vm / swappiness'

$ cat mysrc/test64g.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main( int argc, char **argv ){

        long long int mask = 0xFFFFFFFF8L ;    // 64Gb word
        long long int stag = 8413257 ;  // 8G / 1021
        long long int inc = 1021L ;     // prime < 1024

        long long int w_addr = 0L ;
        long long int r_addr = 0L ;
        long long int w_ct = 0L ;
        long long int r_ct = 0L ;
        long long int w_patt = 0xFEDCBA9876543210L ;
        long long int r_patt = 0xFEDCBA9876543210L ;
        long long int r_buf ;
        int fd, ret ;

        if ( argc < 2
          || argv[1] == NULL
          || 0 > ( fd = open( argv[1], O_RDWR ))){
                printf( "Fatal: Cannot open file $1 for RW.\n" );
                exit( 1 );
        }

        while ( 1 ){
                if ( (off_t)-1 == lseek( fd, w_addr & mask, SEEK_SET )){
                        printf( "Seek to %llX\n", w_addr & mask );
                        perror( "Fatal: Seek failed" );
                        exit( 2 );
                }

                if ( 8 != ( ret = write( fd, (void*)&w_patt, 8 ))){
                        printf( "Seek to %llX\n", w_addr & mask );
                        perror( "Fatal: Write failed" );
                        exit( 3 );
                }

                w_ct++ ;
                w_addr += inc ;
                w_patt += inc ;

                if ( ( w_ct - r_ct ) < stag ){
                        continue ;
                }

                if ( (off_t)-1 == lseek( fd, r_addr & mask, SEEK_SET )){
                        printf( "Seek to %llX\n", r_addr & mask );
                        perror( "Fatal: Seek failed" );
                        exit( 4 );
                }

                if ( 8 != ( ret = read( fd, (void*)&r_buf, 8 ))){
                        printf( "Seek to %llX\n", w_addr & mask );
                        perror( "Fatal: Read failed" );
                        exit( 5 );
                }

                if ( ( ++r_ct & 0XFFFFF ) == 0 ){
                        printf( "Completed %lld writes, %lld reads.\n", w_ct, r_ct );
                }

                if ( r_buf != r_patt ){
                        printf( "Data miscompare on read # %lld at address %llX:\nWas: %llX\nS/B: %llX\n\n", r_ct, r_addr & mask, r_buf, r_patt );
                }

                r_addr += inc ;
                r_patt += inc ;
        }
}

使用2的幂次幂(例如1024)将允许更好的检查或无效的高地址位,尽管每跳仅检查8个字节。
David Pickett

是的,这会错过高位死机的情况。在同一遍中也进行读写操作可能会错过这一点,
user313114

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.