www.pudn.com > raid.rar > raid.c


/*! raid.c  dell硬盘检测入口
*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "raid.h"
#include 
#include "Attr_API.h"

struct locator {
	int channel;
	int target;
	int lun;
};

/* RAID IOCTL Operation Definition */
struct raid_ioctl_operations {
	int	(*raid_ioctl_init)();
	int	(*raid_ioctl_end)();
	int 	(*raid_ioctl_sel_adapt)(unsigned char adapt_no);
	int 	(*raid_ioctl)(unsigned int cmd, char *addr);
	char	raid_card_name[DEV_NAME_LEN];
};


/*获取raid状态的api, raid_ioctl_ops[0]用于sas  perc5接口的硬盘
	raid_ioctl_ops[1]用于scsi perc4硬盘
*/
static struct raid_ioctl_operations raid_ioctl_ops[] = {
	{	
	.raid_ioctl_init = megasas_ioctl_init, 
	.raid_ioctl_end = megasas_ioctl_end, 
	.raid_ioctl_sel_adapt = megasas_ioctl_sel_adapt,
	.raid_ioctl = megasas_ioctl, 
	"PERC5"
	}, 
	{	
	.raid_ioctl_init = megascsi_ioctl_init, 
	.raid_ioctl_end = megascsi_ioctl_end, 
	.raid_ioctl_sel_adapt = megascsi_ioctl_sel_adapt,
	.raid_ioctl = megascsi_ioctl, 
	"PERCSCSI"
	}
};

//全局api 函数指针
int	(*raid_ioctl_init)();
int	(*raid_ioctl_end)();
int 	(*raid_ioctl_sel_adapt)(unsigned char adapt_no);
int	(*raid_ioctl)(unsigned int cmd, char *addr);
char	raid_card_name[DEV_NAME_LEN];

void mio_inq(char *);


struct mio_locate bl;



/* 功能:创建设备文件并获取设备raid信息
	返回:卷数目

*/
int  QueryRaidStatus(int *raidLevel, struct raid_ioctl_operations* poperation);


/*功能:获取raid状态
   参数:devnum 设备号,praidinfo存储探测结果
  返回: 0 获取失败
                其他  ,返回volume数量
*/
int  GetRaidStatus(int devnum, int *raidLevel)
{
	char sCommand[1024]={0};
	int num=0;
	system("rm /dev/megadev0");
	snprintf(sCommand, sizeof(sCommand),"mknod  /dev/megadev0 c %d 0",devnum);
	system(sCommand);

	if((num=QueryRaidStatus(raidLevel, &raid_ioctl_ops[0]) )>0)
		return num;

	if((num=QueryRaidStatus(raidLevel, &raid_ioctl_ops[1]) )>0)
		return num;
	return 0;
}


 
 int mio_inq_2(char *name, int *raidLevel);


/*
	功能:根据指定的api,获取接口信息
	参数:praidinfo 保存探测的设备状态
		     poperation  api指针集
	返回:<=0获取状态失败
			>0 获取的volume数目
*/
int  QueryRaidStatus(int *raidLevel, struct raid_ioctl_operations* poperation)
{

	int numv=0;
	raid_ioctl_init = poperation->raid_ioctl_init;
	raid_ioctl_end = poperation->raid_ioctl_end;
	raid_ioctl_sel_adapt = poperation->raid_ioctl_sel_adapt;
	raid_ioctl = poperation->raid_ioctl;
	strcpy(raid_card_name, poperation->raid_card_name);
	if (raid_ioctl_init()) {
		//printf("MEGA SAS IOCTL initialization failed\n");
		return -1;
	}
	
	raid_ioctl_sel_adapt(0);
	numv=mio_inq_2(raid_card_name, raidLevel);
	raid_ioctl_end();
	return numv;
}


/*
	功能:DELL硬盘检测入口函数,该函数完成检测功能
	
*/

int ReadDellRaidInfo()
{
	FILE* fp=NULL;
	char cCommand[1024]={0};
	char devinfo[300]={0};

    int raidLevel = -1;
	int retflag=0;
	
	snprintf(cCommand,sizeof(cCommand),"cat /proc/devices |grep mega");
	fp=popen(cCommand,"r");
	if(NULL==fp)
	{
		//printf("there's no mega device\n");
		return raidLevel;
	}
	
	while(!feof(fp))
	{
		int len=0;
		int devno=0;
		memset(devinfo,0,sizeof(devinfo));
		fgets(devinfo,sizeof(devinfo),fp);
		devinfo[sizeof(devinfo)-1]='\0';
		//printf("%s\n",devinfo);
		len=strlen(devinfo);
		if(0==len)
		{
			//printf("this line is empty\n");
			//fprintf(g_outfd,"this line is empty\n");
			continue;
		}
		devinfo[len-1]='\0';
		//printf("Dell_Raid_Chek:%s\n",devinfo);
		//fprintf(g_outfd,"Dell_Raid_Chek:%s\n",devinfo);
		devno=atoi(devinfo);
		retflag=GetRaidStatus(devno, &raidLevel);
		if(retflag<=0)
		{
			continue;
		}
		else
		{
		    break;
		}
		//printf("vnum:%d\n",tmpraiddeisinfo._volumenum);
		//fprintf(g_outfd,"vnum:%d\n",tmpraiddeisinfo._volumenum);
		
	}
	pclose(fp);

    return raidLevel;
}



/*
	功能:获取raid状态,结果保存在praidinfo中
	参数: name 接口名
			
*/
int mio_inq_2(char *name, int *raidLevel)
{
	int rv, i;
	struct mioc_inq bi;
	struct mioc_vol bv;
    (void)name;
	
	memset(&bi, 0, sizeof(bi));

	bi.bi_cookie = bl.bl_cookie;

	rv = raid_ioctl(MIOC_INQ, (char *)&bi);
	if (rv == -1) {
		warn("MIOC_INQ");
		return -1;
	}

	for (i = 0; i < bi.bi_novol; i++) 
	{
		memset(&bv, 0, sizeof(bv));
		bv.bv_cookie = bl.bl_cookie;
		bv.bv_volid = i;

		rv = raid_ioctl(MIOC_VOL, (char *)&bv);
		if (rv == -1) 
		{
			warn("MIOC_VOL");
			return -1;
		}
		
/*
		if (name && strcmp(name, bv.bv_dev) != 0)
		{
			continue;
		}
*/

		if ((bv.bv_level == -1) && (bv.bv_nodisk == 1))
		{
			continue;
		}
		else if ((bv.bv_level == -2) && (bv.bv_nodisk == 1))
		{
			continue;
		}
		else 
		{
            *raidLevel = bv.bv_level;
			//printf("the raid level is RAID%u\n", *raidLevel);
		}
	}
	return bi.bi_novol;
}