标题: 程序员的片段(4)--在x64/Solaris上挂载NTFS分区 创建: 2015-12-04 11:37 更新: 链接: https://scz.617.cn/unix/201512041137.txt 这个系列有点类似"Old News",绝大多数内容不具有现实意义,但从中可以看到一些 折腾的影子。 起因是在x64/Solaris 10上挂载NTFS分区。如果只读挂载,可以用FSWfsmisc,当然 这个包现在很难找到了,有一个地方还能下到: https://aminsblog.files.wordpress.com/2012/05/fswpart-tar-gz-remove.png (FSWpart.tar.gz) https://aminsblog.files.wordpress.com/2012/05/fswfsmisc-tar-gz-remove.png (FSWfsmisc.tar.gz) FSWfsmisc其实是对Martin Rosenau所写mount_ntfs的再封装,前者可以用标准mount 命令,后者得用专用的mount_ntfs命令。实在找不到FSWfsmisc时,就用mount_ntfs 即可。后者的技术原理如下: The idea here is to use NFSv2 Server that has the ability to read raw blocks from a block device and interpret the raw data as per the NTFS on-disk format. You can use the existing NFS Client in Solaris to mount via the loopback interface. 下载点: NTFS Mount (x86/Solaris) - Martin Rosenau [2006-08-04] http://mount-ntfs.sourceforge.net/ http://sourceforge.net/projects/mount-ntfs/ (下载mount_ntfs.0.9.1.opensol-x86-binary、mount_ntfs.0.9.1.zip) 前面的方案都是只读挂载NTFS分区,有读写挂载NTFS分区的方案,即ntfs-3g。该方 案同时需要fuse、ntfs-3g,只适用于Solaris 11及以上版本。 这里提到的fuse曾经是OpenSolaris的开源项目,不是下面这个: http://fuse.sourceforge.net/ 当然,最初是从这儿开始移植的。Oracle收购Sun之后这个项目就关闭了,于是你很 难再下到Solaris版的fuse源码。也不是绝对下不到,那是另一个话题。有人提供了 编译好的二进制: https://blogs.oracle.com/rslee/resource/pkg/SUNWfusefs.pkg https://blogs.oracle.com/rslee/resource/pkg/SUNWlibfuse.pkg 后面是本文的重点部分,再次强调当前系统是x64/Solaris 10,不是11。 # uname -a SunOS SCZSUN10 5.10 Generic_147148-26 i86pc i386 i86pc # pkgadd -d SUNWfusefs.pkg ... /usr/kernel/drv/amd64/fuse /usr/kernel/drv/fuse /usr/kernel/drv/fuse.conf ... devfsadm: driver failed to attach: fuse Warning: Driver (fuse) successfully added to system but failed to attach ... 提示fuse驱动已安装到系统中,但attach失败。有Solaris内核模块开发经验的人都 知道,"failed to attach"这个提示就是跎屎,没有提供任何有价值的参考信息。比 如当模块存在无法解析的符号时,attach也会失败,但你得不到别的提示。此时必须 用别的办法获取有价值的参考信息。调试器太重型了,有个简单办法,用getlog.c或 dmesg都能看到: genunix: [ID 233861 kern.warning] WARNING: file system 'fuse' version mismatch 从中我们可以知道fuse的模块与当前使用的genunix存在某种版本不匹配现象,让我 们去找出它的根源。 用IDA反编译/kernel/amd64/genunix,在Strings window中找到: "file system '%s' version mismatch" 查看交叉引用,定位mod_installfs(): -------------------------------------------------------------------------- /* * if ( modl->fs_vfsdef->def_version == VFSDEF_VERSION ) */ 00000000001CDA85 83 F8 03 cmp eax, 3 00000000001CDA88 0F 85 42 01 00 00 jnz loc_1CDBD0 ... 00000000001CDBDF 4C 89 EA mov rdx, r13 00000000001CDBE2 48 C7 C6 D0 A1 22 00 mov rsi, offset aFileSystemSVer ; "file system '%s' version mismatch" -------------------------------------------------------------------------- 当前版本的genunix的VFSDEF_VERSION等于3 在OpenSolaris源码中查看之: usr/src/uts/common/os/modconf.c 我这份源码中VFSDEF_VERSION等于5。那么fuse模块中的def_version等于多少? -------------------------------------------------------------------------- /* * usr/src/uts/common/sys/modctl.h * * For filesystems */ struct modlfs { struct mod_ops *fs_modops; char *fs_linkinfo; /* * version may actually vary */ struct vfsdef_v5 *fs_vfsdef; }; /* * usr/src/uts/common/sys/vfs.h * * Filesystem type definition record. All file systems must export a record * of this type through their modlfs structure. N.B., changing the version * number requires a change in sys/modctl.h. */ typedef struct vfsdef_v5 { int def_version; /* structure version, must be first */ char *name; /* filesystem type name */ int (*init) ( int, char * ); /* init routine */ int flags; /* filesystem flags */ mntopts_t *optproto; /* mount options table prototype */ } vfsdef_v5; -------------------------------------------------------------------------- # cp /usr/kernel/drv/amd64/fuse /tmp/fuse_64 # cp /usr/kernel/drv/fuse /tmp/fuse_32 # pkgrm SUNWfusefs 用IDA反编译fuse_32。 _init() mod_install() Private_modlinkage 1 fuse_dev_drv_modldrv fuse_vfs_modldrv mod_fsops "filesystem for fuse" fs_vfsdef_or_fs_vfssw 5 // def_version "fuse" fuse_init() 1 ... 本来想把fuse_32、fuse_64中的def_version由5改成3,后来放弃了,这样绝对没有 好果子吃。 顺便说一句,在x64/Solaris 10上就不要想着读写挂载NTFS了。