Chinaunix首页 | 论坛 | 博客
  • 博客访问: 593407
  • 博文数量: 226
  • 博客积分: 10080
  • 博客等级: 上将
  • 技术积分: 1725
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-26 11:15
文章分类

全部博文(226)

文章存档

2011年(5)

2010年(64)

2009年(99)

2008年(37)

2007年(21)

我的朋友

分类: LINUX

2011-04-23 16:01:38

      部门一产品,比较成熟,其中使用了消息队列。在AIX,HP-UX等多个UNIX下使用均没有问题,前段时间由于系统组的要求,搬迁到LINUX主机上运行,从UNIX到LINUX一般问题应该不大,也顺利部署了几个,但是当再另外一个用户下部署的时候,发现引用不能正常启动,分析代码段:
this->m_iMsqFD = msgget(ipckey,MQ_MODE); 
得到值为-1,perror输出信息为:“Permission denied“查了下msgget的具体说明如下:

/*************************************************************************/

系统调用:msgget();

原型:intmsgget(key_t key,int msgflg);

返回值:如果成功,返回消息队列标识符

如果失败,则返回-1:

errno=EACCESS(权限不允许)

EEXIST(队列已经存在,无法创建)

EIDRM(队列标志为删除)

ENOENT(队列不存在)

ENOMEM(创建队列时内存不够)

ENOSPC(超出最大队列限制)

/*************************************************************************/

发现应该是EACCESS错误,msgget包括创建或得到消息队列的功能,得到消息队列是得到key对应的队列ID,报无权限,有可能系统上有重复的非本用户下的队列,造成无权访问的问题。按照这个思路,我加了打印语句(不好的调试方式:>),输出了由ftok创建的key为:16941057,转成16进制得到:0x01028001,然后用linux下查看消息队列的命令:

ipcs -q|grep 8001 果然得到另外一个用户下的消息队列,现在问题转成了为什么key会重复问题,可以是如何根据目录生成的那?

    查阅了资料发现:ftok 的原型声明为:

key_t ftok( char * fname, int id )

其中,fname是指定的文件名(包括目录名),这个必须是存在,而且是有权限访问的,

id是子序号,虽然为int,但是只有8个比特被使用(0-255)。

    ”在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。如指定文件的索引节点号为65538,换算成16进制为 0x010002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002

查询文件索引节点号的方法是: ls -i 

     通过ls -i查询得到我创建key的目录为索引节点为:11370497 转成16进制为AD 8001 linux中取后四位即后面2个字节,我们程序传入的ID为:01 ,不过linuxdev有关系,拼接上ID 最终得到的Key为 0x 01 02 8001 ,dev的查看方法为cat /proc/devices 查看硬盘对应的dev为02 (我自己的理解),得到的值果然重复,用man ftok查看了下:

  Typically, a best effort attempt com-bines the given proj_id byte, the lower 16 bits of the i-node number, and the lower 8 bits of the device number  into  a  32-bit  result.

并且有,有时候重复是难免的,既然重复难以避免的怎么办那?对于我的情况,我想可以通过删除创建key的目录,然后重建,不过在这两个动作之间一定要有创建文件的操作,防止再次创建目录的inode节点和原来是同一个,程序代码嘛,可以改成一直随机id的值,直到不报错位置(也许您又更好的办法:>).





阅读(5169) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~