* (unknown), [not found] <201012251036232181820@gmail.com> @ 2010-12-25 2:49 ` kernel.majianpeng 2010-12-26 11:44 ` using poll on /proc/mdstat Neil Brown 0 siblings, 1 reply; 4+ messages in thread From: kernel.majianpeng @ 2010-12-25 2:49 UTC (permalink / raw) To: linux-raid 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 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: using poll on /proc/mdstat 2010-12-25 2:49 ` (unknown), kernel.majianpeng @ 2010-12-26 11:44 ` Neil Brown 2010-12-27 1:21 ` kernel.majianpeng 0 siblings, 1 reply; 4+ messages in thread From: Neil Brown @ 2010-12-26 11:44 UTC (permalink / raw) To: kernel.majianpeng; +Cc: linux-raid On Sat, 25 Dec 2010 10:49:02 +0800 "kernel.majianpeng" <kernel.majianpeng@gmail.com> wrote: > > > 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. 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. > 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. 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 > 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 majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Re: using poll on /proc/mdstat 2010-12-26 11:44 ` using poll on /proc/mdstat Neil Brown @ 2010-12-27 1:21 ` kernel.majianpeng 2010-12-27 6:27 ` Neil Brown 0 siblings, 1 reply; 4+ messages in thread From: kernel.majianpeng @ 2010-12-27 1:21 UTC (permalink / raw) To: Neil Brown; +Cc: linux-raid 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 On Sat, 25 Dec 2010 10:49:02 +0800 "kernel.majianpeng" <kernel.majianpeng@gmail.com> wrote: > > > 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. 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. > 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. 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 > 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 majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: using poll on /proc/mdstat 2010-12-27 1:21 ` kernel.majianpeng @ 2010-12-27 6:27 ` Neil Brown 0 siblings, 0 replies; 4+ messages in thread From: Neil Brown @ 2010-12-27 6:27 UTC (permalink / raw) To: kernel.majianpeng; +Cc: linux-raid On Mon, 27 Dec 2010 09:21:00 +0800 "kernel.majianpeng" <kernel.majianpeng@gmail.com> wrote: > 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. You missed this bit: > 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 ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-12-27 6:27 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <201012251036232181820@gmail.com> 2010-12-25 2:49 ` (unknown), kernel.majianpeng 2010-12-26 11:44 ` using poll on /proc/mdstat Neil Brown 2010-12-27 1:21 ` kernel.majianpeng 2010-12-27 6:27 ` Neil Brown
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).