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