connector: Added coredumping event to the process connector
authorJesper Derehag <jderehag@hotmail.com>
Tue, 19 Mar 2013 20:50:05 +0000 (20:50 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 20 Mar 2013 17:23:21 +0000 (13:23 -0400)
Process connector can now also detect coredumping events.

Main aim of patch is get notified at start of coredumping, instead of
having to wait for it to finish and then being notified through EXIT
event.

Could be used for instance by process-managers that want to get
notified as soon as possible about process failures, and not
necessarily beeing notified after coredump, which could be in the
order of minutes depending on size of coredump, piping and so on.

Signed-off-by: Jesper Derehag <jderehag@hotmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/connector/cn_proc.c
include/linux/cn_proc.h
include/uapi/linux/cn_proc.h
kernel/signal.c

index 1110478dd0fdb83b6bbdbae5fa1f40c0a2406655..08ae128cce9be2e930454088c1041478bce8d8f5 100644 (file)
@@ -232,6 +232,31 @@ void proc_comm_connector(struct task_struct *task)
        cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
 }
 
+void proc_coredump_connector(struct task_struct *task)
+{
+       struct cn_msg *msg;
+       struct proc_event *ev;
+       __u8 buffer[CN_PROC_MSG_SIZE];
+       struct timespec ts;
+
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+
+       msg = (struct cn_msg *)buffer;
+       ev = (struct proc_event *)msg->data;
+       get_seq(&msg->seq, &ev->cpu);
+       ktime_get_ts(&ts); /* get high res monotonic timestamp */
+       put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
+       ev->what = PROC_EVENT_COREDUMP;
+       ev->event_data.coredump.process_pid = task->pid;
+       ev->event_data.coredump.process_tgid = task->tgid;
+
+       memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+       msg->ack = 0; /* not used */
+       msg->len = sizeof(*ev);
+       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
 void proc_exit_connector(struct task_struct *task)
 {
        struct cn_msg *msg;
index 2c1bc1ea04ee05471bb536ccdd8ed6a8cf2fbc3c..1d5b02a96c46304b7821c498e179a67c534263bd 100644 (file)
@@ -26,6 +26,7 @@ void proc_id_connector(struct task_struct *task, int which_id);
 void proc_sid_connector(struct task_struct *task);
 void proc_ptrace_connector(struct task_struct *task, int which_id);
 void proc_comm_connector(struct task_struct *task);
+void proc_coredump_connector(struct task_struct *task);
 void proc_exit_connector(struct task_struct *task);
 #else
 static inline void proc_fork_connector(struct task_struct *task)
@@ -48,6 +49,9 @@ static inline void proc_ptrace_connector(struct task_struct *task,
                                         int ptrace_id)
 {}
 
+static inline void proc_coredump_connector(struct task_struct *task)
+{}
+
 static inline void proc_exit_connector(struct task_struct *task)
 {}
 #endif /* CONFIG_PROC_EVENTS */
index 0d7b49973bb35451254d51d2d24645588678af2e..f6c271035bbd2c5eb6deb10cf89b04b6fa0f710a 100644 (file)
@@ -56,7 +56,9 @@ struct proc_event {
                PROC_EVENT_PTRACE = 0x00000100,
                PROC_EVENT_COMM = 0x00000200,
                /* "next" should be 0x00000400 */
-               /* "last" is the last process event: exit */
+               /* "last" is the last process event: exit,
+                * while "next to last" is coredumping event */
+               PROC_EVENT_COREDUMP = 0x40000000,
                PROC_EVENT_EXIT = 0x80000000
        } what;
        __u32 cpu;
@@ -110,11 +112,17 @@ struct proc_event {
                        char           comm[16];
                } comm;
 
+               struct coredump_proc_event {
+                       __kernel_pid_t process_pid;
+                       __kernel_pid_t process_tgid;
+               } coredump;
+
                struct exit_proc_event {
                        __kernel_pid_t process_pid;
                        __kernel_pid_t process_tgid;
                        __u32 exit_code, exit_signal;
                } exit;
+
        } event_data;
 };
 
index dd72567767d963ccb8ac2f3cfa4a824fa5f81b4e..497330ec2ae948d707553824f7bb3b9b780d9065 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/user_namespace.h>
 #include <linux/uprobes.h>
 #include <linux/compat.h>
+#include <linux/cn_proc.h>
 #define CREATE_TRACE_POINTS
 #include <trace/events/signal.h>
 
@@ -2350,6 +2351,7 @@ relock:
                if (sig_kernel_coredump(signr)) {
                        if (print_fatal_signals)
                                print_fatal_signal(info->si_signo);
+                       proc_coredump_connector(current);
                        /*
                         * If it was able to dump core, this kills all
                         * other threads in the group and synchronizes with