summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhunt <hunt>2007-11-01 19:19:33 +0000
committerhunt <hunt>2007-11-01 19:19:33 +0000
commit68e81635a3fd6d11f6e605995c72801c66305171 (patch)
tree3871759d4412aedebf85975ccfcedfe712613559
parentd47936fc8f3245d9f14797eb7bf2e876b3c37c99 (diff)
downloadsystemtap-steved-68e81635a3fd6d11f6e605995c72801c66305171.tar.gz
systemtap-steved-68e81635a3fd6d11f6e605995c72801c66305171.tar.xz
systemtap-steved-68e81635a3fd6d11f6e605995c72801c66305171.zip
2007-11-01 Martin Hunt <hunt@redhat.com>
* procfs.c, control.c, transport.c: Recognize when stapio is detached and disable delayed work. Enable when attached. Cleanup code to destroy workqueue on exit.
-rw-r--r--runtime/transport/ChangeLog6
-rw-r--r--runtime/transport/control.c17
-rw-r--r--runtime/transport/procfs.c14
-rw-r--r--runtime/transport/transport.c49
-rw-r--r--runtime/transport/transport.h1
5 files changed, 54 insertions, 33 deletions
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog
index 66811376..4872fa11 100644
--- a/runtime/transport/ChangeLog
+++ b/runtime/transport/ChangeLog
@@ -1,3 +1,9 @@
+2007-11-01 Martin Hunt <hunt@redhat.com>
+
+ * procfs.c, control.c, transport.c: Recognize when stapio
+ is detached and disable delayed work. Enable when attached.
+ Cleanup code to destroy workqueue on exit.
+
2007-10-12 Martin Hunt <hunt@redhat.com>
* transport.c (_stp_ask_for_symbols): Don't ask for
diff --git a/runtime/transport/control.c b/runtime/transport/control.c
index ae731659..7846572a 100644
--- a/runtime/transport/control.c
+++ b/runtime/transport/control.c
@@ -261,6 +261,8 @@ static int _stp_ctl_send (int type, void *data, int len)
} else {
while ((err = _stp_ctl_write(type, data, len)) < 0 && trylimit--)
msleep (5);
+ if (err > 0)
+ wake_up_interruptible(&_stp_ctl_wq);
}
kbug("returning %d\n", err);
return err;
@@ -368,26 +370,19 @@ static int _stp_sym_close_cmd (struct inode *inode, struct file *file)
return 0;
}
-static int _stp_ctl_opens = 0;
static int _stp_ctl_open_cmd (struct inode *inode, struct file *file)
{
- /* only allow one reader */
- if (_stp_ctl_opens)
+ if (_stp_attached)
return -1;
- _stp_ctl_opens++;
- _stp_pid = current->pid;
- utt_overwrite_flag = 0;
+ _stp_attach();
return 0;
}
static int _stp_ctl_close_cmd (struct inode *inode, struct file *file)
{
- if (_stp_ctl_opens)
- _stp_ctl_opens--;
- _stp_pid = 0;
- if (!_stp_exit_flag)
- utt_overwrite_flag = 1;
+ if (_stp_attached)
+ _stp_detach();
return 0;
}
diff --git a/runtime/transport/procfs.c b/runtime/transport/procfs.c
index 88740847..069e379e 100644
--- a/runtime/transport/procfs.c
+++ b/runtime/transport/procfs.c
@@ -324,6 +324,8 @@ static int _stp_ctl_send (int type, void *data, int len)
} else {
while ((err = _stp_ctl_write(type, data, len)) < 0 && trylimit--)
msleep (5);
+ if (err > 0)
+ wake_up_interruptible(&_stp_ctl_wq);
}
return err;
}
@@ -430,23 +432,19 @@ static int _stp_sym_close_cmd (struct inode *inode, struct file *file)
return 0;
}
-static int _stp_ctl_opens = 0;
static int _stp_ctl_open_cmd (struct inode *inode, struct file *file)
{
- /* only allow one reader */
- if (_stp_ctl_opens)
+ if (_stp_attached)
return -1;
- _stp_ctl_opens++;
- _stp_pid = current->pid;
+ _stp_attach();
return 0;
}
static int _stp_ctl_close_cmd (struct inode *inode, struct file *file)
{
- if (_stp_ctl_opens)
- _stp_ctl_opens--;
- _stp_pid = 0;
+ if (_stp_attached)
+ _stp_detach();
return 0;
}
diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
index d44d6851..0a959917 100644
--- a/runtime/transport/transport.c
+++ b/runtime/transport/transport.c
@@ -47,7 +47,8 @@ void probe_exit(void);
int probe_start(void);
void _stp_exit(void);
void _stp_handle_start (struct _stp_msg_start *st);
-
+static void _stp_detach(void);
+static void _stp_attach(void);
/* check for new workqueue API */
#ifdef DECLARE_DELAYED_WORK
@@ -115,6 +116,7 @@ static void _stp_cleanup_and_exit (int dont_rmmod)
if (!_stp_exit_called) {
int failures;
+ _stp_exit_flag = 1;
unregister_module_notifier(&_stp_module_load_nb);
/* we only want to do this stuff once */
@@ -142,6 +144,34 @@ static void _stp_cleanup_and_exit (int dont_rmmod)
}
/*
+ * Called when stapio closes the control channel.
+ */
+static void _stp_detach(void)
+{
+ kbug("detach\n");
+ _stp_attached = 0;
+ _stp_pid = 0;
+
+ if (!_stp_exit_flag)
+ utt_overwrite_flag = 1;
+
+ cancel_delayed_work(&_stp_work);
+ wake_up_interruptible(&_stp_ctl_wq);
+}
+
+/*
+ * Called when stapio opens the control channel.
+ */
+static void _stp_attach(void)
+{
+ kbug("attach\n");
+ _stp_attached = 1;
+ _stp_pid = current->pid;
+ utt_overwrite_flag = 0;
+ queue_delayed_work(_stp_wq, &_stp_work, STP_WORK_TIMER);
+}
+
+/*
* _stp_work_queue - periodically check for IO or exit
* This is run by a kernel thread and may sleep.
*/
@@ -162,12 +192,9 @@ static void _stp_work_queue (void *data)
wake_up_interruptible(&_stp_ctl_wq);
/* if exit flag is set AND we have finished with probe_start() */
- if (unlikely(_stp_exit_flag && _stp_start_finished)) {
+ if (unlikely(_stp_exit_flag && _stp_start_finished))
_stp_cleanup_and_exit(0);
- cancel_delayed_work(&_stp_work);
- flush_workqueue(_stp_wq);
- wake_up_interruptible(&_stp_ctl_wq);
- } else
+ else if (likely(_stp_attached))
queue_delayed_work(_stp_wq, &_stp_work, STP_WORK_TIMER);
}
@@ -179,18 +206,14 @@ static void _stp_work_queue (void *data)
*/
void _stp_transport_close()
{
- kbug("************** transport_close *************\n");
+ kbug("%d: ************** transport_close *************\n", current->pid);
_stp_cleanup_and_exit(1);
- cancel_delayed_work(&_stp_work);
destroy_workqueue(_stp_wq);
- wake_up_interruptible(&_stp_ctl_wq);
- unregister_module_notifier(&_stp_module_load_nb);
_stp_unregister_ctl_channel();
if (_stp_utt) utt_trace_remove(_stp_utt);
_stp_free_modules();
_stp_kill_time();
_stp_print_cleanup(); /* free print buffers */
-
kbug("---- CLOSED ----\n");
}
@@ -257,9 +280,7 @@ int _stp_transport_init(void)
_stp_wq = create_workqueue("systemtap");
if (!_stp_wq)
goto err3;
-
- queue_delayed_work(_stp_wq, &_stp_work, STP_WORK_TIMER);
-
+
/* request symbolic information */
_stp_ask_for_symbols();
return 0;
diff --git a/runtime/transport/transport.h b/runtime/transport/transport.h
index 0a83001e..6dc00d2b 100644
--- a/runtime/transport/transport.h
+++ b/runtime/transport/transport.h
@@ -26,4 +26,5 @@ int _stp_pid = 0;
uid_t _stp_uid = 0;
gid_t _stp_gid = 0;
pid_t _stp_init_pid = 0;
+int _stp_attached = 0;
#endif /* _TRANSPORT_TRANSPORT_H_ */