Linux dia manana fitaovana be dia be amin'ny debugging ny kernel sy ny fampiharana. Ny ankamaroan'izy ireo dia misy fiantraikany ratsy amin'ny fampiharana fampiharana ary tsy azo ampiasaina amin'ny famokarana.
Roa taona lasa izay dia nisy
Efa misy fitaovana fampiharana maro izay mampiasa eBPF, ary ato amin'ity lahatsoratra ity dia hojerentsika ny fomba hanoratana ny mombamomba anao manokana mifototra amin'ny tranomboky.
Miadana i Ceph
Nampiana mpampiantrano vaovao ao amin'ny cluster Ceph. Taorian'ny nifindrany ny angon-drakitra sasany ho azy, dia tsikaritray fa ambany lavitra noho ny amin'ny lohamilina hafa ny hafainganam-pandehan'ny fanodinana ny fangatahana fanoratana ataon'izy io.
Tsy toy ny sehatra hafa, ity mpampiantrano ity dia nampiasa bcache sy ny kernel linux 4.15 vaovao. Ity no fotoana voalohany nampiasana an'ity tefy ity teto. Ary tamin'izany fotoana izany dia nazava fa ny fototry ny olana dia mety ho na inona na inona.
Fanadihadiana ny Mpampiasa
Andeha isika hanomboka amin'ny fijerena izay mitranga ao anatin'ny dingana ceph-osd. Ho an'ity dia hampiasaintsika
Ny sary dia milaza amintsika fa ny asa fdatasync() nandany fotoana be nandefa fangatahana ho an'ny asa generic_make_request(). Midika izany fa mety ho any ivelan'ny daemon osd mihitsy no mahatonga ny olana. Ity dia mety ho kernel na disks. Ny vokatra iostat dia nampiseho fahatarana ambony amin'ny fanodinana fangatahana amin'ny kapila bcache.
Rehefa nanamarina ny mpampiantrano izahay dia nahita fa ny daemon systemd-udevd dia mandany fotoana betsaka amin'ny CPU - eo amin'ny 20% amin'ny cores maromaro. Fihetsika hafahafa izany, ka mila fantarinao ny antony. Satria miara-miasa amin'ny uevents ny Systemd-udevd, dia nanapa-kevitra ny hijery azy ireo izahay udevadm monitor. Hita fa be dia be ny hetsika fanovana natao ho an'ny fitaovana sakana tsirairay ao amin'ny rafitra. Hafahafa ihany izany, ka tsy maintsy hojerentsika izay mahatonga ireo hetsika rehetra ireo.
Mampiasa ny BCC Toolkit
Araka ny efa hitantsika, ny kernel (sy ny daemon ceph ao amin'ny rafitra antso) dia mandany fotoana be generic_make_request(). Andeha hojerentsika ny hafainganam-pandehan'ity asa ity. IN
Ity fampiasa ity matetika dia miasa haingana. Ny hany ataony dia ny mandefa ny fangatahana amin'ny filaharana mpamily fitaovana.
Bcache dia fitaovana sarotra izay misy kapila telo tokoa:
- fitaovana fanohanana (kapila cached), amin'ity tranga ity dia HDD miadana;
- fitaovana caching (kapila caching), ity dia fizarana iray amin'ny fitaovana NVMe;
- ny fitaovana virtoaly bcache izay iasan'ny fampiharana.
Fantatray fa miadana ny fandefasana fangatahana, fa ho an'iza amin'ireo fitaovana ireo? Hiatrika izany isika aoriana kely.
Fantatray izao fa mety hiteraka olana ny uevents. Tsy mora ny fitadiavana izay tena mahatonga ny taranany. Andeha hatao hoe karazana logiciel atomboka tsindraindray ity. Andeha hojerentsika hoe karazana rindrambaiko mandeha amin'ny rafitra mampiasa script execsnoop avy amin'ny mitovy
Ohatra toy izao:
/usr/share/bcc/tools/execsnoop | tee ./execdump
Tsy hampiseho ny vokatra feno an'ny execsnoop eto izahay, fa ny andalana iray mahaliana anay dia toy izao:
sh 1764905 5802 0 sudo arcconf getconfig 1 AD | grep Temperature | awk -F '[:/]' '{print $2}' | sed 's/^ ([0-9]*) C.*/1/'
Ny tsanganana fahatelo dia ny PPID (PID ray aman-dreny) amin'ny dingana. Ny dingana miaraka amin'ny PID 5802 dia nanjary iray amin'ireo kofehy amin'ny rafitra fanaraha-maso. Rehefa nanamarina ny fanamafisana ny rafitra fanaraha-maso dia hita ny masontsivana diso. Ny hafanan'ny adaptatera HBA dia nalaina isaky ny 30 segondra, izay matetika kokoa noho ny ilaina. Taorian'ny nanovany ny elanelam-potoana fanamarinana ho lava kokoa, dia hitanay fa tsy nisongadina intsony ny faharetan'ny fanodinana fangatahana amin'ity mpampiantrano ity raha oharina amin'ireo mpampiantrano hafa.
Saingy mbola tsy mazava ny antony nahatonga ilay fitaovana bcache miadana. Nanomana sehatra fitsapana miaraka amin'ny fandrindrana mitovy izahay ary nanandrana namerina ny olana tamin'ny alΓ lan'ny fampandehanana fio amin'ny bcache, mandeha tsindraindray ny trigger udevadm mba hamoronana uevents.
Manoratra Fitaovana Miorina amin'ny BCC
Andao hiezaka hanoratra fitaovana tsotra hanohizana sy hanehoana ireo antso miadana indrindra generic_make_request(). Mahaliana ihany koa ny anaran'ny fiara izay niantsoana an'io fiasa io.
Tsotra ny drafitra:
- hisoratra anarana kprobe amin'ny generic_make_request():
- Tehirizo ao anaty fitadidiana ny anaran'ny kapila, azo idirana amin'ny alΓ lan'ny tohan-kevitra fiasa;
- Tehirizinay ny mari-pamantarana.
- hisoratra anarana kretprobe ho fiverenana avy generic_make_request():
- Mahazo ny mari-pamantarana amin'izao fotoana izao izahay;
- Mitady ny mari-pamantarana voatahiry izahay ary mampitaha izany amin'ny ankehitriny;
- Raha lehibe noho ilay voatondro ny vokatra, dia hitantsika ny anaran'ny kapila voatahiry ary asehoy eo amin'ny terminal.
Kprobes ΠΈ kretprobes mampiasa mekanika breakpoint hanova ny kaody fampiasa amin'ny lalitra. Afaka mamaky ianao
Ny lahatsoratra eBPF ao anatin'ny script python dia toy izao:
bpf_text = βββ # Here will be the bpf program code βββ
Mba hifanakalozana angon-drakitra eo amin'ny fiasa dia mampiasa programa eBPF
struct data_t {
u64 pid;
u64 ts;
char comm[TASK_COMM_LEN];
u64 lat;
char disk[DISK_NAME_LEN];
};
BPF_HASH(p, u64, struct data_t);
BPF_PERF_OUTPUT(events);
Eto isika dia manoratra tabilao hash antsoina hoe p, miaraka amin'ny karazana fanalahidy u64 ary sanda iray karazana struct data_t. Ny tabilao dia ho hita ao anatin'ny tontolon'ny programa BPF. Ny macro BPF_PERF_OUTPUT dia manoratra tabilao hafa antsoina zava-mitranga, izay ampiasaina amin'ny
Rehefa mandrefy ny fahatarana eo anelanelan'ny fiantsoana asa iray sy ny fiverenana avy aminy, na eo anelanelan'ny fiantsoana amin'ny asa samihafa, dia mila raisinao fa ny angon-drakitra voaray dia tsy maintsy mifanaraka amin'ny contexte iray ihany. Raha lazaina amin'ny teny hafa, mila mitadidy momba ny mety ho fanombohana parallèle ny asa. Manana fahafahana mandrefy ny elanelam-potoana eo anelanelan'ny fiantsoana asa iray ao anatin'ny tontolon'ny dingana iray sy ny fiverenana avy amin'io fiasa io ao anatin'ny tontolon'ny dingana iray hafa isika, saingy azo inoana fa tsy misy ilà na azy izany. Ohatra tsara eto
Manaraka, mila manoratra ny kaody izay handeha isika rehefa antsoina hoe ny asa eo ambany fianarana:
void start(struct pt_regs *ctx, struct bio *bio) {
u64 pid = bpf_get_current_pid_tgid();
struct data_t data = {};
u64 ts = bpf_ktime_get_ns();
data.pid = pid;
data.ts = ts;
bpf_probe_read_str(&data.disk, sizeof(data.disk), (void*)bio->bi_disk->disk_name);
p.update(&pid, &data);
}
Eto ny hevitra voalohany amin'ny asa antsoina dia hosoloina ho toy ny hevitra faharoa
Ity asa manaraka ity dia hantsoina rehefa miverina avy generic_make_request():
void stop(struct pt_regs *ctx) {
u64 pid = bpf_get_current_pid_tgid();
u64 ts = bpf_ktime_get_ns();
struct data_t* data = p.lookup(&pid);
if (data != 0 && data->ts > 0) {
bpf_get_current_comm(&data->comm, sizeof(data->comm));
data->lat = (ts - data->ts)/1000;
if (data->lat > MIN_US) {
FACTOR
data->pid >>= 32;
events.perf_submit(ctx, data, sizeof(struct data_t));
}
p.delete(&pid);
}
}
Ity fiasa ity dia mitovy amin'ny teo aloha: hitantsika ny PID amin'ny dingana sy ny fe-potoana, fa tsy manome fahatsiarovana ho an'ny rafitra data vaovao. Fa kosa, mikaroka ny latabatra hash isika amin'ny rafitra efa misy amin'ny fampiasana ny lakile == PID ankehitriny. Raha hita ny rafitra, dia hitantsika ny anaran'ny dingana mihazakazaka ary ampio izany.
Ny fiovan'ny binary ampiasaintsika eto dia ilaina hahazoana ny kofehy GID. ireo. PID ny dingana lehibe izay nanomboka ny kofehy amin'ny toe-javatra iasanay. Ny asa antsoinay
Rehefa mivoaka amin'ny terminal isika dia tsy liana amin'ny kofehy amin'izao fotoana izao, fa liana amin'ny dingana lehibe. Aorian'ny fampitahana ny fahatarana aterak'izany amin'ny tokonam-baravarana iray dia mandalo ny rafitray izahay tahirin-kevitra mankany amin'ny habaka mpampiasa amin'ny alΓ lan'ny latabatra zava-mitranga, avy eo dia mamafa ny fidirana amin'ny p.
Ao amin'ny script python izay hampiditra an'io kaody io dia mila manolo ny MIN_US sy FACTOR miaraka amin'ny tokonam-baravaran'ny fanemorana sy ny fe-potoana isika, izay handalo ny tohan-kevitra:
bpf_text = bpf_text.replace('MIN_US',str(min_usec))
if args.milliseconds:
bpf_text = bpf_text.replace('FACTOR','data->lat /= 1000;')
label = "msec"
else:
bpf_text = bpf_text.replace('FACTOR','')
label = "usec"
Ankehitriny dia mila manomana ny programa BPF amin'ny alΓ lan'ny
b = BPF(text=bpf_text)
b.attach_kprobe(event="generic_make_request",fn_name="start")
b.attach_kretprobe(event="generic_make_request",fn_name="stop")
Tsy maintsy hamaritra ihany koa isika struct data_t ao amin'ny scripty, raha tsy izany dia tsy ho afaka hamaky na inona na inona izahay:
TASK_COMM_LEN = 16 # linux/sched.h
DISK_NAME_LEN = 32 # linux/genhd.h
class Data(ct.Structure):
_fields_ = [("pid", ct.c_ulonglong),
("ts", ct.c_ulonglong),
("comm", ct.c_char * TASK_COMM_LEN),
("lat", ct.c_ulonglong),
("disk",ct.c_char * DISK_NAME_LEN)]
Ny dingana farany dia ny famoahana data amin'ny terminal:
def print_event(cpu, data, size):
global start
event = ct.cast(data, ct.POINTER(Data)).contents
if start == 0:
start = event.ts
time_s = (float(event.ts - start)) / 1000000000
print("%-18.9f %-16s %-6d %-1s %s %s" % (time_s, event.comm, event.pid, event.lat, label, event.disk))
b["events"].open_perf_buffer(print_event)
# format output
start = 0
while 1:
try:
b.perf_buffer_poll()
except KeyboardInterrupt:
exit()
Ny script mihitsy dia hita ao amin'ny
Farany! Hitantsika izao fa ny toa ny fitaovana bcache miato dia antso miato generic_make_request() ho an'ny kapila misy cache.
Hiverina any amin'ny Kernel
Inona marina no miadana mandritra ny fandefasana fangatahana? Hitantsika fa mitranga ny fahatarana na dia alohan'ny hanombohan'ny kaonty fangatahana aza, i.e. tsy mbola nanomboka ny kaonty fangatahana manokana momba ny famoahana antontan'isa momba izany (/proc/diskstats na iostat). Azo hamarinina mora foana izany amin'ny alΓ lan'ny fampandehanana iostat rehefa mamerina ny olana, na
Raha jerena ny asa generic_make_request(), dia ho hitantsika fa alohan'ny hanombohan'ny fitakiana kaonty dia misy asa roa hafa antsoina. Voalohany - generic_make_request_checks(), manao fisavana ny maha-ara-dalΓ na ny fangatahana momba ny firafitry ny kapila. Faharoa -
ret = wait_event_interruptible(q->mq_freeze_wq,
(atomic_read(&q->mq_freeze_depth) == 0 &&
(preempt || !blk_queue_preempt_only(q))) ||
blk_queue_dying(q));
Ao anatin'izany, ny kernel dia miandry ny filaharana tsy hivaingana. Andeha horefesina ny fahatarana blk_queue_enter():
~# /usr/share/bcc/tools/funclatency blk_queue_enter -i 1 -m
Tracing 1 functions for "blk_queue_enter"... Hit Ctrl-C to end.
msecs : count distribution
0 -> 1 : 341 |****************************************|
msecs : count distribution
0 -> 1 : 316 |****************************************|
msecs : count distribution
0 -> 1 : 255 |****************************************|
2 -> 3 : 0 | |
4 -> 7 : 0 | |
8 -> 15 : 1 | |
Toa efa akaiky vahaolana isika. Ny fiasa ampiasaina hanamafisana / hanalana filaharana dia
Ny fotoana ilaina hanesorana an'io filaharana io dia mitovy amin'ny fahatarana kapila satria miandry ny famitana ny asa milahatra rehetra ny kernel. Rehefa foana ny filaharana dia ampiharina ny fanovana fanovana. Aorian'izay no iantsoana azy
Efa ampy ny fahafantarantsika izao mba hanitsiana ny toe-javatra. Ny baikon'ny trigger udevadm dia mahatonga ny firafitry ny fitaovana fanakanana hampiharina. Ireo toe-javatra ireo dia voalaza ao amin'ny fitsipika udev. Hitantsika hoe inona ny toe-javatra manamaivana ny filaharana amin'ny fiezahana hanova azy ireo amin'ny alΓ lan'ny sysfs na amin'ny fijerena ny code source kernel. Azontsika atao koa ny manandrana ny BCC utility
~# /usr/share/bcc/tools/trace blk_freeze_queue -K -U
PID TID COMM FUNC
3809642 3809642 systemd-udevd blk_freeze_queue
blk_freeze_queue+0x1 [kernel]
elevator_switch+0x29 [kernel]
elv_iosched_store+0x197 [kernel]
queue_attr_store+0x5c [kernel]
sysfs_kf_write+0x3c [kernel]
kernfs_fop_write+0x125 [kernel]
__vfs_write+0x1b [kernel]
vfs_write+0xb8 [kernel]
sys_write+0x55 [kernel]
do_syscall_64+0x73 [kernel]
entry_SYSCALL_64_after_hwframe+0x3d [kernel]
__write_nocancel+0x7 [libc-2.23.so]
[unknown]
3809631 3809631 systemd-udevd blk_freeze_queue
blk_freeze_queue+0x1 [kernel]
queue_requests_store+0xb6 [kernel]
queue_attr_store+0x5c [kernel]
sysfs_kf_write+0x3c [kernel]
kernfs_fop_write+0x125 [kernel]
__vfs_write+0x1b [kernel]
vfs_write+0xb8 [kernel]
sys_write+0x55 [kernel]
do_syscall_64+0x73 [kernel]
entry_SYSCALL_64_after_hwframe+0x3d [kernel]
__write_nocancel+0x7 [libc-2.23.so]
[unknown]
Mahalana no miova ny fitsipiky ny Udev ary matetika izany dia mitranga amin'ny fomba voafehy. Noho izany dia hitantsika fa na dia ny fampiharana ireo soatoavina efa napetraka aza dia miteraka fiakarana amin'ny fanemorana ny famindrana ny fangatahana avy amin'ny fampiharana mankany amin'ny disk. Mazava ho azy fa tsy fomba fanao tsara ny famoronana hetsika udev rehefa tsy misy fiovana eo amin'ny firafitry ny kapila (ohatra, ny fitaovana dia tsy mipetaka / tapaka). Na izany aza, afaka manampy ny kernel tsy hanao asa tsy ilaina isika ary hanamaivana ny filaharana fangatahana raha tsy ilaina izany.
Famaranana
Ny eBPF dia fitaovana tena malefaka sy matanjaka. Tao amin'ny lahatsoratra dia nijery tranga iray azo ampiharina izahay ary nampiseho ampahany kely amin'izay azo atao. Raha liana amin'ny fampivoarana ny fampitaovana BCC ianao dia mendrika ny hojerena
Misy fitaovana debugging sy profiling mahaliana hafa mifototra amin'ny eBPF. Ny iray tamin'izy ireo -
Source: www.habr.com