Initial Linux ZFS GIT Repo
[zfs.git] / scripts / profile-kpios.sh
1 #!/bin/bash
2 # profile-kpios.sh
3
4 trap "RUN_DONE=1" SIGHUP
5
6 RUN_PHASE=${1}
7 RUN_LOG_DIR=${2}
8 RUN_ID=${3}
9 RUN_DONE=0
10
11 POLL_INTERVAL=2.99
12
13 # Log these pids, the exact pid numbers will vary from system to system
14 # so I harvest pid for all the following type of processes from /proc/<pid>/
15 #
16 # zio_taskq/#
17 # spa_zio_issue/#
18 # spa_zio_intr/#
19 # txg_quiesce_thr
20 # txg_sync_thread
21 # txg_timelimit_t
22 # arc_reclaim_thr
23 # l2arc_feed_thre
24 # kpios_io/#
25
26 ZIO_TASKQ_PIDS=()
27 ZIO_REQ_NUL_PIDS=() 
28 ZIO_IRQ_NUL_PIDS=() 
29 ZIO_REQ_RD_PIDS=() 
30 ZIO_IRQ_RD_PIDS=() 
31 ZIO_REQ_WR_PIDS=() 
32 ZIO_IRQ_WR_PIDS=()
33 ZIO_REQ_FR_PIDS=() 
34 ZIO_IRQ_FR_PIDS=()
35 ZIO_REQ_CM_PIDS=() 
36 ZIO_IRQ_CM_PIDS=()
37 ZIO_REQ_CTL_PIDS=() 
38 ZIO_IRQ_CTL_PIDS=()
39
40 TXG_QUIESCE_PIDS=()
41 TXG_SYNC_PIDS=() 
42 TXG_TIMELIMIT_PIDS=()
43
44 ARC_RECLAIM_PIDS=()
45 L2ARC_FEED_PIDS=()
46
47 KPIOS_IO_PIDS=()
48
49 show_pids() {
50         echo "* zio_taskq:     { ${ZIO_TASKQ_PIDS[@]} } = ${#ZIO_TASKQ_PIDS[@]}"
51         echo "* zio_req_nul:   { ${ZIO_REQ_NUL_PIDS[@]} } = ${#ZIO_REQ_NUL_PIDS[@]}"
52         echo "* zio_irq_nul:   { ${ZIO_IRQ_NUL_PIDS[@]} } = ${#ZIO_IRQ_NUL_PIDS[@]}"
53         echo "* zio_req_rd:    { ${ZIO_REQ_RD_PIDS[@]} } = ${#ZIO_REQ_RD_PIDS[@]}"
54         echo "* zio_irq_rd:    { ${ZIO_IRQ_RD_PIDS[@]} } = ${#ZIO_IRQ_RD_PIDS[@]}"
55         echo "* zio_req_wr:    { ${ZIO_REQ_WR_PIDS[@]} } = ${#ZIO_REQ_WR_PIDS[@]}"
56         echo "* zio_irq_wr:    { ${ZIO_IRQ_WR_PIDS[@]} } = ${#ZIO_IRQ_WR_PIDS[@]}"
57         echo "* zio_req_fr:    { ${ZIO_REQ_FR_PIDS[@]} } = ${#ZIO_REQ_FR_PIDS[@]}"
58         echo "* zio_irq_fr:    { ${ZIO_IRQ_FR_PIDS[@]} } = ${#ZIO_IRQ_FR_PIDS[@]}"
59         echo "* zio_req_cm:    { ${ZIO_REQ_CM_PIDS[@]} } = ${#ZIO_REQ_CM_PIDS[@]}"
60         echo "* zio_irq_cm:    { ${ZIO_IRQ_CM_PIDS[@]} } = ${#ZIO_IRQ_CM_PIDS[@]}"
61         echo "* zio_req_ctl:   { ${ZIO_REQ_CTL_PIDS[@]} } = ${#ZIO_REQ_CTL_PIDS[@]}"
62         echo "* zio_irq_ctl:   { ${ZIO_IRQ_CTL_PIDS[@]} } = ${#ZIO_IRQ_CTL_PIDS[@]}"
63         echo "* txg_quiesce:   { ${TXG_QUIESCE_PIDS[@]} } = ${#TXG_QUIESCE_PIDS[@]}"
64         echo "* txg_sync:      { ${TXG_SYNC_PIDS[@]} } = ${#TXG_SYNC_PIDS[@]}"
65         echo "* txg_timelimit: { ${TXG_TIMELIMIT_PIDS[@]} } = ${#TXG_TIMELIMIT_PIDS[@]}"
66         echo "* arc_reclaim:   { ${ARC_RECLAIM_PIDS[@]} } = ${#ARC_RECLAIM_PIDS[@]}"
67         echo "* l2arc_feed:    { ${L2ARC_FEED_PIDS[@]} } = ${#L2ARC_FEED_PIDS[@]}"
68         echo "* kpios_io:      { ${KPIOS_IO_PIDS[@]} } = ${#KPIOS_IO_PIDS[@]}"
69 }
70
71 check_pid() {
72         local PID=$1
73         local NAME=$2
74         local TYPE=$3
75         local PIDS=( "$4" )
76         local NAME_STRING=`echo ${NAME} | cut -f1 -d'/'`
77         local NAME_NUMBER=`echo ${NAME} | cut -f2 -d'/'`
78
79         if [ "${NAME_STRING}" == "${TYPE}" ]; then
80                 if [ -n "${NAME_NUMBER}" ]; then
81                         PIDS[${NAME_NUMBER}]=${PID}
82                 else
83                         PIDS[${#PIDS[@]}]=${PID}
84
85                 fi
86         fi
87
88         echo "${PIDS[@]}"
89 }
90
91 # NOTE: This whole process is crazy slow but it will do for now
92 aquire_pids() {
93         echo "--- Aquiring ZFS pids ---"
94
95         for PID in `ls /proc/ | grep [0-9] | sort -n -u`; do
96                 if [ ! -e /proc/${PID}/status ]; then
97                         continue
98                 fi
99
100                 NAME=`cat /proc/${PID}/status  | head -n1 | cut -f2`
101
102                 ZIO_TASKQ_PIDS=( `check_pid ${PID} ${NAME} "zio_taskq" \
103                                  "$(echo "${ZIO_TASKQ_PIDS[@]}")"` )
104
105                 ZIO_REQ_NUL_PIDS=( `check_pid ${PID} ${NAME} "zio_req_nul" \
106                                    "$(echo "${ZIO_REQ_NUL_PIDS[@]}")"` )
107
108                 ZIO_IRQ_NUL_PIDS=( `check_pid ${PID} ${NAME} "zio_irq_nul" \
109                                    "$(echo "${ZIO_IRQ_NUL_PIDS[@]}")"` )
110
111                 ZIO_REQ_RD_PIDS=( `check_pid ${PID} ${NAME} "zio_req_rd" \
112                                    "$(echo "${ZIO_REQ_RD_PIDS[@]}")"` )
113
114                 ZIO_IRQ_RD_PIDS=( `check_pid ${PID} ${NAME} "zio_irq_rd" \
115                                    "$(echo "${ZIO_IRQ_RD_PIDS[@]}")"` )
116
117                 ZIO_REQ_WR_PIDS=( `check_pid ${PID} ${NAME} "zio_req_wr" \
118                                    "$(echo "${ZIO_REQ_WR_PIDS[@]}")"` )
119
120                 ZIO_IRQ_WR_PIDS=( `check_pid ${PID} ${NAME} "zio_irq_wr" \
121                                    "$(echo "${ZIO_IRQ_WR_PIDS[@]}")"` )
122
123                 ZIO_REQ_FR_PIDS=( `check_pid ${PID} ${NAME} "zio_req_fr" \
124                                    "$(echo "${ZIO_REQ_FR_PIDS[@]}")"` )
125
126                 ZIO_IRQ_FR_PIDS=( `check_pid ${PID} ${NAME} "zio_irq_fr" \
127                                    "$(echo "${ZIO_IRQ_FR_PIDS[@]}")"` )
128
129                 ZIO_REQ_CM_PIDS=( `check_pid ${PID} ${NAME} "zio_req_cm" \
130                                    "$(echo "${ZIO_REQ_CM_PIDS[@]}")"` )
131
132                 ZIO_IRQ_CM_PIDS=( `check_pid ${PID} ${NAME} "zio_irq_cm" \
133                                    "$(echo "${ZIO_IRQ_CM_PIDS[@]}")"` )
134
135                 ZIO_REQ_CTL_PIDS=( `check_pid ${PID} ${NAME} "zio_req_ctl" \
136                                    "$(echo "${ZIO_REQ_CTL_PIDS[@]}")"` )
137
138                 ZIO_IRQ_CTL_PIDS=( `check_pid ${PID} ${NAME} "zio_irq_ctl" \
139                                    "$(echo "${ZIO_IRQ_CTL_PIDS[@]}")"` )
140
141                 TXG_QUIESCE_PIDS=( `check_pid ${PID} ${NAME} "txg_quiesce" \
142                                    "$(echo "${TXG_QUIESCE_PIDS[@]}")"` )
143
144                 TXG_SYNC_PIDS=( `check_pid ${PID} ${NAME} "txg_sync" \
145                                 "$(echo "${TXG_SYNC_PIDS[@]}")"` )
146
147                 TXG_TIMELIMIT_PIDS=( `check_pid ${PID} ${NAME} "txg_timelimit" \
148                                      "$(echo "${TXG_TIMELIMIT_PIDS[@]}")"` )
149
150                 ARC_RECLAIM_PIDS=( `check_pid ${PID} ${NAME} "arc_reclaim" \
151                                      "$(echo "${ARC_RECLAIM_PIDS[@]}")"` )
152
153                 L2ARC_FEED_PIDS=( `check_pid ${PID} ${NAME} "l2arc_feed" \
154                                   "$(echo "${L2ARC_FEED_PIDS[@]}")"` )
155         done
156
157         # Wait for kpios_io threads to start
158         kill -s SIGHUP ${PPID}
159         echo "* Waiting for kpios_io threads to start"
160         while [ ${RUN_DONE} -eq 0 ]; do
161                 KPIOS_IO_PIDS=( `ps ax | grep kpios_io | grep -v grep | \
162                                  sed 's/^ *//g' | cut -f1 -d' '` )
163                 if [ ${#KPIOS_IO_PIDS[@]} -gt 0 ]; then
164                         break;
165                 fi
166                 sleep 0.1
167         done
168
169         echo "`show_pids`" >${RUN_LOG_DIR}/${RUN_ID}/pids.txt
170 }
171
172 log_pids() {
173         echo "--- Logging ZFS profile to ${RUN_LOG_DIR}/${RUN_ID}/ ---"
174         ALL_PIDS=( ${ZIO_TASKQ_PIDS[@]}     \
175                    ${ZIO_REQ_NUL_PIDS[@]}   \
176                    ${ZIO_IRQ_NUL_PIDS[@]}   \
177                    ${ZIO_REQ_RD_PID[@]}     \
178                    ${ZIO_IRQ_RD_PIDS[@]}    \
179                    ${ZIO_REQ_WR_PIDS[@]}    \
180                    ${ZIO_IRQ_WR_PIDS[@]}    \
181                    ${ZIO_REQ_FR_PIDS[@]}    \ 
182                    ${ZIO_IRQ_FR_PIDS[@]}    \
183                    ${ZIO_REQ_CM_PIDS[@]}    \ 
184                    ${ZIO_IRQ_CM_PIDS[@]}    \
185                    ${ZIO_REQ_CTL_PIDS[@]}   \
186                    ${ZIO_IRQ_CTL_PIDS[@]}   \
187                    ${TXG_QUIESCE_PIDS[@]}   \
188                    ${TXG_SYNC_PIDS[@]}      \
189                    ${TXG_TIMELIMIT_PIDS[@]} \
190                    ${ARC_RECLAIM_PIDS[@]}   \
191                    ${L2ARC_FEED_PIDS[@]}    \
192                    ${KPIOS_IO_PIDS[@]} )
193
194         while [ ${RUN_DONE} -eq 0 ]; do
195                 NOW=`date +%s.%N`
196                 LOG_PIDS="${RUN_LOG_DIR}/${RUN_ID}/pids-${NOW}"
197                 LOG_DISK="${RUN_LOG_DIR}/${RUN_ID}/disk-${NOW}"
198
199                 for PID in "${ALL_PIDS[@]}"; do
200                         if [ -z ${PID} ]; then
201                                 continue;
202                         fi
203
204                         if [ -e /proc/${PID}/stat ]; then
205                                 cat /proc/${PID}/stat | head -n1 >>${LOG_PIDS}
206                         else
207                                 echo "<${PID} exited>" >>${LOG_PIDS}
208                         fi
209                 done
210
211                 cat /proc/diskstats >${LOG_DISK}
212
213                 NOW2=`date +%s.%N`
214                 DELTA=`echo "${POLL_INTERVAL}-(${NOW2}-${NOW})" | bc`
215                 sleep ${DELTA}
216         done
217 }
218
219 aquire_pids
220 log_pids
221
222 exit 0