对udisk操作

本文最后更新于:2022年4月18日 下午

前言

这几天为了完成导师的任务在封校的苦闷日子中找一点乐趣,想着怎么对自己的u盘进行一些操作,让我能够读取固定位置的数据。

然后我就苦逼得找了两天。

其实早就找到了 这一杀器,问题是我不知道怎么执行scsi命令。

下面介绍一下最强大的u盘工具:

sg3_utils

所谓 ,实际上是封装好的c函数库,安装好后可以直接在系统内调用相关函数来执行u disk相关操作。完善支持macos,linux,windows

安装

安装有大坑,至少我在linux上是这样。

先介绍我的 环境

1
Ubuntu: 21.20

安装有两种方式,一:

1
sudo apt-get install  sg3-utils

我未尝试该方法,该方法可能会出现一些问题。

另一种是在官网通过源码编译安装,我下载的是1.47.tar.xz

之后的安装方式是这样的:

1
2
3
4
sudo ./configure --prefix=/usr --disable-static && make

#之后:
sudo make install

这里解释一下,--disable-static 会阻止安装时采用依赖库的静态版本(参考博文),如果不这样做,可能会在执行命令时产生和我一样的错误:

1
error while loading shared libraries: libsgutils2.so.1.47: cannot open shared object file: No such file or directory

即便采用软链接的方式把libsgutils2.so.2链接到libgutils2.so.147也不行。

我在这里耽误了好久,最终找到上文中的博文才知道是安装是出了问题。 😂

使用

在我的 环境中,要读取u disk指定位置的内容,首先查看u盘名称:

1
2
3
4
5
6
7
8
9
> df -h
文件系统 容量 已用 可用 已用% 挂载点
tmpfs 1.4G 3.7M 1.4G 1% /run
/dev/nvme0n1p8 428G 207G 200G 51% /
tmpfs 6.8G 163M 6.7G 3% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
/dev/nvme0n1p1 256M 34M 223M 14% /boot/efi
tmpfs 1.4G 188K 1.4G 1% /run/user/1000
/dev/sda1 30G 112K 30G 1% /media/heeler/UBUNTU 21_0

我对linux的了解并不深,其中 /dev/sda1 与根目录下的 /dev/sg0 应为同一个设备,应该是linux对u盘不同功能的区分,实际上还是同一个设备。

之后我们可以对u disk进行读取操作了:

1
2
3
4
5
❯ sudo sg_read if=/dev/sg0 bs=512 count=2kB mmap=1 time=1
[sudo] heeler 的密码:
Time for all SCSI READ commands was 0.016853 secs, 60.76 MB/sec
Average number of SCSI READ commands per second was 949.39
2000+0 records in, SCSI READ commands issued: 16

sg_read 属于 sg3_utils 的一个函数,其官方介绍在网址if 参数指定挂载的文件系统, bs 是要读取的每一个块(block,我不知道怎么翻译)的大小,这里是对每一个块读取512字节, count 相当于读取的数据量,这里是读取2kb大小的块, time 相当于开启一个计时选项,当然sg_read还有很多参数可选,具体参数请参考官方文档。

当然,我们不能只是一行行的敲shell命令,那么怎么把命令写在脚本里面呢?

我首先尝试了写一个1.sh脚本:

1
sg_read if=/dev/sg0 bs=512 count=2kB mmap=1 time=1

然后sudo ./1.sh,会显示commod not found;或者在su -root下sudo ./1.sh显示权限不够,原因在于1.sh要求读取系统层面的文件,而sg_read并没有添加到系统配置里面,所以显示command not found或者权限不够,具体原因我还不是很了解。 🥺

那么我们怎么办呢?

我写了一个脚本1.py,在 sudo python3 1.py 就可以了。下面是py脚本:

1
2
3
4
5
import os
process=os.popen("sg_read if=/dev/sg0 bs=512 count=2kB mmap=1 time=1")
output=process.read()
process.close()
print(output)

用上python之后,就可以加一些奇技淫巧了。比如添加随机数据,随机读取数据以测量u disk的性能。

写在最后

不得不说,从 开始真的痛苦, 某人没人指导,没人给方向,前半部分时间我一直在研究一个脚本,他通过直接调用内核参数来实现对u disk的操作。我还大致浏览了一些scsi的书籍,比如来自mit的scsi,结果屁用没有成功提高了我对scsi的理解。这也是我写出这篇博客的动力,帮助人们认识到 这个强大的工具。 也有一个go写的框架,但现在还没有一个较完善的功能。总之,对u disk进行操作的话,我还是建议使用sg3_utils这个完善、强大的工具。

参考链接

sg3_utils

安装博文

sg_read网址

sg3_utils汇总工具网址

使用c调用内核参数的linux下脚本

go写的scsi框架,目前尚不完善


本文作者: Heeler-Deer
本文链接: https://heeler-deer.github.io/2022/04/06/%E5%AF%B9udisk%E6%93%8D%E4%BD%9C/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!