3 # The MIT License (MIT)
5 # Copyright (C) 2015 - Julien Desfossez <jdesfossez@efficios.com>
7 # Permission is hereby granted, free of charge, to any person obtaining a copy
8 # of this software and associated documentation files (the "Software"), to deal
9 # in the Software without restriction, including without limitation the rights
10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 # copies of the Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
14 # The above copyright notice and this permission notice shall be included in
15 # all copies or substantial portions of the Software.
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 from linuxautomaton
import sp
, sv
, common
28 class BlockStateProvider(sp
.StateProvider
):
29 def __init__(self
, state
):
31 self
.cpus
= state
.cpus
32 self
.disks
= state
.disks
33 self
.tids
= state
.tids
34 self
.remap_requests
= []
36 'block_rq_complete': self
._process
_block
_rq
_complete
,
37 'block_rq_issue': self
._process
_block
_rq
_issue
,
38 'block_bio_remap': self
._process
_block
_bio
_remap
,
39 'block_bio_backmerge': self
._process
_block
_bio
_backmerge
,
41 self
._register
_cbs
(cbs
)
43 def process_event(self
, ev
):
44 self
._process
_event
_cb
(ev
)
46 def _process_block_bio_remap(self
, event
):
48 sector
= event
["sector"]
49 old_dev
= event
["old_dev"]
50 old_sector
= event
["old_sector"]
52 for req
in self
.remap_requests
:
53 if req
["dev"] == old_dev
and req
["sector"] == old_sector
:
55 req
["sector"] = sector
59 req
["orig_dev"] = old_dev
61 req
["sector"] = sector
62 self
.remap_requests
.append(req
)
64 # For backmerge requests, just remove the request from the
65 # remap_requests queue, because we rely later on the nr_sector
66 # which has all the info we need.
67 def _process_block_bio_backmerge(self
, event
):
69 sector
= event
["sector"]
70 for req
in self
.remap_requests
:
71 if req
["dev"] == dev
and req
["sector"] == sector
:
72 self
.remap_requests
.remove(req
)
74 def _process_block_rq_issue(self
, event
):
76 sector
= event
["sector"]
77 nr_sector
= event
["nr_sector"]
78 # Note: since we don't know, we assume a sector is 512 bytes
84 rq
["nr_sector"] = nr_sector
85 rq
["rq_time"] = event
.timestamp
86 rq
["iorequest"] = sv
.IORequest()
87 rq
["iorequest"].iotype
= sv
.IORequest
.IO_BLOCK
88 rq
["iorequest"].begin
= event
.timestamp
89 rq
["iorequest"].size
= nr_sector
* block_size
92 for req
in self
.remap_requests
:
93 if req
["dev"] == dev
and req
["sector"] == sector
:
94 d
= common
.get_disk(req
["orig_dev"], self
.disks
)
96 d
= common
.get_disk(dev
, self
.disks
)
99 d
.nr_sector
+= nr_sector
100 d
.pending_requests
[sector
] = rq
102 if "tid" in event
.keys():
104 if tid
not in self
.tids
:
110 if p
.pid
!= -1 and p
.tid
!= p
.pid
:
113 # even rwbs means read, odd means write
114 if event
["rwbs"] % 2 == 0:
115 p
.block_read
+= nr_sector
* block_size
116 rq
["iorequest"].operation
= sv
.IORequest
.OP_READ
118 p
.block_write
+= nr_sector
* block_size
119 rq
["iorequest"].operation
= sv
.IORequest
.OP_WRITE
121 def _process_block_rq_complete(self
, event
):
123 sector
= event
["sector"]
124 nr_sector
= event
["nr_sector"]
129 for req
in self
.remap_requests
:
130 if req
["dev"] == dev
and req
["sector"] == sector
:
131 d
= common
.get_disk(req
["orig_dev"], self
.disks
)
132 self
.remap_requests
.remove(req
)
135 d
= common
.get_disk(dev
, self
.disks
)
137 # ignore the completion of requests we didn't see the issue
138 # because it would mess up the latency totals
139 if sector
not in d
.pending_requests
.keys():
142 rq
= d
.pending_requests
[sector
]
143 if rq
["nr_sector"] != nr_sector
:
145 d
.completed_requests
+= 1
146 if rq
["rq_time"] > event
.timestamp
:
147 print("Weird request TS", event
.timestamp
)
148 time_per_sector
= (event
.timestamp
- rq
["rq_time"]) / rq
["nr_sector"]
149 d
.request_time
+= time_per_sector
150 rq
["iorequest"].duration
= time_per_sector
151 rq
["iorequest"].end
= event
.timestamp
152 d
.rq_list
.append(rq
["iorequest"])
153 if "pid" in rq
.keys():
154 rq
["pid"].iorequests
.append(rq
["iorequest"])
155 del d
.pending_requests
[sector
]
157 def dump_orphan_requests(self
):
158 for req
in self
.remap_requests
:
159 print("Orphan : %d : %d %d" % (req
["orig_dev"], req
["dev"],
This page took 0.040914 seconds and 5 git commands to generate.