Skip to content

Latest commit

 

History

History
154 lines (120 loc) · 5.5 KB

201512041137.txt.md

File metadata and controls

154 lines (120 loc) · 5.5 KB

标题: 程序员的片段(4)--在x64/Solaris上挂载NTFS分区

创建: 2015-12-04 11:37 更新: 链接: http://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了。