[DRBD-cvs] svn commit by phil - r2787 - trunk/drbd - Ok,
there was a race condition that could lead to this:
drbd-cvs at lists.linbit.com
drbd-cvs at lists.linbit.com
Tue Mar 6 17:19:45 CET 2007
Author: phil
Date: 2007-03-06 17:19:43 +0100 (Tue, 06 Mar 2007)
New Revision: 2787
Modified:
trunk/drbd/drbd_int.h
trunk/drbd/drbd_main.c
Log:
Ok, there was a race condition that could lead to this:
1) The receiver thread was for some reason restarting
itself.
2) Now someone issued the "drbdadm disconnect" command.
This state change hits the receiver thread after it
changed its state to "Unconneted".
3) The receiver thread exited then without setting
the connection state to "StandAlone".
4) The "drbdadm disconnect" hangs forever because we
never reached the "StandAlone" state.
Fixed all this, by having a two step procedure to stop
the receiver thread.
Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h 2007-03-05 17:00:43 UTC (rev 2786)
+++ trunk/drbd/drbd_int.h 2007-03-06 16:19:43 UTC (rev 2787)
@@ -923,6 +923,7 @@
enum chg_state_flags);
extern int drbd_thread_start(struct Drbd_thread *thi);
extern void _drbd_thread_stop(struct Drbd_thread *thi, int restart, int wait);
+extern void drbd_thread_signal(struct Drbd_thread *thi);
extern void drbd_free_resources(drbd_dev *mdev);
extern void tl_release(drbd_dev *mdev,unsigned int barrier_nr,
unsigned int set_size);
Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c 2007-03-05 17:00:43 UTC (rev 2786)
+++ trunk/drbd/drbd_main.c 2007-03-06 16:19:43 UTC (rev 2787)
@@ -1013,7 +1013,13 @@
resume_next_sg(mdev);
}
- if ( os.conn != Disconnecting && ns.conn <= Disconnecting ) {
+ // Receiver should clean up itself
+ if ( os.conn != Disconnecting && ns.conn == Disconnecting ) {
+ drbd_thread_signal(&mdev->receiver);
+ }
+
+ // Now the receiver finished cleaning up itself, it should die now
+ if ( os.conn != StandAlone && ns.conn == StandAlone ) {
drbd_thread_stop_nowait(&mdev->receiver);
}
@@ -1168,6 +1174,22 @@
}
}
+void drbd_thread_signal(struct Drbd_thread *thi)
+{
+ spin_lock(&thi->t_lock);
+
+ if (thi->t_state == None) {
+ spin_unlock(&thi->t_lock);
+ return;
+ }
+
+ if (thi->task != current) {
+ force_sig(DRBD_SIGKILL,thi->task);
+ }
+
+ spin_unlock(&thi->t_lock);
+}
+
/* the appropriate socket mutex must be held already */
int _drbd_send_cmd(drbd_dev *mdev, struct socket *sock,
Drbd_Packet_Cmd cmd, Drbd_Header *h,
More information about the drbd-cvs
mailing list