转自:http://blog.chinaunix.net/uid-10769062-id-3230811.html

Busybox-1.9.
在util-linux/mount.c的line:1609行首先映入眼帘的是:
int mount_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
由于busybox是一个box,里面包含很多的可执行程序,如果cp,mount,umount等我们常用的一些命令,所以每个命令单独写入一个文件,而每个文件中也用类似mount_main()这样的命名方法作为局部的main函数。
MAIN_EXTERNALLY_VISIBLE的定义在 busybox-1.9./include/libbb.h中
如下:
/* We need to export XXX_main from libbusybox
* only if we build "individual" binaries
*/
#if ENABLE_FEATURE_INDIVIDUAL
#define MAIN_EXTERNALLY_VISIBLE EXTERNALLY_VISIBLE
#else
#define MAIN_EXTERNALLY_VISIBLE
#endif
而 EXTERNALLY_VISIBLE的定义在 busybox-1.9./include/platform.h中,line:73如下 /* -fwhole-program makes all symbols local. The attribute externally_visible
forces a symbol global. */
# if __GNUC_PREREQ (,)
# define EXTERNALLY_VISIBLE __attribute__(( visibility("default") ));
//__attribute__ ((__externally_visible__))
# else
# define EXTERNALLY_VISIBLE
# endif /* GNUC >= 4.1 */ 其中,__GNUC_PREREQ() 是什么意思呢? 在 busybox-1.9./include/platform.h,line:
/* Convenience macros to test the version of gcc. */
#undef __GNUC_PREREQ
#if defined __GNUC__ && defined __GNUC_MINOR__
# define __GNUC_PREREQ(maj, min) \
((__GNUC__ << ) __GNUC_MINOR__ >= ((maj) << ) (min))
#else
# define __GNUC_PREREQ(maj, min)
#endif 首先取消 __GNUC_PREREQ原来的宏定义,然后再根据__GNUC__ 和__GNUC_MINOR__的情况重新定义 __GNUC_PREREQ。
#undef 是在后面取消以前定义的宏定义§
其中, __GNUC__ 是gcc编译器编译代码时预定义的一个宏,他的值表示当前GCC的版本号,可以通过查看gcc版确定一下。
然后 __GNUC_MINOR__的含义也就可以推出了。 The macro contains the minor version number of the compiler. This can be used to work around differences between different releases of the compiler. It must always be used together with __GNUC__§. 返回去看
# if __GNUC_PREREQ (,)
其实就是看当前的GCC版本是否>=.1然后再做下一步判断。
接下来的:
#define EXTERNALLY_VISIBLE __attribute__(( visibility("default") ));
重点在于:
__attribute__(( visibility("default") ));
通过这个链接:http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html可知__attribute__ 的强大,可对变量,函数等symbols 对外的可见属性进行修改:
visibility ("visibility_type")
The visibility attribute on ELF targets causes the declaration to be emitted with default, hidden, protected or internal visibility.
void __attribute__ ((visibility ("protected")))
f () { /* Do something. */; }
int i __attribute__ ((visibility ("hidden"))); See the ELF gABI for complete details, but the short story is:
default
Default visibility is the normal case for ELF. This value is available for the visibility attribute to override other options that may change the assumed visibility of symbols. hidden
Hidden visibility indicates that the symbol will not be placed into the dynamic symbol table, so no other module (executable or shared library) can reference it directly. internal
Internal visibility is like hidden visibility, but with additional processor specific semantics. Unless otherwise specified by the psABI, GCC defines internal visibility to mean that the function is never called from another module. Note that hidden symbols, while they cannot be referenced directly by other modules, can be referenced indirectly via function pointers. By indicating that a symbol cannot be called from outside the module, GCC may for instance omit the load of a PIC register since it is known that the calling function loaded the correct value. protected
Protected visibility indicates that the symbol will be placed in the dynamic symbol table, but that references within the defining module will bind to the local symbol. That is, the symbol cannot be overridden by another module.
Not all ELF targets support this attribute. 接下来
/* parse long options, like --bind and --move. Note that -o option
* and --option are synonymous. Yes, this means --remount,rw works. */ for (i = j = ; i < argc; i )
{
if (argv[i][] == '-' && argv[i][] == '-')
{
append_mount_options(&cmdopts, argv[i] );
}
else
{
argv[j ] = argv[i];
}
}
argv[j] = ;
argc = j;
主要目的是解析命令行中的参数和选项,针对的是带有 "- -" 类型的长选项,实际上,- - 和 - 是一样的。主要是通过 append_mount_options()这个函数完成,进入 append_mount_options()。
其中,cmdopts是一个指针,它通过
char *cmdopts = xstrdup(""), busybox-1.9./util-linux/mount.c line: /* Append mount options to string */
static void append_mount_options(char **oldopts, const char *newopts)
{
if (*oldopts && **oldopts) {
/* do not insert options which are already there */
while (newopts[]) {
char *p;
int len = strlen(newopts);
p = strchr(newopts, ',');
if (p) len = p - newopts;
p = *oldopts;
while () {
if (!strncmp(p, newopts, len)
&& (p[len] == ',' || p[len] == '\0'))
goto skip;
p = strchr(p,',');
if (!p) break;
p ;
}
p = xasprintf("%s,%.*s", *oldopts, len, newopts);
free(*oldopts);
*oldopts = p;
skip:
newopts = len;
while (newopts[] == ',') newopts ;
}
} else {
if (ENABLE_FEATURE_CLEAN_UP) free(*oldopts);
*oldopts = xstrdup(newopts);
}
} -- : if (!argc)
{
if (!(opt & OPT_ALL)) {
FILE *mountTable = setmntent(bb_path_mtab_file, "r");
printf("[%s:%d]bb_path_mtab_file=%s\n",__FILE__,__LINE__,bb_path_mtab_file); if (!mountTable) bb_error_msg_and_die("no %s", bb_path_mtab_file); while (getmntent_r(mountTable, &mtpair[], getmntent_buf,sizeof(getmntent_buf)))
{
// Don't show rootfs. FIXME: why??
// util-linux 2.12a happily shows rootfs...
//if (!strcmp(mtpair->mnt_fsname, "rootfs")) continue; if (!fstype || !strcmp(mtpair->mnt_type, fstype))
{
printf("%s on %s type %s (%s)\n", mtpair->mnt_fsname,mtpair->mnt_dir, mtpair->mnt_type,mtpair->mnt_opts);
}
}
if (ENABLE_FEATURE_CLEAN_UP)
{
endmntent(mountTable);
}
return EXIT_SUCCESS;
}
}
else
{
storage_path = bb_simplify_path(argv[]);
} line: 到line1765是依次从bb_path_mtab指向的文件中读取一行一行的数据,这些数据是 struct mntent格式的。Line1761 到line1763是打印出来的信息,如在命令行下直接输入:mount则显示: [zl@zhanglei ~]$ mount
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime,seclabel)
devtmpfs on /dev type devtmpfs (rw,nosuid,relatime,seclabel,size=956748k,nr_inodes=,mode=)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,seclabel,gid=,mode=,ptmxmode=)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,relatime,seclabel)
/dev/sda3 on / type ext4 (rw,relatime,seclabel,user_xattr,acl,barrier=,data=ordered)
tmpfs on /run type tmpfs (rw,nosuid,nodev,relatime,seclabel,mode=)
selinuxfs on /sys/fs/selinux type selinuxfs (rw,relatime)
tmpfs on /sys/fs/cgroup type tmpfs (rw,nosuid,nodev,noexec,relatime,seclabel,mode=)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
systemd- on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=,pgrp=,timeout=,minproto=,maxproto=,direct)
mqueue on /dev/mqueue type mqueue (rw,relatime,seclabel)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,seclabel)
securityfs on /sys/kernel/security type securityfs (rw,relatime)
tmpfs on /media type tmpfs (rw,nosuid,nodev,noexec,relatime,rootcontext=system_u:object_r:mnt_t:s0,seclabel,mode=)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
/dev/sda5 on /mnt/sda5 type ext2 (rw,relatime,seclabel,user_xattr,acl,barrier=)
/dev/sda6 on /mnt/sda6 type ext2 (rw,relatime,seclabel,user_xattr,acl,barrier=)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)
gvfs-fuse-daemon on /home/zl/.gvfs type fuse.gvfs-fuse-daemon (rw,nosuid,nodev,relatime,user_id=,group_id=)
[zl@zhanglei ~]$ 同时查看/etc/fstab的内容为: [zl@zhanglei ~]$ cat /etc/fstab #
# /etc/fstab
# Created by anaconda on Thu Dec ::
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(), findfs(), mount() and/or blkid() for more info
#
UUID=a95fe862-ce64-485c-8bc6-10c3047b2fdb / ext4 defaults
UUID=869aca65-bf53-48e1-ab81-e6d2296cb818 swap swap

mount源码分析 【转】的更多相关文章

  1. Spring源码分析——资源访问利器Resource之实现类分析

    今天来分析Spring的资源接口Resource的各个实现类.关于它的接口和抽象类,参见上一篇博文——Spring源码分析——资源访问利器Resource之接口和抽象类分析 一.文件系统资源 File ...

  2. Solr初始化源码分析-Solr初始化与启动

    用solr做项目已经有一年有余,但都是使用层面,只是利用solr现有机制,修改参数,然后监控调优,从没有对solr进行源码级别的研究.但是,最近手头的一个项目,让我感觉必须把solrn内部原理和扩展机 ...

  3. Docker源码分析(九):Docker镜像

    1.前言 回首过去的2014年,大家可以看到Docker在全球刮起了一阵又一阵的“容器风”,工业界对Docker的探索与实践更是一波高过一波.在如今的2015年以及未来,Docker似乎并不会像其他昙 ...

  4. Vue.js 源码分析(三十一) 高级应用 keep-alive 组件 详解

    当使用is特性切换不同的组件时,每次都会重新生成组件Vue实例并生成对应的VNode进行渲染,这样是比较花费性能的,而且切换重新显示时数据又会初始化,例如: <!DOCTYPE html> ...

  5. Vue.js 源码分析(二十七) 高级应用 异步组件 详解

    当我们的项目足够大,使用的组件就会很多,此时如果一次性加载所有的组件是比较花费时间的.一开始就把所有的组件都加载是没必要的一笔开销,此时可以用异步组件来优化一下. 异步组件简单的说就是只有等到在页面里 ...

  6. Vue.js 源码分析(三) 基础篇 模板渲染 el、emplate、render属性详解

    Vue有三个属性和模板有关,官网上是这样解释的: el ;提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标 template ;一个字符串模板作为 Vue 实例的标识使用.模板将会 ...

  7. Vue.js 源码分析(九) 基础篇 生命周期详解

    先来看看官网的介绍: 主要有八个生命周期,分别是: beforeCreate.created.beforeMount.mounted.beforeupdate.updated   .beforeDes ...

  8. Vue.js 源码分析(十二) 基础篇 组件详解

    组件是可复用的Vue实例,一个组件本质上是一个拥有预定义选项的一个Vue实例,组件和组件之间通过一些属性进行联系. 组件有两种注册方式,分别是全局注册和局部注册,前者通过Vue.component() ...

  9. Vue源码分析(二) : Vue实例挂载

    Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...

随机推荐

  1. 手机端input[type=date]的时候placeholder不起作用解决方案

    目前PC端对input 的date类型支持不好,我试下来的结果是只有chrome支持.firefox.IE11 都不支持.而且PC端有很多日历控件可供使用.就不去多考虑这点了. 那么在移动端的话,io ...

  2. 给你完美浪漫的七夕,APICloud送你双人电影票!

    我一直觉得“幸福的感觉” 就像存款 留着以后用 会幸福感爆棚 于是,我一直习惯于等等,再等等 以为那样就会很幸福 直到有一天,突然发现,在我构想的未来中,总是有你 世界那么大,我只在乎你 世界那么长, ...

  3. IIS应用程序池添加ASP.NET v4.0

    可能在安装.NET Framewrok 4.0之前,IIS就已经装好了,结果在IIS的应用程序池中只有.NET 2.0的Classic .NET AppPool和DefaultAppPool.在使用v ...

  4. Yii中配置单点登录 即多个子站同步登录

    研究Yii的同步登录大概2个多月,几乎查遍了网上所有资料和案例,但都不是很理想,最后摸索出整理出来以下配置方案. 以下配置文件在config.php中,所有需要同步的站点都需要填写.网上一些站点给出的 ...

  5. ATS连接 https

    HTTPS协议是Http Over SSL,简单来说就是HTTP的安全版本,在HTTP的基础上增加SSL/TLS加密传输协议,通过HTTPS加密传输和身份认证保证了传输过程的安全性.在登录网银和电子邮 ...

  6. iOS如何统计渠道

    http://bbs.umeng.com/thread-10-1-1.html https://www.zhihu.com/question/20697933

  7. iOS调用系统的电话功能

    NSString *allString = [NSString stringWithFormat:@"tel:10086"];//注意电话号码不能包含空格,包含空格的电话号码拨打没 ...

  8. 使用ajax请求,模态框调用并更改密码

    前端页面 <a href="javascript:void(0);" onclick="changPassword()"> <i class= ...

  9. 布置theano(Ubuntu14.04 LTS)

    引言 由于研究生阶段将会从事自然语言处理方向的研究,目前要用到机器学习和深度学习相关的框架,那应老师的要求,将要使用theano,由于theano官方文档中关于ubuntu下配置的问题并没有给出很好的 ...

  10. C++Primer 第五章

    //1.表达式语句的作用:执行表达式并丢弃求值结果 ; value + ; //执行,并丢弃结果 //2.复合语句是指用花括号括起来的语句和声明的序列,复合语句称为块.一个块就是一个作用域.块不以分号 ...