根据/proc/partitions获取插入的U盘设备名称

本文介绍如何通过/proc/partitions文件获取U盘设备信息,包括主设备号、次设备号、逻辑块大小及设备名,并通过示例代码演示如何标记首要设备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


1   在/proc/partitions中存放着U盘的设备名称,如sda,sdb2等,以sd开头。

major 主设备号,比如一个U盘有3个分区,主设备名为sda,major为8,分区的major也为8 (可能所有的U盘插进来,major都是8),minor则为分区号,sda1,sda2,minor值为1 ,2

sda的minor为0,name即为设备名,连接/dev./设备名,就可以挂载到一个目录。

blocks表示物理设备逻辑块的大小



2,代码

sign_primacy函数标记首要设备

read_proc_partition读取/proc/partitions


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct  parititions_info_s
{
	unsigned long nMajor;
	unsigned long nMinor;
	unsigned long nBlocks;
	char chDeviceName[50];
	int  nPrimacyDeviceFlag;
}parititions_info_t;

int sign_primacy(parititions_info_t *pstuPartitionsInfo,int nDeviceNum)

{
	int i = 0;
	int j = 0;
	char chDeviceNameLastSign[100] = {0};
	if((NULL == pstuPartitionsInfo) ||
		(nDeviceNum <= 0))
	{
		printf("\nparam error\n");
		return -1;
	}

	for(i = 0; i < nDeviceNum - 1;i++)
	{
		if((0 != strlen(chDeviceNameLastSign)) &&
			(NULL != strstr(pstuPartitionsInfo[i].chDeviceName,chDeviceNameLastSign)))
		{
			continue;
		}
		
		for(j = i + 1 ; j < nDeviceNum; j++)
		{
			if(pstuPartitionsInfo[i].nMajor != pstuPartitionsInfo[j].nMajor) //major相同才比较
			{
				break;
			}
			if(NULL != strstr(pstuPartitionsInfo[j].chDeviceName, pstuPartitionsInfo[i].chDeviceName))
			{
				 pstuPartitionsInfo[i].nPrimacyDeviceFlag = 1;

				 memset(chDeviceNameLastSign,0,sizeof(chDeviceNameLastSign));
				 strncpy(chDeviceNameLastSign,pstuPartitionsInfo[i].m_chDeviceName,sizeof(chDeviceNameLastSign) - 1);

				 printf("\n zzh_test primacy  chDeviceName=%s,nMajor[%lu] minor=%lu Flag = %d\n",
				 	pstuPartitionsInfo[i].chDeviceName,
				 	pstuPartitionsInfo[i].nMajor,
				 	pstuPartitionsInfo[i].nMinor,
				 	pstuPartitionsInfo[i].nPrimacyDeviceFlag);

				 i = j;
				 
				 break;
			}
		}
	}

	return 0;
}

int read_proc_partition(parititions_info_t * pstuPartitionsInfo,int nMaxNum,int *pnNum)
{
	FILE *fp = NULL;
	int ret = -1;
	int i = 0;
	int nSscanfNum = 0;
	unsigned long nMajor = 0;
	unsigned long nMinor = 0;
	unsigned long nBlocks = 0;
	char chDeviceName[50] = {0};
	char chBuffer[1024] = {0};
	int nDeviceNum = 0; 
	int nFindDeviceFlag = 0;
	
	if(NULL == pstuPartitionsInfo ||
		NULL == pnNum)
	{
		printf("\n param error \n");
		return -1;
	}

	fp = fopen("/proc/partitions","r");

	if (NULL == fp)
	{
		printf("\n fopen /proc/partitions failed \n");
		return -1;
	}

	
	while(1)
	{
		nFindDeviceFlag = 0;
		memset(chBuffer,0,sizeof(chBuffer));
		if(NULL == fgets(chBuffer,sizeof(chBuffer),fp))
		{
			break;
		}
		memset(chDeviceName,0,sizeof(chDeviceName));
		nSscanfNum = sscanf(chBuffer ," %lu %lu %lu %[^\n]",&nMajor,&nMinor,&nBlocks,chDeviceName);

		if(4 != nSscanfNum)
		{
			continue;
		}

		if(0 != strncmp(chDeviceName,"sd",strlen("sd")))
		{
			continue;
		}

		memset(&pstuPartitionsInfo[nDeviceNum], 0, sizeof(parititions_info_t));
		strncpy(pstuPartitionsInfo[nDeviceNum].chDeviceName,chDeviceName,sizeof(pstuPartitionsInfo[nDeviceNum].chDeviceName) -1);
		pstuPartitionsInfo[nDeviceNum].nMajor = nMajor;
		pstuPartitionsInfo[nDeviceNum].nMinor = nMinor; 
		pstuPartitionsInfo[nDeviceNum].nBlocks = nBlocks;

		printf("\n  nMajor[%lu],   nMinor[%lu],    nBlocks[%lu],    chDeviceName[%s] \n",nMajor,nMinor,nBlocks,chDeviceName);
		//find device 
		nDeviceNum++;

		if(nDeviceNum >= nMaxNum)//最多处理nMaxNum个
		{
			fclose(fp);
			*pnNum = nDeviceNum;
			 sign_primacy( pstuPartitionsInfo,nDeviceNum);
			return 0;
		}
	}
	fclose(fp);

	*pnNum = nDeviceNum;
	if(nDeviceNum > 0)
	{	
		sign_primacy( pstuPartitionsInfo,nDeviceNum);
	}
	
	
	return 0;
}

int main()
{
	parititions_info_t stuPartitionsInfo[30] = {0};
	int nMaxNum = sizeof(stuPartitionsInfo)/sizeof(stuPartitionsInfo[0]);
	int nNum = 0;

	read_proc_partition( stuPartitionsInfo, nMaxNum, &nNum);

	printf("\n Num[%d] \n",nNum);
}



运行结果:






Linux读取U或者移动硬序列号并获取U或者移动硬分区名。基本原理如下: 当有外置 USB 插入的时候,会产生 /proc/scsi/usb-storage 目录,并在其中产生数字文件(形如 1 2 3 4),此文件存储了设备相关信息。 相应的 /sys/class/scsi_device/ 目录中会有 scsi 设备的目录(ide 硬默认无子目录,sata硬默认有子目录),以数字开头(形如 1:0:0:0 2:0:0:0) 这个数字与前面 /proc/scsi/usb-storage目录中的相对应,子目录表示sata硬。比如 /sys/class/scsi_device/2:0:0:0/device/block 中有USB设备,从该目录下得到U或者移动硬的分区名,比如sda1。 该demo实现了上述过程,先检查 /proc/scsi/usb-storage 目录,看是否有u或者移动硬接入,如果有则读取u或者移动硬的序列号,然后在/sys/class/scsi_device/目录下逐级查找,直到找到u或者移动硬的分区。 完整代码,可直接编译和测试,嵌入式环境下也是适应的。 在linux测试如下,id表示序列号,sdb1表示是分区名称: # ./a.out udisk dev num:0 udisk id:055CE21B ret:0 dev num:0 found dir:0:0:0:1 found dev dir:0:0:0:1,full path:/sys/class/scsi_device/0:0:0:1 sub founction found dir:sda found sd device dir:sda,full path:/sys/class/scsi_device/0:0:0:1/device/block/sda found dir:0:0:0:2 found dev dir:0:0:0:2,full path:/sys/class/scsi_device/0:0:0:2 sub founction found dir:sdb found sd device dir:sdb,full path:/sys/class/scsi_device/0:0:0:2/device/block/sdb found sd sub device dir:sdb1 found dir:0:0:0:0 found dev dir:0:0:0:0,full path:/sys/class/scsi_device/0:0:0:0 sub funciton Open Directory /sys/class/scsi_device/0:0:0:0/device/block Error:No such file or directory get name return:0,disk name:sdb1 # 因为有的USB设备会有好几个,比如把CD和U集成到一起,就会出现上面的情况,有多个子目录去查找。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值