Skip to content

Instantly share code, notes, and snippets.

@ethercflow
Last active May 28, 2018 16:41
Show Gist options
  • Select an option

  • Save ethercflow/68eeda5bdda610f9594d800b3222bdc7 to your computer and use it in GitHub Desktop.

Select an option

Save ethercflow/68eeda5bdda610f9594d800b3222bdc7 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
import logging
import os
import signal
import threading
def parse_opts():
parser = argparse.ArgumentParser(prog='iodelay')
parser.add_argument('--dev', help='dev' )
parser.add_argument('--base', type = int, help='delay')
parser.add_argument('--step', type = int, help='step')
parser.add_argument('--cycle', type = int, help='cycle')
parser.add_argument('--type', choices='rw', help='rdelay or wdelay')
subparsers = parser.add_subparsers(help='sub-command help')
parser_inc = subparsers.add_parser('inc', help='inc iodelay')
parser_inc.set_defaults(func=inc)
parser_dec = subparsers.add_parser('dec', help='dec iodelay')
parser_dec.set_defaults(func=dec)
return parser.parse_args()
rsrc = '''global inject
probe procfs("rinject").write {
inject = $value;
}
probe vfs.read.return {
if (inject == "off\\n") {
exit();
}
if ($return && devname == @1) {
udelay($2);
}
}
'''
wsrc = '''global inject
probe procfs("winject").write {
inject = $value;
}
probe vfs.write.return {
if (inject == "off\\n") {
exit();
}
if ($return && devname == @1) {
udelay($2);
}
}
'''
with open('ridd.stp', 'w') as f:
f.write(rsrc)
with open('widd.stp', 'w') as f:
f.write(wsrc)
item = 'widd'
wctl = "/proc/systemtap/widd/winject"
rctr = "/proc/systemtap/ridd/rinject"
def inc(args):
global item
global wctl
global rctl
ctr = wctr
if args.type == 'r':
item = "ridd"
ctl = rctl
run(args.cycle, item, args.dev, args.base, args.step, ctl)
def dec(args):
global item
global wctl
global rctl
ctl = wctl
if args.type == 'r':
item = "ridd"
ctl = rctr
run(args.cycle, item, args.dev, args.base, -args.step, ctl)
def run(cycle, item, dev, delay, step, ctl):
os.system('echo off|sudo tee %s' % ctl)
cmd1 = 'sudo stap -p4 -DMAXSKIPPED=9999 -m %s -g %s %s %s' % (item, '%s.stp' % item, dev, delay)
logging.info(cmd1)
ret = os.system(cmd1) != 0
if ret != 0:
logging.fatal(cmd1)
exit(1)
cmd2 = 'sudo staprun %s.ko &' % item
logging.info(cmd2)
ret = os.system(cmd2) != 0
if ret != 0:
logging.fatal(cmd2)
exit(1)
delay += step
if delay < 0:
delay = 0
t = threading.Timer(cycle, run, (cycle, item, dev, delay, step, ctl))
t.start()
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
args = parse_opts()
args.func(args)
@ethercflow
Copy link
Copy Markdown
Author

eg:

./iodelay.py --dev sda3 --base 10 --step 1 --cycle 1 --type=w dec
./iodelay.py --dev sda3 --base 10 --step 1 --cycle 1 --type=r inc

参数说明:

  1. dev是分区名称;
  2. base是初始延迟;
  3. step是延迟变化步长;
  4. cycle是变化周期,单位是s;
  5. type只有两个选择,w代表写延迟,r代表读延迟;
  6. dec是周期性减少,inc是周期性增。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment