|
| 1 | +# Close |
| 2 | +# log stap_info right before connection being closed. |
| 3 | + |
| 4 | +%{ |
| 5 | + #include <net/tcp.h> |
| 6 | + #include <linux/timer.h> |
| 7 | + |
| 8 | + struct stap_info; |
| 9 | +%} |
| 10 | + |
| 11 | +/** |
| 12 | + * When a connection is closing. |
| 13 | + */ |
| 14 | +probe close.Close = |
| 15 | + kernel.function("tcp_set_state") |
| 16 | +{ |
| 17 | + if (!$sk || !$sk->sk_protinfo) |
| 18 | + next |
| 19 | + |
| 20 | + new_state = $state |
| 21 | + if (new_state == %{TCP_CLOSE%} || |
| 22 | + new_state == %{TCP_FIN_WAIT2%}) { |
| 23 | + if (!mem_is_stop()) { |
| 24 | + check_rst($sk, new_state) |
| 25 | + close_update($sk) |
| 26 | + |
| 27 | + if (filter_output($sk)) { |
| 28 | + /* Default */ |
| 29 | + log_conn_id($sk) |
| 30 | + log_trans($sk, new_state) |
| 31 | + log_cwnd_ssthr($sk) |
| 32 | + log_rtt_rto($sk) |
| 33 | + |
| 34 | + /* Optional */ |
| 35 | + log_retrans($sk) |
| 36 | + log_cong($sk) |
| 37 | + log_http($sk) |
| 38 | + printf("\n") |
| 39 | + } |
| 40 | + } |
| 41 | + |
| 42 | + mem_free($sk) |
| 43 | + } |
| 44 | +} |
| 45 | + |
| 46 | +function filter_output:long (sk:long) |
| 47 | +{ |
| 48 | + ret = 1 |
| 49 | + |
| 50 | + if (%{stap_options.bitmap & STAPF_HTTP%}) |
| 51 | + ret &= filter_http_transtime(sk) |
| 52 | + |
| 53 | + ret &= filter_conn_lifetime(sk) |
| 54 | + |
| 55 | + return ret |
| 56 | +} |
| 57 | + |
| 58 | +function filter_conn_lifetime:long (sk:long) |
| 59 | +{ |
| 60 | + return get_conn_lifetime(sk) >= %{stap_options.lifetime%} |
| 61 | +} |
| 62 | + |
| 63 | +function close_update(sk:long) |
| 64 | +{ |
| 65 | + cwnd_ssthr_update(sk) |
| 66 | + cong_close_update(sk) |
| 67 | +} |
| 68 | + |
| 69 | +function cwnd_ssthr_update(sk:long) |
| 70 | +%{ |
| 71 | + struct sock *sk = (struct sock *)STAP_ARG_sk; |
| 72 | + struct stap_info *info = sk->sk_protinfo; |
| 73 | + struct tcp_sock *tp = tcp_sk(sk); |
| 74 | + |
| 75 | + info->end_cwnd = tp->snd_cwnd; |
| 76 | + info->end_ssthr = tp->snd_ssthresh; |
| 77 | +%} |
| 78 | + |
| 79 | +/** |
| 80 | + * Make sure memory being freed in any condition. |
| 81 | + */ |
| 82 | +probe close.Destruct = |
| 83 | + kernel.function("inet_sock_destruct") |
| 84 | +{ |
| 85 | + if (!$sk->sk_protinfo) |
| 86 | + next |
| 87 | + |
| 88 | + mem_free($sk) |
| 89 | +} |
| 90 | + |
| 91 | +/** |
| 92 | + * Capture signal SIGINT and SIGTERM to quit. |
| 93 | + */ |
| 94 | +probe close.Signal = |
| 95 | + signal.send |
| 96 | +{ |
| 97 | + if (!mem_is_stop() && |
| 98 | + (sig_name == "SIGINT" || sig_name == "SIGTERM") |
| 99 | + && pid_name == "stapio") { |
| 100 | + mem_set_stop() |
| 101 | + mem_free_active() |
| 102 | + } |
| 103 | +} |
| 104 | + |
| 105 | +/** |
| 106 | + * Log ID of a connection. |
| 107 | + */ |
| 108 | +function log_conn_id (sk:long) |
| 109 | +{ |
| 110 | + tm_year = %{STAP_VALUE(STAP_ARG_sk, tm).tm_year%} |
| 111 | + tm_mon = %{STAP_VALUE(STAP_ARG_sk, tm).tm_mon%} |
| 112 | + tm_mday = %{STAP_VALUE(STAP_ARG_sk, tm).tm_mday%} |
| 113 | + tm_hour = %{STAP_VALUE(STAP_ARG_sk, tm).tm_hour%} |
| 114 | + tm_min = %{STAP_VALUE(STAP_ARG_sk, tm).tm_min%} |
| 115 | + tm_sec = %{STAP_VALUE(STAP_ARG_sk, tm).tm_sec%} |
| 116 | + isn = %{STAP_VALUE(STAP_ARG_sk, isn)%} |
| 117 | + |
| 118 | + time = sprintf("%d/%d/%d,start=%02d:%02d:%02d,end=%s", |
| 119 | + tm_year+1900, tm_mon+1, tm_mday, tm_hour, tm_min, tm_sec, |
| 120 | + get_short_time()) |
| 121 | + |
| 122 | + addr = get_socket_addr(sk) |
| 123 | + |
| 124 | + if (%{stap_options.detail_log%}) { |
| 125 | + line = "=====================================" |
| 126 | + printf("%s%s\n", line, line) |
| 127 | + printf("%s,id=%u\n%s\n\n", time, isn, addr) |
| 128 | + } else { |
| 129 | + printf("%s,%s,id=%u", time, addr, isn) |
| 130 | + } |
| 131 | +} |
| 132 | + |
| 133 | + |
0 commit comments