Saturday, September 26, 2009

What Should Be Compiled as a Module?

前几天了解了一点关于module被kernel使用的两种方法:
1. built-in module
2. modular module
被编译入内核其实在速度上没有占有多大的优势, 相反, 列出了一堆使用模块module的好处. 那实际解决了一个极端的想法:
* 一切都被编译入kernel. ( 90%的人应该会想到速度上升的感觉. 其实这是幻觉 )

但是, 又会出现另一极端的想法:
* 一切都是modular module
又会是基于什么幻觉呢?

1. 基于方便使用?
这是不可能的. modular module还要被担心是不是被load到kernel中. 这增加了管理的需求.
built-in module在这方面更方便! 一切都在内核中了. 连modprobe和脚本都不用理会.

2. 基于省内存?
这篇文章: http://www.linuxjournal.com/article/1279 中的一节: What Should Be Compiled as a Module? 指出了多一个module会多浪费一点内存的. 这种浪费与多一个文件多一点浪费是一样道理的.

其实, 这种浪费会给人斤斤计较的感觉. 这个kernel会有成千上万个module? .和built-in module在速度上的上升一样是斤斤计较

所以, 两个极端的想都是不行的. 应该: 常用的被编译入kernel, 这样可以省去管理. 其它的都是modular module, 可以重编译module和省内存
这就存在一个如何区分哪些module是常用与不常的问题?

呃.... 我还不会. 我也不想斤斤计较.

上面引用的文章其实很旧了. 因为kerneld这种加载module的功能早已经被写到kernel中.
kernel中加载内核的实现:

内核代码树中的kernel/kmod.c中的:
int __request_module(bool wait, const char *fmt, ...)
在include/linux/kmod.h中定义一个重命名的宏:
#define request_module(mod...) __request_module(true, mod)

__request_module其实也是大家说的system call:
jessinio@niolaptop /usr/src/linux $ cat /proc/kallsyms |grep __request_module
c02389fa T __request_module
* 说白了, 这只是一个kernel空间被定义的, 很普通的function
* 这种system call在用户空间中没有什么特别能力! 因为它是使用了modprobe命令(在/proc/sys/kernel/modprobe中指定)
* 这种system call不会是人们关注的system call的
* "__"开始的函数与python推介的使用习惯是相同意义的

关于kmod: http://pficheux.free.fr/eyrolles/linux_embarque/docs_externes/kmod.txt.html
上面的文章中, 给出了一个issue, 和一个很有意义的建议:
Note for users building a heavily modularised system. It is a good idea to
create modules.dep after installing the modules and before booting a kernel for
the first time. "depmod -ae m.n.p" where m.n.p is the new kernel version.
不过. 这篇文章也是有点老了, 1999年的. 不知道在2.6内核中是否对这个issue上有了改进

Wednesday, September 23, 2009

built-in 与 modular两种module

本人不是一专追求机器性能的人. 本人世界观觉得是没有必要这样做的.
本文主要是为了弄明白一件事: 编译入内核的module与动态加载的module是否在效率上有较大的差距.

linux kernel是单核结构, 称为monolithic kernel. 因为单核的一些缺点, linux kernel加入了modular结构.
因此linux对待module的方法有两种:
1. module被编译入内核, 成为monolithic kernel内部代码
2. module被编译成模块, 需要时才加载. 称为modular kernel.

被加载入内核的module, 其实也是执行于kernel的code space的. 这个的module与built-in module在效率上什么区别吗?

如果一定要说效率的话, 差别就在于静态链接与动态链接的差别了!

相反, modular kernel可以让kernel得到功能裁减, 效率上有提升!

modular module
优势:
1. 方便增加功能.
2. module参数传递
3. 减少memory footprint, 增加效率. 不使用时可以rmmod, 减少内存开支
缺点:
1. 在加载module上浪费时间( 这点其实是可以无视的! )
2. 容易被利用rootkit( 如果Module support = N 的话就永远不会出现 )

这里也没有提到built-in的module是否比load入的module效率高.
http://www.redhatlinuxsysadmin.com/configure-key-linux-components/module2/modular-monolithic-kernels.php

module需要被注册才可以被使用的. 所以/proc/devices中有系统中的所有驱动module
jessinio@niolaptop ~ $ cat /proc/devices
Character devices:
  1 mem
  4 /dev/vc/0
  4 tty
  4 ttyS
  5 /dev/tty
...
Block devices:
  1 ramdisk
259 blkext
  7 loop
  8 sd
  9 md
 11 sr
...

例子中, major number是1的就是内存的module

jessinio@niolaptop ~ $ cat /proc/devices |grep alsa
116 alsa
jessinio@niolaptop ~ $ lsmod |grep alsa

比较一下, 可以知道alsa是一个built-in module

rmmod命令能否拆下built-in module呢? 下面测试一下
jessinio@niolaptop ~ $ sudo rmmod alsa
ERROR: Module alsa does not exist in /proc/modules
* 因为built-in module不在此文件中记录, rmmod是需要此文件的记录, 所以出错
其实rmmod是使用
delete_module这个system call的:
jessinio@niolaptop /tmp $ sudo strace rmmod test_n
...
open("/proc/modules", O_RDONLY)
...
delete_module("test_nx", O_RDONLY|O_EXCL|O_NONBLOCK)

...
从delete_module的man手册中看到:
delete_module - delete a loadable module entry. 只是针对于loadable的module才起作用的

* 所以rmmod是不能拆下built-in module的

其它参考文档:
http://systhread.net/texts/200510kdiff.php

Tuesday, September 22, 2009

major and minor number

Devices are divided into two types: character devices and block devices. 两者的区别:
1. 块设备有缓存区(有处理缓存区数据的可能性), 字符设备没有缓存区
2. 块设备返回的数据长度是固定的(由块设备决定). 但是字符设备是没有限制的

major number: tells you which driver is used to access the hardware, Each
driver is assigned a unique major number; all device files with the same major number are controlled by the same
driver
minor number: is used by the driver to distinguish between the various hardware it controls
* 其实major number比mino number容易解理. various hardware不是很好理解.
这两种number从应用上这样的:
当用户程序使用一个device file时(如打开一个sda). kernel需要使用major number去找适当的device driver去处理当前行为, 这时kernel对minor需求; 当请求到device driver处时, device driver需要利用minor number去区别对硬件的处理
其实上, minor number就是device driver的一个参数. 参数不同, device driver的行为不同. 至于这个参数的具体行为, 不同的驱动有不同的用法.

最常用的例子就是硬盘与分区:

jessinio@niolaptop /tmp $ ls -l /dev/sda*
brw-rw---- 1 root disk 8, 0 2009-09-21 07:39 /dev/sda
brw-rw---- 1 root disk 8, 1 2009-09-21 07:39 /dev/sda1
brw-rw---- 1 root disk 8, 2 2009-09-21 07:39 /dev/sda2
brw-rw---- 1 root disk 8, 3 2009-09-21 07:39 /dev/sda3
brw-rw---- 1 root disk 8, 5 2009-09-21 07:39 /dev/sda5
brw-rw---- 1 root disk 8, 6 2009-09-21 07:39 /dev/sda6
* 同一个硬盘使用minor number去区别不同分区.
曾加一个U盘的情况:
jessinio@niolaptop /tmp $ ls -l /dev/sdb*
brw-rw---- 1 root disk 8, 16 2009-09-23 04:46 /dev/sdb
brw-rw---- 1 root disk 8, 17 2009-09-23 04:46 /dev/sdb1
* 同一种硬盘是使用相同的device driver, 但是分区就是不同的minor number.

相同major number不同minor number可以表示相同硬件也可以表示不同硬件, 我们怎么区别呢?

linux下的major号列表: /usr/src/linux/Documentation/devices.txt
这个文件其实就给出了方法, 如下为major number为8的block设备:
  8 block   SCSI disk devices (0-15)
          0 = /dev/sda      First SCSI disk whole disk
         16 = /dev/sdb      Second SCSI disk whole disk
         32 = /dev/sdc      Third SCSI disk whole disk
            ...
        240 = /dev/sdp      Sixteenth SCSI disk whole disk

        Partitions are handled in the same way as for IDE
        disks (see major number 3) except that the limit on
        partitions is 15.
* minor number从16-31都为第二块硬盘使用的
* 本驱动对同一个硬盘最多支持15个分区. 最多也只能支持15个硬盘


从网上找到的第二个例子:
% ls -l /dev/fd0 /dev/fd0u1680
brwxrwxrwx 1 root floppy 2, 0 Jul 5 2000 /dev/fd0
brw-rw---- 1 root floppy 2, 44 Jul 5 2000 /dev/fd0u1680

其实上面是同一个硬件! 因为floppy有两种功能: 除了使用1.44M盘外, 还有一种高密度盘, 这种是需要相对硬件才能交换数据的
* 具体可以查看/usr/src/linux/Documentation/devices.txt

你自己的major号呢? 请申请吧
mknod命令

module怎么与major number关联呢?
通过如下API( 准确来说是system call )
include "linux/fs.h"
int register_chrdev(unsigned int major, const char *name, struct file_operations *fops);


Linux kernel module(LKM)管理

学习linux下的module机制, 方便管理

module与文件的路径

linux module放置的路径为/lib/modules/version
* version为kernel的版本, 如# uname -r
module文件名都是以ko结尾的.
* 2.4之前为 .o 结尾

如果安装了bash-completion你就会发现
# modprobe <tab><tab>
列出的module数目与
# find /lib/modules/version -name *.ko
是一样的, 也可以使用
# modprobe -l

module的CLI管理工具

jessinio@niolaptop /etc $ equery belongs modprobe
 * Searching for modprobe ...
sys-apps/module-init-tools-3.5 (/sbin/modprobe)
* 之前的管理工具叫modutils

具体工具名单:
jessinio@niolaptop /etc $ equery files sys-apps/module-init-tools|grep bin
/bin
/bin/lsmod
/sbin
/sbin/depmod
/sbin/generate-modprobe.conf
/sbin/insmod
/sbin/insmod.static
/sbin/lsmod
/sbin/modinfo
/sbin/modprobe
/sbin/rmmod
/sbin/update-modules

module-init-tools工具配置文件

modprobe的配置文件:
1. /etc/modprobe.conf
2. /etc/modprobe.d
2.4前的modutils使用的配置文件(现在还保留):
1. /etc/modules.conf
2. /etc/modules.d

linux distro在启动时有一个加载module的脚本: /etc/init.d/modules
调用的配置文件为(man 5modules.autoload) :
1. /etc/modules.autoload
2. /etc/modules.d
* 这些文件属于sys-apps/baselayout包

kernel信息文件:
/proc/kallsyms: kernel space中的symbol, 包括变量到函数. system call就在其中!
/proc/modules: 加载的module列表.

kernel module loader

中文称之为加载器. 这部分变化几次. 有两个版本:
1. 2.2前, 使用的module loader为kerneld, 这一个daemon程序. 这方面的资料地址
2. 2.4后, 被集成kernel中, 内核配置需要CONFIG_KMOD
KMOD在2.6.28后就不需要
http://cateee.net/lkddb/web-lkddb/KMOD.html

module loader的源代码于:linux-source/kernel/kmod.c
module loader代码中默认会使用modprobe, 用户也可以动态修改: /proc/sys/kernel/modprobe
kmod.c提供了加载module的处理API, 如: request_module(bool wait, const char *name, ...)
这实现了一个module可以加载另一个module的方法

加载module

参数:
insmod ne.o io=0x300 irq=11
每个module都没有统一的参数, 需要参考module的文档
对于使用modprobe命令去加载的module, 它们的参数可以写到配置文件/etc/modprobe.conf和/etc/modprobe.d/*中

依赖关系:
平时我们都喜欢使用modprobe命令而不是使用insmod, 因为modprobe解决了module之间的依赖. 其实, modprobe需要依赖于depmod命令产生的modules.dep文件
. 此文件默认路径: /lib/modules/version/module.dep
* man module.dep

Alias

# modprobe name
其实name不一定是module的名字, 可以是alias

用处:
1. 应用层统一. 比如使用eth0去表示第一块网卡, 而不要去理会实际使用的module名的差异.
* ALSA的一个例子: http://alsa.opensrc.org/index.php/Setting_up_modprobe_and_kmod_support

常用的alias: http://svn.exactcode.de/t2/trunk/package/base/module-init-tools/modprobe.conf.data
还有这样的用法:
http://www.ducea.com/2006/06/01/disable-ipv6-module-on-default-kernels/

自己写的一篇alia方面的文章: http://blog.jessinio.info/2009/09/modulealias.html

automatic load

1. 在系统启动时自动加载module, 涉及的:
/etc/init.d/modules
/etc/modules.autoload

2. 在系统需要使用modules功能时, 会调用来自kernel/kmod.c的request_module(bool wait, const char *name, ...)函数.

module的加载过程



参考文档:
http://tldp.org/HOWTO/Module-HOWTO/
http://tldp.org/LDP/lkmpg/2.6/html/x44.html

module的alias

/etc/modprobe.conf中就定义了module的alias
从modprobe.conf的man手册中描述的是:
This  allows  you  to  give  alternate  names  for  a  module
这种机制常常会使人想的一种使用方式: 把复杂的, 长的, 不人性化的module名alia到简单的, 短的, 容易记的module名.

但是modprobe.conf中会出现相反的:
alias sound-service-0-1 snd-seq-oss
alias char-major-108    ppp_generic

alias pnp:dPNPb02f analog

其实, 上面的例子中, 我不觉得alia名比module名好记多少

但在实现应用中, 这个alias就有相当重要的作用.

/usr/src/linux/socket.c 文件中的一段代码:
#ifdef CONFIG_MODULES
    /* Attempt to load a protocol module if the find failed.
     *
     * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user
     * requested real, full-featured networking support upon configuration.
     * Otherwise module support will break!
     */
    if (net_families[family] == NULL)
        request_module("net-pf-%d", family);
#endif

"net-pf-%d"就是网络协议的alia名. 一个module判断需求的另一个module, 是根据kernel space中是否某一变量:
jessinio@niolaptop /usr/src/linux $ cat /proc/kallsyms |grep net_families
c09270e0 d net_families
* 至少这个变量是否被module的初始化函数去声明. 暂不理会.

可以从上面的使用方式去理解module的alia的作用: 为module定义一个不变的名字

怎么解理呢?
/usr/src/linux/socket.c的代码中, 使用了"net-pf-%d"字符串, 如果ipv4的module名因为需求变化了. 这就会影响到socket.c的使用! 当alia的存在可以很方便解决这种问题

其实就与NSS机制(配置文件为nsswitch.conf)是一样道理的.


Tuesday, September 15, 2009

总线及其信息查看

总线这个概念有点复杂. 总线可以被N多device共同使用, 各种device均并联在这条总线上,但是在任一时刻, 总线只有一个device在使用. 就就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都有唯一的地址.
关于总线的概念, 比较偏向于硬件设计, 所以看下面的文章也看不出什么头绪:
http://en.wikipedia.org/wiki/Bus_(computing)

1. 前端总线

CPU与北桥相连的总线称为前端总线(FSB), 它影响到CPU访问memory的速度

2. 南桥与北桥

典型PC机的CPU与其它硬件的连接图:
North bridge: 北桥,
The northbridge, also known as a memory controller hub (MCH) or an integrated memory controller (IMC)
CPU与其它硬件通信都要通过北桥. 北桥管理南桥, memory, Graphics card

South bridge: 南桥, The Southbridge, also known as an I/O Controller Hub (ICH) or a Platform Controller Hub (PCH)
南桥主要管理I/O硬件, 这类硬件的速度都较低

3. PCI总线

PCI全称为Peripheral Component Interconnect. 也为一种总线, 它的设计目的:

The purpose of the PCI local bus standard is to provide a means of
transferring data between devices in a computer.

PCI总线支持的设备的数目是有限的. 所以就有一种叫PCI-PCI bridge的设备

4. 高速I/O总线PCI-E

PCI这种并行总线设计上存在的极限速度, 这样外设(peripherals)就有速度上的限制. 对于高速的I/O设备呢?
如: Gigabit网卡, SATA, SAS

I/O的速度需求, 也给北桥与南桥之间的总线带来压力:
Link Between Northbridge and Southbridge.
Congestion on the PCI bus also affects the link between the Northbridge
and the Southbridge. SATA drives and USB devices further stress this
link. A higher-bandwidth link will be required in the future.


因些, 出现PCI-Express. 速度为 5-80 gigabits per second (Gbps), PCI-E为串行型总线

PCI-E与PCI的兼容情况
PCI Express provides a scalable, high-speed, serial
I/O bus that maintains backward compatibility with PCI applications and
drivers. The PCI Express layered architecture supports existing PCI
applications and drivers by maintaining compatibility with the existing
PCI load-store (and flat address space) model.

PCI-Express被用于高速设备之间的连接, 如下为现在的PC设计:


1. PCI-Express取代AGP总线
2. 北桥与南桥使用PCI-Express variant替代
3. Gigabit型网卡与PCI-Express相连
4.  PCI还是被保留

便携式电脑有自己的硬件结构:

从上面的文字: Devices Integrated on system board, 看出主板上的集成设备使用PCI-E总线

USB2.0设备没有被挂到PCI-E总线上! 而是直接与南桥连接

* 这里有计算机总线技术变迁, 这有意思的变化: http://www.dell.com/content/topics/global.aspx/vectors/en/2004_pciexpress?c=us&l=en

5. 其它总线

PC机还有其它总线, 这些总线都bridge转换后连接到PCI总线上. 如: ISA-PCI bridge

6. 硬件探测

我的机器都有哪些硬件? 硬件的探测工具:
 * http://www.gentoo-wiki.info/Detecting_your_Hardware

对于硬件的探测工具, 有个有意思的问题:
探测有两种:
1. 直接探测硬件, directly probe the raw hardware
2. 从kernel中收集硬件信息, retrieve the information from kernel

这下是搜出的关于这种问题的讨论:
* http://www.vlug.org/pipermail/discuss/2006-March/020875.html

一个叫David Bronaugh的说:
So neither of these utilities "directly talk with the raw hardware".
They use the kernel as an intermediary, as they should. You're not going
to find many programs in linux (other than the X.org X window system)
that talk directly to hardware without some kind of kernel arbitration,
because it's dangerous.
kernel的安全机制不给directly probe hardware

还有一个 J.Bakshi 的指出lspci三个有意思的参数: -H1, -H2, -M. 如下是lspci的-H1文档:
-H1    Use  direct hardware access via Intel configuration mechanism 1.
看来不是随意就可以talk directly to hardware的!

7. 探测工具的输出结果

下次再写笔记....

Monday, September 14, 2009

使用wireshark了解HTTP的数据包

1. 之前做SA的时候, 出现过挂马现象(其实不是服务器的问题), 那时不知道怎么分析. 结果...不理!!
2. 从书上了解过HTTP的数据, 但没有检测过

使用wireshark, 从网络帧上了解数据包与上层HTTP数据. 会有一些新的, 有意思的事情被发现的


上面的图是访问www.google.com抓出的包. 还有其它包没有显示, 这里只分析GET / HTTP/1.1这个请求

GET /请求被分成三个帧:16, 18, 20. 这种帧在Info栏被称为"TCP segment of a reassembeld PDU". 第16, 18帧都带了1418bytes的, 如下:

看到图片最后: TCP segment data (1418 btyes )

重要: 如果分开去分析16, 18, 20这三个帧, 是很难出整体数据的全貌的.
当然, 要硬查看原始数据也是可以的:

上面就是frame16的data, 开始是HTTP头部数据. 如下是frame18的data:

frame18的data是二进制数据!, frame20也是二进制数据.
为什么? 因为HTTP包的数据部分可以是gzip数据!(下面分析HTTP头部时可以看出来)

如果分析这种被分开的数据包, 其中又包含有二进制数据块是很头大的. 还好, wireshark为大家化简了这种分析!
wireshark会在最后一个TCP包(这里为frame20)进行数据全貌整合, 这种整合只是对于GUI软件显示时出现的, 它并不会对其实数据包进行操作

上图就是frame20的具体情况, 917才是frame20的data部分, 但是还显示出了 Reassembled TCP segments ( 3753 bytes ), 这3753 bytes就是整合出来的

下面看一下整合出来的HTTP请求全貌:

 * 图中蓝色的就是HTTP的gzip数据部分: 二进制数据! 其中Content-Encoding: gzip 就是为什么frame16, 18是二进制数据的原因.

wireshark中也提供了查看HTTP中gzip数据的功能, 在整合帧(frame20)的数据窗口最下面有几个功能:



第一个为本帧的实现数据情况
第二个为整合的整体数据, 这时是有gzip数据的
第三个为解压gzip数据的HTTP情况

Sunday, September 13, 2009

wireshark网络分析

wireshark从网卡中取出的frame:

23 frame: SYN标志, TCP三次握手之一, 这里Seq=0不会存在安全问题? 如这里的: http://en.wikipedia.org/wiki/TCP_sequence_prediction_attack
25 frame: SYN,ACK标志, TCP三次握手之二, 返回多一个Ack=1, (Acknowledgment number)
26 frame: ACK标志, TCP三次握手之三. 握手结束, TCP的会话开始
27 frame: 本帧带一个完整的HTTP请求, 因为从28帧的Ack=422看出:本帧带的TCP数据长度为421bytes, 但每个帧的长度为1500(网卡的MTU为1500), TCP的data最为1428bytes, 所以可以一个帧完整个http的GET请求, 如下本帧的完整情况:
图中可以看到, Seq=1, Ack=1, Len=421
28 frame: 反馈帧, 表示收到421bytes, 期待从第422字节开始
29 frame: 由于GET请求的response数据较长, 被分成多个frame, 29帧的情况从上面绿色的图看不出, 需要从wireshark的frame详细窗中看到:

从第一行看这为Frame 29. Ack=422与28帧一样, 因为source机器除了发GET请求就没有其它请求了.一直是Ack=422
TCP帧带了1428bytes数据(图中的Len=1428).
30 frame: 反馈帧, Ack=1429表示收到1428bytes, 期待从第1429字节开始
31 frame: 与第29帧的情况一样. 帧带了1428bytes的http数据, 为http数据中的一部分

32 frame: 反馈帧, Ack=2857表示收到2857 - 1429(与上一帧相关) = 1428 bytes, 期待从第2857字节开始
33 frame:
36 frame: 与第29帧的情况一样. 帧带了1428bytes的http数据, 为http数据中的一部分, 如图:

37 frame: 反馈帧, Ack=4285表示收到4285 - 2857(与上一帧相关) = 1428 bytes, 期待从第4285字节开始
38 frame: 与第29帧的情况一样. 帧带了1428bytes的http数据, 为http数据中的一部分, 如图:

39 frame: 反馈帧, Ack=5713表示收到5713 - 4285(与上一帧相关) = 1428 bytes, 期待从第4285字节开始
40 frame: 与第29帧的情况一样. 帧带了1428bytes的http数据, 为http数据中的一部分, 如图:

41 frame: 反馈帧, Ack=7141表示收到7141 - 5713(与上一帧相关) = 1428 bytes, 期待从第7141字节开始
42 frame: 与第29帧的情况一样. 帧带了1428bytes的http数据, 为http数据中的一部分, 如图:

43 frame:
反馈帧, Ack=7141表示收到7141 - 5713(与上一帧相关) = 1428 bytes, 期待从第7141字节开始
46 frame, 47 frame:frame33 一起, 起到重配置seq和ack计数器, 如图:

48 frame: 下一次通信开始

Saturday, September 12, 2009

还是跑不起QQ2009

linux下跑个windows, windows下只跑个QQ2009, 觉得总是不对路! 浪费

想到wine, 早知结果是问题多多的, 但是还是动手了.... 呃..... 难道是因为下面这句话:
QQ2009基于Hummer平台,一方面全面兼容、支持Windows/Vista/Linux/Mac等多个系统平台,另一方面更可在PC、手机与无线终端等均可随意、无缝切换。
* 来自http://tech.qq.com/a/20090419/000104.htm

实在是受不了. 还是放弃!

找到很好的两个脚本:

对于wine的乱码问题, 在网上找的修改注册表的文章对QQ2009不起作用. 但是下面的脚本自带的注册表起作用
* http://code.google.com/p/winelocale/

还有一个很有用的脚本:
http://wiki.winehq.org/winetricks

它会从microsoft官网上下载安装包, 主要是为了native dll

Friday, September 11, 2009

就是不使用GUI的samba browser!

如果问我: 使用过Gnome, 它给你最大的印象有哪些?
我一定会说出nautilus. 因为它的功能实大强大, samba的浏览就是一个印象很深刻的功能

我记得有一次使用mount无法加载一个smbfs(其实是不知道使用什么参数, 现在也不知道), 但是nautilus简单完成了

在gentoo下, 因为为了省时间(make的时间实在太久), 一直没有使用nautilus. 近排又想出了samba的GUI browser.
除了nautilus还其实后备?

在linux下, 还有一个比较小型一点的samba browser: LinNeighborhood
使用equery depgraph查看了一下依懒, 不算多. 本想动手emerge一个, 但是又想到
1. samba常在服务器上使用.
2. 使用GUI常常会有"黑箱"的感觉, 有error不能方便在stderr中打印出现
结果还是停下手. 决定搞命令行的!

方便, 快速使用samba的share. 应该使用smbclient, 并非是mount

方便快速使用samba, 应该要:
1. smbclient使用方法
2. nbtscan对网络搜索方法
3. NetBIOS name的使用
下面反序讲述上面3种方法

nbtscan对网络搜索方法

使用GUI browser方便之一就是可以查看整个windows share网络的情况, 比较"网络邻居":

在linux下, 可以使用nbtscan去搜索:
1. 得到整个网段的windows share机器列表
2. 得到NetBIOS名字

例如:
jessinio@niolaptop ~ $ nbtscan  192.168.10.0/24
Doing NBT name scan for addresses from 192.168.10.0/24

IP address       NetBIOS Name     Server    User             MAC address      
------------------------------------------------------------------------------
192.168.10.0    Sendto failed: Permission denied
192.168.10.2     RAINLY-PC        <server>  <unknown>        08-00-27-2c-58-7c
192.168.10.105   NIOLAPTOP        <server>  NIOLAPTOP        00-00-00-00-00-00
192.168.10.106   NIOWIN           <server>  <unknown>        08-00-27-e9-70-63

可以看到, 在192网段有三台机器开了samba服务

nbtscan软件主页: http://www.inetcat.net/software/nbtscan.html
* 不知道是网络不稳定还是nbtscan的问题, 有时搜索的结果不一样的
* 当搜索不出时, 可能使用IP, 硬要使用NetBIOS的话, 可以:wbinfo -I 192.168.10.105 得到NetBIOS name, 但是这时需要winbindd的支持

NetBIOS name的使用

使用NetBIOS name主要是方便指定主机, 如果在smbclient中使用IP去指定机器的话, 可以不使用NetBIOS name
NetBIOS name全名NetBIOS name service, 与DNS是同一类服务!
* 关于NetBIOS name service应见: http://en.wikipedia.org/wiki/NetBIOS#Name_service
例如:
jessinio@niolaptop ~ $ ping NIOWIN
PING NIOWIN (192.168.10.106) 56(84) bytes of data.
64 bytes from 192.168.10.106: icmp_seq=1 ttl=128 time=0.514 ms
* 蓝色的NIOWIN就是使用nbtscan搜索出的NetBIOS name

使用NetBIOS name需要server和client都要有配置!

服务器端:

1. linux下: samba默认就有NetBIOS的功能. smb.conf还有N多关于NetBIOS的配置
2. windows下: 需要在control pannel -> network connections的网卡配置中启用NetBIOS:

客户端:

对我而言, 客户端就是linux. 需要smbclient, ping等程序都可以使用NetBIOS name service, 需要:
1. 编译samba时, 需要编译入winbind功能
2. 配置nsswitch.conf

如下是man winbindd的手册内容:
           ## only available on IRIX: use winbind to resolve hosts:
           # hosts:        files dns winbind
           ## All other NSS enabled systems should use libnss_wins.so like this:
           hosts:          files dns wins
* linux是使用wins, nss使用的库路径为:
jessinio@niolaptop /tmp $ equery files samba|grep libnss
/usr/lib/libnss_winbind.so
/usr/lib/libnss_winbind.so.2
/usr/lib/libnss_wins.so
/usr/lib/libnss_wins.so.2

所以, 只需要在/etc/nsswitch.conf中的hosts一列中加入wins就可以让程序去查询NetBIOS name service


smbclient的使用

上面一大段内容, 只是为了两点:
1. 了解网段中的windows (samba) share的机器
2. 使用NetBIOS name
为使用smbclient提供了一些方便的基础. 现在需要使用smbclient去实际操作数据

列出share point:
smbclient -L //<netbios name>

得出share point后, 登陆samba空间:
jessinio@niolaptop ~ $ smbclient //NIOWIN/personal
Password:
Domain=[NIOWIN] OS=[Windows 5.1] Server=[Windows 2000 LAN Manager]
smb: \>
* NIOWIN为NetBIOS name, personal为share point
smbclient为ftp操作方式, 多数操作看help可以快速学会.
有两个命令需要注意:
1. mput
2. mget
这两个命令与两个switch相关:
1. prompt: 使用mput和mget命令时, 可以使用prompt默认回答y. 一次prompt只能使用一次mput和mget!
2. recurse: 使用mput和mget命令时, 可以使用recurse去操作子目录, 否则子目录会成为一个empty文件
这两个命令是无参数的, 就是说: 单次数打开命令, 双次数为关闭命令
* prompt和recurse在使用上有点重要, 应该多试一下. 本人没有这种描述能力和文章长度不想太长太臭.不说!

smbclient还有一个-c选项, 成了no-interactive方式. happy!






Monday, September 7, 2009

全局umask及机制联想

有需要让系统的mask值统一设置成0002.

自己之前对umask的了解:
1. 设置用户的mask值
2. 在设置用户的mask值后, 用户的新进程都使用这个mask

jessinio@niolaptop ~ $ which umask
which: no umask in (/usr/local/bin:/usr/bin:/bin:/opt/bin:/usr/i686-pc-linux-gnu/gcc-bin/4.3.2:/usr/games/bin:/usr/sbin:/sbin:/usr/local/sbin:/opt)

umask并不是一个独立的一个bin文件, 它是shell中内建的命令

下面两句让我认知都自己的理解是错误的:
1. umask() sets the calling process's file mode creation mask (umask) to mask & 0777 (i.e., only the file permission bits of mask are used), and returns the previous value of the mask.

A  child process created via fork(2) inherits its parent's umask.  The umask is left unchanged by execve(2)
* 来自man 2 umask

总感觉umask的值就像一个环境变量:
jessinio@niolaptop ~ $ umask
0002
jessinio@niolaptop ~ $ bash -c "umask 0022"
jessinio@niolaptop ~ $ umask
0002


子进程是不会影响到父进程的mask值.

这样子, 自己刚开始的需求:
 * 统一影响到所有的程序的Mask值
被分解为三部分:
1. no-interactive的程序, 这里针对/etc/init.d下的daemon
2. interactive的程序
3. 程序自身设置Mask的值

对于第一种, 应该从父进程入手, 系统的所有程序的父进程为init, 查看init的man手册, 没有相关选项.
/sbin/init是由/boot/initrd.img 内的linux脚本启动. 要修改应该从这个入手


对于第二种, 应该从login shell入手. 如:
* /etc/profile
* ~/.profile
* ~/.bash_profile
* ~/.bash_login
* 对于非login shell还有一个文件: ~/.bashrc

对于第三种, 这除了修改代码还有其它办法?

Wednesday, September 2, 2009

以太网卡工作原理

对网卡有个疑问:
1. 网卡对某些数据包进行处理时, 计算机的CPU是不知道的?

为解开这两个问题, 找了一点资料

下面的图是ethernet card的大致设计图: ( 来源于: http://www.patentstorm.us/patents/6252874/claims.html )


arbitration电路: 主要起到转换数据在转输顺序, 所以Transmitting circuit都为经过arbitration circuit才能到达transceiver, 然后发出数据到以太网络中
如下内容从参考文档中copy出来的:
According to one aspect of the present invention, a transmitting circuit and a detection circuit are added to a regular ethernet card, enabling the CPU(fox example, RISC) to inspect packet data received by the MAC of the ethernet card, so that the CPU directly drives the MAC to discard received packet data if packet data received by the MAC has nothing to do with the host computer
* 有两部分Transmitting circuit, 一部分是computer的, 还有一部分是ethernet card的, 因为ethernet card CPU可以直接回复某些数据包而不经过computer的CPU

Receiving circuit 与 Transmitting circuit两部分电路总和称之为 MAC
* 上面的图中没有明文指出哪里是MAC ( media access control )
Detection电路: 主要起到控制MAC中的Receiving circuit部分( 逻辑由CPU去发出 ), 也就是起到控制前往computer的数据流的作用, 对满足要求的数据才能到达computer, 否则, 在ethernet card中被丢掉

到目前为止, 本人提出的疑问算是解开了.

ifconfig可以配置的参数还有很多:
1. promisc: 如果开启此选项, 那么receiving的数据将不受物理地址的影响, 即Destination为任一值都接收
2. hw class address: 可以改变网卡的物理地址
3. arp: 是否充许ARP请求
4. mtu: 修改网卡的物理帧的长度
* 其它参数还没有用到....

参考文档:
https://docs.google.com/fileview?id=0By6wzuq9XWc6ZTMwNzJmYjctNGUxYy00MmRmLTk3ZjItNGZhNjJkM2ViYWRi&hl=en