Skip to contentSkip to conversation

(unknown)

DISCUSSION kernel.majianpeng 2 participants 4 messages Dec 25, 2010 – Dec 27, 2010 1 message not in the archive MD RAID

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

According md.c:
* We have a system wide 'event count' that is incremented
* on any 'interesting' event, and readers of /proc/mdstat
* can use 'poll' or 'select' to find out when the event
* count increases.
Events are:
* start array, stop array, error, add device, remove device,
* start build, activate spare
I wanted to monitor RAID5 events,so I writed a c-function:
int fd = open("/proc/mdstat",O_RDONLY);
if(fd < 0){
printf("open /proc/mdstat error:%s\n",strerror(errno));
return -errno;
}
struct pollfd fds[1];
int ret;
fds[0].fd = fd;
fds[0].events = POLLPRI;
while(1){
fds[0].fd = fd;
fds[0].events = POLLPRI;
ret = poll(fds,1,-1);
if(ret < 0){
printf("poll error:%s\n",strerror(errno));
break;
}else
printf("ret value=%d\n",ret);
}
close(fd);
But this function did not run like my thought.
After a raid event occured,the poll did not blocked,.The function only well at first. I wrote anthoer function:
do{
int fd = open("/proc/mdstat",O_RDONLY);
if(fd < 0){
printf("open /proc/mdstat error:%s\n",strerror(errno));
return ;
}
struct pollfd fds;
memset(&fds,0, sizeof(struct pollfd));
fds.fd = fd;
fds.events = POLLPRI|POLLERR;
if(poll(&fds,1,-1) == -1){
printf("poll error:%s\n",strerror(errno));
break;
}
printf("return events:%d\n",fds.revents);
close(fd);
}while(1);
this function work well, can return when raid_event occured.
I read the source found:
static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
{
struct seq_file *m = filp->private_data;
struct mdstat_info *mi = m->private;
int mask;
poll_wait(filp, &md_event_waiters, wait);
/* always allow read */
mask = POLLIN | POLLRDNORM;
if (mi->event != atomic_read(&md_event_count)){
mask |= POLLERR | POLLPRI;
}
return mask;
}
the mi->event assigned at function:md_seq_open.
When open /proc/mdstat,the mi->event = md_event_count, so the first poll blocked. But after poll return,mi->event != md_event_count,so the rest poll must immediately return. In second function,every time I opend /proc/mdstat,so mi->event = md_event_count, when blocked

2010-12-25

kernel.majianpeng

#2 lore raw

Re: using poll on /proc/mdstat

Quoted 25 lines · On Sat, 25 Dec 2010 10:49:02 +0800 "kernel.majianpeng"…

According md.c:
* We have a system wide 'event count' that is incremented
* on any 'interesting' event, and readers of /proc/mdstat
* can use 'poll' or 'select' to find out when the event
* count increases.
Events are:
* start array, stop array, error, add device, remove device,
* start build, activate spare
I wanted to monitor RAID5 events,so I writed a c-function:
int fd = open("/proc/mdstat",O_RDONLY);
if(fd < 0){
printf("open /proc/mdstat error:%s\n",strerror(errno)); return -errno;
}
struct pollfd fds[1];
int ret;
fds[0].fd = fd;
fds[0].events = POLLPRI;
while(1){
fds[0].fd = fd;
fds[0].events = POLLPRI;
ret = poll(fds,1,-1);
if(ret < 0){

Quoted 8 lines

printf("poll error:%s\n",strerror(errno));
break;
}else
printf("ret value=%d\n",ret);
}
close(fd);
But this function did not run like my thought.
After a raid event occured,the poll did not blocked,.The function only well at first.

poll will only block again after you read to the end of the file (and thus observe any change), and then seek back to the start.

Any time that poll reports and event, you need to respond to that event (e.g. by reading) or poll will continue to tell you that the event is pending. This helps avoid some races.

Quoted 11 lines

I wrote anthoer function:
do{
int fd = open("/proc/mdstat",O_RDONLY);
if(fd < 0){
printf("open /proc/mdstat error:%s\n",strerror(errno)); return ;
}
struct pollfd fds;
memset(&fds,0, sizeof(struct pollfd));
fds.fd = fd;
fds.events = POLLPRI|POLLERR;

Quoted 8 lines

if(poll(&fds,1,-1) == -1){
printf("poll error:%s\n",strerror(errno));
break;
}
printf("return events:%d\n",fds.revents); close(fd);
}while(1);
this function work well, can return when raid_event occured.

After each poll, you close and re-open the file. This is enough to 'tell' poll that you have noticed the event.

If you have further questions, please ask.

NeilBrown

Quoted 29 lines

I read the source found:
static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
{
struct seq_file *m = filp->private_data;
struct mdstat_info *mi = m->private;
int mask;
poll_wait(filp, &md_event_waiters, wait);
/* always allow read */
mask = POLLIN | POLLRDNORM;
if (mi->event != atomic_read(&md_event_count)){
mask |= POLLERR | POLLPRI;
}
return mask;
}
the mi->event assigned at function:md_seq_open.
When open /proc/mdstat,the mi->event = md_event_count, so the first poll blocked. But after poll return,mi->event != md_event_count,so the rest poll must immediately return. In second function,every time I opend /proc/mdstat,so mi->event = md_event_count, when blocked

2010-12-25

kernel.majianpeng

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#3 lore raw

Re: Re: using poll on /proc/mdstat

Hi all:
read Neil Brown's mail, I modified the function:

char buff[4096] = {0};
	int fd = open("/proc/mdstat",O_RDONLY);
	if(fd < 0){
		printf("open /proc/mdstat error:%s\n",strerror(errno));
		return -errno;
	}

	struct pollfd fds[1];
	int ret;

	fds[0].fd = fd;
	fds[0].events = POLLPRI;
	while(1){
		fds[0].fd = fd;
		fds[0].events = POLLPRI;
		ret = poll(fds,1,-1);
		if(ret < 0){
			printf("poll error:%s\n",strerror(errno));
			break;
		}else
			printf("ret value=%d\n",fds[0].revents);
		read(fd,buff,4096);
		memset(buff ,0,4096);
	}
	close(fd);

I add read command and confirm read end of file /proc/mdstat. But this fution also to find only one event.

------------------
kernel.majianpeng
2010-12-27

-------------------------------------------------------------
发件人:Neil Brown
发送日期:2010-12-26 19:44:43
收件人:kernel.majianpeng
抄送:linux-raid
主题:Re: using poll on /proc/mdstat

Quoted 25 lines · On Sat, 25 Dec 2010 10:49:02 +0800 "kernel.majianpeng"…

According md.c:
* We have a system wide 'event count' that is incremented
* on any 'interesting' event, and readers of /proc/mdstat
* can use 'poll' or 'select' to find out when the event
* count increases.
Events are:
* start array, stop array, error, add device, remove device,
* start build, activate spare
I wanted to monitor RAID5 events,so I writed a c-function:
int fd = open("/proc/mdstat",O_RDONLY);
if(fd < 0){
printf("open /proc/mdstat error:%s\n",strerror(errno)); return -errno;
}
struct pollfd fds[1];
int ret;
fds[0].fd = fd;
fds[0].events = POLLPRI;
while(1){
fds[0].fd = fd;
fds[0].events = POLLPRI;
ret = poll(fds,1,-1);
if(ret < 0){

Quoted 8 lines

printf("poll error:%s\n",strerror(errno));
break;
}else
printf("ret value=%d\n",ret);
}
close(fd);
But this function did not run like my thought.
After a raid event occured,the poll did not blocked,.The function only well at first.

poll will only block again after you read to the end of the file (and thus observe any change), and then seek back to the start.

Any time that poll reports and event, you need to respond to that event (e.g. by reading) or poll will continue to tell you that the event is pending. This helps avoid some races.

Quoted 11 lines

I wrote anthoer function:
do{
int fd = open("/proc/mdstat",O_RDONLY);
if(fd < 0){
printf("open /proc/mdstat error:%s\n",strerror(errno)); return ;
}
struct pollfd fds;
memset(&fds,0, sizeof(struct pollfd));
fds.fd = fd;
fds.events = POLLPRI|POLLERR;

Quoted 8 lines

if(poll(&fds,1,-1) == -1){
printf("poll error:%s\n",strerror(errno));
break;
}
printf("return events:%d\n",fds.revents); close(fd);
}while(1);
this function work well, can return when raid_event occured.

After each poll, you close and re-open the file. This is enough to 'tell' poll that you have noticed the event.

If you have further questions, please ask.

NeilBrown

Quoted 29 lines

I read the source found:
static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
{
struct seq_file *m = filp->private_data;
struct mdstat_info *mi = m->private;
int mask;
poll_wait(filp, &md_event_waiters, wait);
/* always allow read */
mask = POLLIN | POLLRDNORM;
if (mi->event != atomic_read(&md_event_count)){
mask |= POLLERR | POLLPRI;
}
return mask;
}
the mi->event assigned at function:md_seq_open.
When open /proc/mdstat,the mi->event = md_event_count, so the first poll blocked. But after poll return,mi->event != md_event_count,so the rest poll must immediately return. In second function,every time I opend /proc/mdstat,so mi->event = md_event_count, when blocked

2010-12-25

kernel.majianpeng

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#4 lore raw

Re: using poll on /proc/mdstat

Quoted 28 lines · On Mon, 27 Dec 2010 09:21:00 +0800 "kernel.majianpeng"…

Hi all:
read Neil Brown's mail, I modified the function:

char buff[4096] = {0};
	int fd = open("/proc/mdstat",O_RDONLY);
	if(fd < 0){
		printf("open /proc/mdstat error:%s\n",strerror(errno));
		return -errno;
	}

	struct pollfd fds[1];
	int ret;

	fds[0].fd = fd;
	fds[0].events = POLLPRI;
	while(1){
		fds[0].fd = fd;
		fds[0].events = POLLPRI;
		ret = poll(fds,1,-1);
		if(ret < 0){
			printf("poll error:%s\n",strerror(errno));
			break;
		}else
			printf("ret value=%d\n",fds[0].revents);
		read(fd,buff,4096);
		memset(buff ,0,4096);
	}
	close(fd);
Quoted 2 lines

I add read command and confirm read end of file /proc/mdstat. But this fution also to find only one event.

You missed this bit:

Quoted 2 lines

poll will only block again after you read to the end of the file (and thus observe any change), and then seek back to the start.

                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

NeilBrown