Re: init scripts problems ?
"Peter T. Breuer" <[email protected]>
| Newsgroups | gmane.linux.enbd.general |
|---|---|
| Message-ID | <[email protected]> |
"Also sprach denis bonnenfant:"
> > This problem needs investigating! When you have the two clients stuck
> > like that please please please get the WCHAN field from ps! As far as I
> > recall, the stuck client is in a semaphore that I don't own! So what
> > can I do?
>
> Ok, just the time to retreive my server system config to a vmware box
> and i will try to reproduce exactly the problems. Just the matter of one
> or two days... As i'm quite busy too !
I've just checked the enbd_open() code and I see nothing suspicious
there _except_ maybe the "media check" that is launched in the kernel:
if (do_media_check) {
// PTB this invalidates buffers, if necessary
ENBD_INFO ("DISK CHECK wanted in open on device nd%s\n",
lo->devnam);
lo->last_checked = jiffies;
check_disk_change(inode->i_bdev);
}
It may be worth disabling that whole check and seeing what happens. As
I recall the kernel tries to read the partition table (the first
sectors) of the "disk" (enbd) and then adds the result to
/proc/partitions.
This is a bit of a race condition in itself, since on first opening by
the client, the enbd device hasn't got a client there and hence can't
ask the server for a sector. I think the race is solved by some fancy
code just above which checks if we are opening it in order to become
the client, or we are opening the device because we already are the
client, something that the kernel code can only tell by checking if we
have the pid of the client that opened the device first.
That code might be wrong. It's certainly the case that with two openers
close in time we might get throough this test both times:
if ((part == 0 || (slot->pid && slot->pid != current->pid))
&& lo->last_checked + timeout < jiffies) {
/*
* PTB induce a remote check and maybe invalidate
* device.
* This currently requires enbd_ioctl for remote
* ioctl support.
*/
do_media_check = 1;
}
I can't help wondering if that != might have been supposed to be an
==. IT SAYS the code only is activated if we are the first checker
(last checked = 0, surely less than jiffies), or it's been a long while
since the media was checked. But the check condition is that either
we're opening the full device (and thus we're a master client daemon) or
we're opening a minor device (and hence we're a slave client daemon) but
not the slave client daemon that is assigned to that minor (which has
already registered).
Weird. Would it make more sense with an ==?
I suspect that that check_disk_change(inode->i_bdev) is mandated by the
kernel for some reason, or no requests will ever be let through. But
the times when it is done or should be done are bscure.
There is definitely some kind of race POSSIBLE. The media check sets te
last_checked time.
One might investigate the result of turning that code to either ALWAYS
do (on open), or always not do. I.e. setting do_media_check to 1 or 0
withut thinking.
But I'm not even sure the code sticks in OPEN, rather than at the first
read. The WCHAN value might indicate.
Peter