linux c语言chdir,rmmod chdir no such file or directory 《转》

说明:

1. 此文档基于 linux 2.6.32,TQ2440上测试通过,

2. arm-linux-gcc版本

Thread model: posix

gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203)

一. 问题描述及追踪分析

使用 rmmod时候发现如下错误

rmmod chdir no such file or directory

追踪该错误信息,发现busybox rmmod.c   位置  busybox-1.xxx/modutils/rmmod.c

函数框架如下

int rmmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;

int rmmod_main(int argc UNUSED_PARAM, char **argv)

{

//.......

if (!*argv)

bb_show_usage();

//......

while (*argv) {

char modname[MODULE_NAME_LEN];

const char *bname;

bname = bb_basename(*argv++);

if (n)

safe_strncpy(modname, bname, MODULE_NAME_LEN);

else

filename2modname(bname, modname);

if (bb_delete_module(modname, flags))

bb_error_msg_and_die("can't unload '%s': %s",

modname, moderror(errno));

}

return EXIT_SUCCESS;

}

研究 这个函数,我们发现删除模块的 核心函数 是 bb_delete_module,追踪这个函数,在 /modutils/modutils.c中,我们得到如下函数

int FAST_FUNC bb_delete_module(const char *module, unsigned int flags)

{

errno = 0;

delete_module(module, flags);

return errno;

}

这个表明rmmod实现是依靠delete_module

继续跟踪delete_module,

#ifdef __UCLIBC__

extern int delete_module(const char *module, unsigned int flags);

#else

# include # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)

#endif

这个 是什么意思呢?

如果定义了 __UCLIBC__  则使用uClibc中的  delete_module(const char *module, unsigned int flags)函数

否则,则用系统调用内核的 sys_delete_module函数 该函数原型如下

asmlinkage long sys_delete_module(const char __user *  name_user,  unsigned int  flags);

我们 再来看 safe_strncpy(modname, bname, MODULE_NAME_LEN); 函数和 filename2modname(bname, modname);函数

这俩个函数 的作用都是获得 模块名称 ,使用的核心实现方式是  strrchr(name, '/');

char *strchr(const char *s, int c);

The strrchr() function returns a pointer to the last occurrence of  the character c in the string s.

这个意思时说strrchr函数返回字符C在 字符串S中最后一次出现的位置。

假如我们使用如下指令

#rmmod  /lib/modules/2.6.32/adc.ko

经过函数处理后, modname 将变回 adc.ko

值得注意的是 bb_basename() 函数如下

const char* FAST_FUNC bb_basename(const char *name)

{

const char *cp = strrchr(name, '/');

if (cp)

return cp + 1;

return name;

} 该函数 已经进行了一次处理

另外, filename2modname 函数

char * FAST_FUNC filename2modname(const char *filename, char *modname)

{

int i;

char *from;

if (filename == NULL)

return NULL;

if (modname == NULL)

modname = xmalloc(MODULE_NAME_LEN);

from = bb_get_last_path_component_nostrip(filename);

for (i = 0; i < (MODULE_NAME_LEN-1) && from[i] != '\0' &&from[i] != '.'; i++)

modname[i] = (from[i] == '-') ? '_' : from[i];

modname[i] = '\0';

return modname;

}

注意

from[i] != '.' ,这个意味着 adc.ko 会被解析成adc

from[i] == '-'? '_' : from[i]这个意味着 adc-xyz会被解析成adc_xyz

分析到这里,我们也就知道了rmmod的全过程,核心在于利用sys_delete_module函数卸载驱动模块

下面给出解决方法

二. 解决方法

建立rmmod.c ,内容如下

#include #include #include #include #include #include int main(int argc, char *argv[])

{

int ret = -1;

int left_time =5;

int i=0;

if(!argv[1])

{

printf("usage: rmmod modename\n");

return -1;

}

char *modname = argv[1];

while(argv[1][i]!='\0')

{

//如下这个 是为了 rmmod adc.ko 与 rmmod adc效果一致

if(argv[1][i]=='.'){argv[1][i]='\0';break;}

i++;

};

while (left_time-- > 0) {

ret = delete_module(modname, O_NONBLOCK | O_EXCL);//系统调用sys_delete_module

if (ret < 0 && errno == EAGAIN)

sleep(1);

else

break;

}

if (ret != 0) printf("Error when rmmod module %s: %s\n",modname, strerror(errno));

return 0;

}

在PC中

#arm-linux-gcc rmmod.c -o rmmod

在板子中

#mv /sbin/rmmod /sbin/rmmod2

#mv rmmod /sbin/rmmod

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值