by quickmouse <quickmouse@263.net> 2008年2月19日
e2fsprogs的工具包当中携带了一个叫blkid的库,可以用来探测一个文件系统的类型。当我们使用mount device mntpoint时候,mount命令自动识别设备的文件系统类型就是通过这个库来完成的。
blkid库通过扫描指定设备上的文件系统特征值来判断是否属于对应的文件系统。在blkid库的源码文件probe.c当中,我们可见这样的结构值:
static struct blkid_magic type_array[] = {
/* type kboff sboff len magic probe */
{ "oracleasm", 0, 32, 8, "ORCLDISK", probe_oracleasm },
{ "ntfs", 0, 3, 8, "NTFS ", probe_ntfs },
{ "jbd", 1, 0x38, 2, "\123\357", probe_jbd },
{ "ext3", 1, 0x38, 2, "\123\357", probe_ext3 },
{ "ext2", 1, 0x38, 2, "\123\357", probe_ext2 },
{ "reiserfs", 8, 0x34, 8, "ReIsErFs", probe_reiserfs },
{ "reiserfs", 64, 0x34, 9, "ReIsEr2Fs", probe_reiserfs },
{ "reiserfs", 64, 0x34, 9, "ReIsEr3Fs", probe_reiserfs }
...
};
很明显,这是各个文件系统的特征值,当然仅仅有特征值还不能完全断定是这个文件系统,还需要进一步判断。正是看到了这个结构值解决了我的一个U盘长期只能用mount -t vfat ...的指定文件系统方式来挂载的问题,在此不细谈。至于进一步判断,我们大可不关心实现细节,如果要使用,只需要在查询前创建blkid的cache,然后再用blkid_get_tag_value查询即可,现在支持的tag包括"TYPE"(文件系统类型)、"UUID"(格式化后文件系统的唯一ID)和"LABEL"(卷标),最后用blkid_put_cache把cache释放即可。
使用blkid cache的好处是如果进行多个重复查询,则速度会快一些。blkid_get_cache当中的第二个参数是cache存放的文件名,若传入NULL,则使用系统缺省的/etc/blkid.tab,若不希望创建,可使用/dev/null。
当然,查询也可以不通过cache进行,这时候可以简单的使用一个blkid_get_tag_value(NULL, "TYPE", devicename)来完成,实际上在blkid_get_tag_value函数内部发现没有cache参数传入时,会自己根据/etc/blkid.tab创建cache,查询完毕后再释放,即屏蔽了blkid_get_cache和blkid_put_cache的操作。
一个小小的测试程序如下,编译的时候记得加-lblkid的库链接参数:
#include <stdio.h>
#include <blkid/blkid.h>
int main(int argc, char **argv)
{
blkid_cache cache;
const char *pfstype;
if(argc != 2)
{
printf("Usage: %s devicename\n", argv[0]);
return 0;
}
blkid_get_cache(&cache, "/dev/null");
pfstype = blkid_get_tag_value(cache, "TYPE", argv[1]);
blkid_put_cache(cache);
printf("The fstype by probing is %s\n", pfstype==NULL?"<don't know>":pfstype);
return 0;
}
【补充于2008-4-21】在nuonuo同学询问之后有如下附加意见:
值得注意的是,在调用了blkid_get_tag_value之后,需要对所指向的空间进行free操作,该库函数在返回前把数据放置在了malloc的一段内存空间当中。
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=1254127