diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/grafana_cpu_watcher_dashboard.json b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/grafana_cpu_watcher_dashboard.json new file mode 100644 index 000000000..9177bf611 --- /dev/null +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/grafana_cpu_watcher_dashboard.json @@ -0,0 +1,1177 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 1, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 11, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"avg_delay/us\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "interval": "1", + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"max_delay/us\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "interval": "1", + "legendFormat": "__auto", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"min_delay/μs\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "interval": "1", + "legendFormat": "__auto", + "range": true, + "refId": "C", + "useBackend": false + } + ], + "title": "schedule_delay", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"irqTime/us\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "irqTime", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 10, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"duration_ns\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "preempt_delay", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 20, + "gradientMode": "scheme", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 3, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "right", + "showLegend": false + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"proc/s\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "interval": "1", + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "procs", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 16 + }, + "id": 9, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"sys/ms\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "sys", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 16 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"softirq/us\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "softirqTime", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 24 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"utime/ms\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "utime", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 24 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"idle/ms\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "interval": "1", + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "idle", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 32 + }, + "id": 7, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"kthread/us\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "kthread", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 40 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"cswch/s\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "cswch", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 20, + "gradientMode": "scheme", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineWidth": 3, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 48 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "right", + "showLegend": false + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddlnxe6bsiha8c" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"delay/ms\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "interval": "1", + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "sys_delay", + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timeRangeUpdatedDuringEditOrView": false, + "timepicker": {}, + "timezone": "browser", + "title": "cpu_watcher_vis", + "uid": "cdlnxoxcy4zr4b", + "version": 4, + "weekStart": "" +} \ No newline at end of file diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/Makefile b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/Makefile index ae93b43c6..af43eaec8 100644 --- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/Makefile +++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/Makefile @@ -42,7 +42,7 @@ INCLUDES := -I$(OUTPUT) -I../../../libbpf/include/uapi -I$(dir $(VMLINUX)) -I$(L CFLAGS := -g -Wall ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS) -APPS = lifecycle_image lock_image newlife_image keytime_image +APPS = lifecycle_image lock_image newlife_image keytime_image migrate_image CARGO ?= $(shell which cargo) ifeq ($(strip $(CARGO)),) diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/migrate_image.bpf.c b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/migrate_image.bpf.c new file mode 100644 index 000000000..886481e22 --- /dev/null +++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/migrate_image.bpf.c @@ -0,0 +1,79 @@ +// Copyright 2023 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: albert_xuu@163.com + +#include "vmlinux.h" +#include //包含了BPF 辅助函数 +#include +#include +#include "migrate_image.h" + +char LICENSE[] SEC("license") = "Dual BSD/GPL"; +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(key_size, sizeof(pid_t)); + __uint(value_size, sizeof(struct migrate_event)); + __uint(max_entries, 128); +} migrate SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(key_size, sizeof(int)); + __uint(value_size, sizeof(int)); + __uint(max_entries, 16); +} t SEC(".maps"); + +SEC("tracepoint/sched/sched_migrate_task") +int tracepoint_sched_migrate_task(struct trace_event_raw_sched_migrate_task *args){ + u64 time = bpf_ktime_get_ns();//当前转移时间点; + pid_t pid = args->pid; + struct migrate_event *migrate_event; + migrate_event = bpf_map_lookup_elem(&migrate,&pid); + if(!migrate_event){ + int key = 0,*count=bpf_map_lookup_elem(&t,&key); + if(!count){ + int init = 1; + bpf_map_update_elem(&t,&key,&init,BPF_ANY); + } + else *count +=1; + + struct migrate_event migrate_event = {}; + migrate_event.pid = pid; + migrate_event.prio = args->prio; + migrate_event.migrate_info[0].time = time; + migrate_event.migrate_info[0].orig_cpu = args->orig_cpu; + migrate_event.migrate_info[0].dest_cpu = args->dest_cpu; + migrate_event.count = 1; + bpf_map_update_elem(&migrate, &pid, &migrate_event, BPF_ANY); + } + /*&& (migrate_event->migrate_info + migrate_event->count) < (migrate_event->migrate_info + MAX_MIGRATE)*/ + else if(migrate_event->count>0 && migrate_event->countmigrate_info + migrate_event->count) < (migrate_event->migrate_info + MAX_MIGRATE) ) + { + migrate_event->migrate_info[migrate_event->count].time = time; + migrate_event->migrate_info[migrate_event->count].orig_cpu = args->orig_cpu; + migrate_event->migrate_info[migrate_event->count++].dest_cpu = args->dest_cpu; + } + else if(migrate_event->count>=MAX_MIGRATE) + { + migrate_event->migrate_info[migrate_event->count % MAX_MIGRATE].time = time; + migrate_event->migrate_info[migrate_event->count % MAX_MIGRATE].orig_cpu = args->orig_cpu; + migrate_event->migrate_info[migrate_event->count % MAX_MIGRATE].dest_cpu = args->dest_cpu; + migrate_event->count++; + migrate_event->rear ++; + } + + //bpf_printk("Time:%llu\tpid:%d\tcomm:%s\tprio:%d\torig_cpu:%d\tdest_cpu:%d\t\n",time,args->pid,args->comm,args->prio,args->orig_cpu,args->dest_cpu); + return 0; +} \ No newline at end of file diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/migrate_image.c b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/migrate_image.c new file mode 100644 index 000000000..ae04ea7e7 --- /dev/null +++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/migrate_image.c @@ -0,0 +1,248 @@ +// Copyright 2023 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: albert_xuu@163.com + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "migrate_image.skel.h" +#include "migrate_image.h" +#include "trace_helpers.h" + +#define warn(...) fprintf(stderr, __VA_ARGS__) + +static volatile bool exiting = false; +struct migrate_image_bpf *skel; +// static struct env { +// int pid; +// int time; +// int cpu_id; +// int stack_count; +// bool set_stack; +// bool enable_cs; +// } env = { +// .pid = 0, +// .time = 0, +// .cpu_id = 0, +// .stack_count = 0, +// .set_stack = false, +// .enable_cs = false, +// }; + +static struct ksyms *ksyms = NULL; + +const char argp_program_doc[] ="Trace process to get process life cycle image.\n"; + +// static const struct argp_option opts[] = { +// { "pid", 'p', "PID", 0, "Process ID to trace" }, +// { "cpuid", 'C', "CPUID", 0, "Set For Tracing Process 0(other processes don't need to set this parameter)" }, +// { "time", 't', "TIME-SEC", 0, "Max Running Time(0 for infinite)" }, +// { "cs-reason", 'r', NULL, 0, "Process context switch reasons annotation" }, +// { "stack", 's', "STACK-COUNT", 0, "The number of kernel stacks printed when the process is under the CPU" }, +// { NULL, 'h', NULL, OPTION_HIDDEN, "show the full help" }, +// {}, +// }; + +// static error_t parse_arg(int key, char *arg, struct argp_state *state) +// { +// long pid; +// long cpu_id; +// long stack; +// switch (key) { +// case 'p': +// errno = 0; +// pid = strtol(arg, NULL, 10); +// if (errno || pid < 0) { +// warn("Invalid PID: %s\n", arg); +// // 调用argp_usage函数,用于打印用法信息并退出程序 +// argp_usage(state); +// } +// env.pid = pid; +// break; +// case 'C': +// cpu_id = strtol(arg, NULL, 10); +// if(cpu_id < 0){ +// warn("Invalid CPUID: %s\n", arg); +// argp_usage(state); +// } +// env.cpu_id = cpu_id; +// break; +// case 't': +// env.time = strtol(arg, NULL, 10); +// if(env.time) alarm(env.time); +// break; +// case 'r': +// env.enable_cs = true; +// break; +// case 's': +// stack = strtol(arg, NULL, 10); +// if (stack < 0) { +// warn("Invalid STACK-COUNT: %s\n", arg); +// // 调用argp_usage函数,用于打印用法信息并退出程序 +// argp_usage(state); +// } +// env.stack_count = stack; +// env.set_stack = true; +// break; +// case 'h': +// argp_state_help(state, stderr, ARGP_HELP_STD_HELP); +// break; +// default: +// return ARGP_ERR_UNKNOWN; +// } + +// return 0; +// } + +static void sig_handler(int sig) +{ + exiting = true; +} + + +static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) +{ + return vfprintf(stderr, format, args); +} + +static int migrate_print(){ + time_t now = time(NULL);// 获取当前时间 + struct tm *localTime = localtime(&now);// 将时间转换为本地时间结构 + printf("Time: %02d:%02d:%02d\n",localTime->tm_hour, localTime->tm_min, localTime->tm_sec); + printf("---------------------------------------------------------------------------------\n"); + int err,migrate_fd =bpf_map__fd(skel->maps.migrate),t_fd =bpf_map__fd(skel->maps.t); + int key =0,count; + err = bpf_map_lookup_elem(t_fd,&key,&count); + if (err < 0) { + fprintf(stderr, "failed to lookup infos: %d\n", err); + return -1; + } + printf("total process %d\n",count); + count = 0; + bpf_map_update_elem(t_fd,&key,&count,BPF_ANY); + + pid_t lookup_key = -1 ,next_key; + struct migrate_event migrate_event; + while(!bpf_map_get_next_key(migrate_fd, &lookup_key, &next_key)){//遍历打印hash map + err = bpf_map_lookup_elem(migrate_fd,&next_key,&migrate_event); + if (err < 0) { + fprintf(stderr, "failed to lookup infos: %d\n", err); + return -1; + } + if(migrate_event.count == migrate_event.rear) { + lookup_key = next_key; + continue; + } + u64 last_time_stamp = 0; + printf("\npid:%d\tprio:%d\tcount:%d\trear:%d\n",migrate_event.pid,migrate_event.prio,migrate_event.count,migrate_event.rear); + for(int i=migrate_event.rear;i%d\t", + migrate_event.migrate_info[i%MAX_MIGRATE].time,migrate_event.migrate_info[i%MAX_MIGRATE].orig_cpu,migrate_event.migrate_info[i%MAX_MIGRATE].dest_cpu); + if(i==migrate_event.rear && last_time_stamp == 0) { + last_time_stamp = migrate_event.migrate_info[i%MAX_MIGRATE].time; + printf("delay: /\n"); + }else{ + printf("delay: %d us\n",(migrate_event.migrate_info[i%MAX_MIGRATE].time - last_time_stamp)/1000); + last_time_stamp = migrate_event.migrate_info[i%MAX_MIGRATE].time; + } + } + migrate_event.rear = migrate_event.count; + bpf_map_update_elem(migrate_fd,&next_key,&migrate_event,BPF_ANY); + lookup_key = next_key; + } + printf("---------------------------------------------------------------------------------\n\n"); + return 0; +} + +int main(int argc, char **argv) +{ + struct ring_buffer *rb = NULL; + int err; + // static const struct argp argp = { + // .options = opts, + // .parser = parse_arg, + // .doc = argp_program_doc, + // }; + + // err = argp_parse(&argp, argc, argv, 0, NULL, NULL); + // if (err) + // return err; + + + libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + /* 设置libbpf错误和调试信息回调 */ + libbpf_set_print(libbpf_print_fn); + + /* 更干净地处理Ctrl-C + SIGINT:由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程 + SIGTERM:请求中止进程,kill命令发送 + */ + signal(SIGINT, sig_handler); + signal(SIGTERM, sig_handler); + signal(SIGALRM,sig_handler); + + /* 打开BPF应用程序 */ + skel = migrate_image_bpf__open(); + if (!skel) { + fprintf(stderr, "Failed to open BPF skeleton\n"); + return 1; + } + + /* 加载并验证BPF程序 */ + err = migrate_image_bpf__load(skel); + if (err) { + fprintf(stderr, "Failed to load and verify BPF skeleton\n"); + goto cleanup; + } + + ksyms = ksyms__load(); + if (!ksyms) { + fprintf(stderr, "failed to load kallsyms\n"); + goto cleanup; + } + + /* 附加跟踪点处理程序 */ + err = migrate_image_bpf__attach(skel); + if (err) { + fprintf(stderr, "Failed to attach BPF skeleton\n"); + goto cleanup; + } + + /* 处理事件 */ + while (!exiting) { + sleep(1); + err = migrate_print(); + if (err == -EINTR) { + err = 0; + break; + } + if (err < 0) { + printf("Error polling perf buffer: %d\n", err); + break; + } + } + +/* 卸载BPF程序 */ +cleanup: + // ring_buffer__free(rb); + migrate_image_bpf__destroy(skel); + return err < 0 ? -err : 0; +} diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/migrate_image.h b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/migrate_image.h new file mode 100644 index 000000000..0bb280c34 --- /dev/null +++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/migrate_image.h @@ -0,0 +1,23 @@ +#include +#include + +typedef unsigned long long u64; +typedef unsigned int u32; +/*----------------------------------------------*/ +/* migrate_event结构体 */ +/*----------------------------------------------*/ +#define MAX_MIGRATE 16 +// #define ARRY_OVERFLOW -1 +struct per_migrate{//每次迁移,记录该次迁移信息; + u64 time; + u32 orig_cpu; + u32 dest_cpu; +}; +//每个进程的迁移信息; +struct migrate_event{ + int erro; + pid_t pid; + int prio; + int count,rear;//迁移频率 + struct per_migrate migrate_info[MAX_MIGRATE];//该进程每次迁移信息; +}; diff --git a/eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.bpf.c b/eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.bpf.c index 50d0bb29c..135a863fd 100644 --- a/eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.bpf.c +++ b/eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.bpf.c @@ -1,63 +1,77 @@ -#include "vmlinux.h" -#include //包含了BPF 辅助函数 +#define BPF_NO_GLOBAL_DATA +#include +#include #include -#include "open.h" +#include -char LICENSE[] SEC("license") = "Dual BSD/GPL"; +#define TASK_COMM_LEN 100 +#define path_size 256 -// 定义哈希映射 struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 1024); __type(key, pid_t); - __type(value, u64); -} fdtmp SEC(".maps"); + __type(value, char[TASK_COMM_LEN]); +} data SEC(".maps"); + +struct event { + int pid_; + char path_name_[path_size]; + int n_; + char comm[TASK_COMM_LEN]; +}; struct { __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); -} rb SEC(".maps"); - -SEC("kprobe/do_sys_openat2") -int BPF_KPROBE(do_sys_openat2) -{ - struct fs_t fs; - pid_t pid; - - //pid - pid = bpf_get_current_pid_tgid() >> 32; - fs.pid = pid; - - //uid - fs.uid = bpf_get_current_uid_gid(); - - //fd,file descriptor - int fd = PT_REGS_RC(ctx); - if (fd >= 0) - fs.fd = fd; - else - fs.fd= -1; - - //time - unsigned long long ts = bpf_ktime_get_ns(); - fs.ts = ts; - bpf_map_update_elem(&fdtmp, &pid, &ts, BPF_ANY); - - //从环形缓冲区(ring buffer)中分配一块内存来存储一个名为 struct fs_t 类型的数据,并将该内存块的指针赋值给指针变量 e - struct fs_t *e; +} rb SEC(".maps"); // 环形缓冲区 + + +SEC("tracepoint/syscalls/sys_enter_openat") +int do_syscall_trace(struct trace_event_raw_sys_enter *ctx) +{ + struct event *e; + char comm[TASK_COMM_LEN]; + bpf_get_current_comm(&comm,sizeof(comm)); e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); - if (!e) return 0; - - //给变量e赋值 - e->pid = fs.pid; - e->uid = fs.uid; - e->fd = fs.fd; - e->ts = fs.ts; - bpf_get_current_comm(e->comm, sizeof(e->comm)); - - // 成功地将其提交到用户空间进行后期处理 + if (!e) + return 0; + + char filename[path_size]; + struct task_struct *task = (struct task_struct *)bpf_get_current_task(), + *real_parent; + if (task == NULL) { + bpf_printk("task\n"); + bpf_ringbuf_discard(e, 0); + return 0; + } + int pid = bpf_get_current_pid_tgid() >> 32, tgid; + + bpf_map_update_elem(&data, &pid, &comm, BPF_ANY); + + int ppid = BPF_CORE_READ(task, real_parent, tgid); + + bpf_probe_read_str(e->path_name_, sizeof(e->path_name_), + (void *)(ctx->args[1])); + + bpf_printk("path name: %s,pid:%d,ppid:%d\n", e->path_name_, pid, ppid); + + struct fdtable *fdt = BPF_CORE_READ(task, files, fdt); + if (fdt == NULL) { + bpf_printk("fdt\n"); + bpf_ringbuf_discard(e, 0); + return 0; + } + + unsigned int i = 0, count = 0, n = BPF_CORE_READ(fdt, max_fds); + bpf_printk("n:%d\n", n); + + e->n_ = n; + e->pid_ = pid; + bpf_ringbuf_submit(e, 0); - return 0; + return 0; } +char LICENSE[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.c b/eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.c index 9a48be42f..ed01c10e5 100644 --- a/eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.c +++ b/eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.c @@ -1,10 +1,38 @@ +// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +/* Copyright (c) 2020 Facebook */ +#include #include -#include +#include +#include +#include +#include #include #include -#include -#include "open.skel.h" //包含了 BPF 字节码和相关的管理函数 -#include "open.h" +#include +#include +#include +#include "open.skel.h" +#include +#include +#include + +#define path_size 256 +#define TASK_COMM_LEN 16 + +struct event { + int pid_; + char path_name_[path_size]; + int n_; + char comm[TASK_COMM_LEN]; +}; + +#define warn(...) fprintf(stderr, __VA_ARGS__) + +static int libbpf_print_fn(enum libbpf_print_level level, const char *format, + va_list args) +{ + return vfprintf(stderr, format, args); +} static volatile bool exiting = false; @@ -13,18 +41,34 @@ static void sig_handler(int sig) exiting = true; } -static int handle_event(void *ctx, void *data,unsigned long data_sz) +static int handle(void *ctx, void *data, size_t data_sz) { - const struct fs_t *e = data; - printf("pid:%d uid:%llu time:%llu fd:%d comm:%s\n",e->pid,e->uid,e->ts,e->fd,e->comm); - - return 0; -} - + struct event *e = (struct event *)data; + char *filename = strrchr(e->path_name_, '/'); + ++filename; -static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) -{ - return vfprintf(stderr, format, args); + char fd_path[path_size]; + char actual_path[path_size]; + char comm[TASK_COMM_LEN]; + int i = 0; + int map_fd = *(int *)ctx;//传递map得文件描述符 + + for (; i < e->n_; ++i) { + snprintf(fd_path, sizeof(fd_path), "/proc/%d/fd/%d", e->pid_,i); + ssize_t len = readlink(fd_path, actual_path, sizeof(actual_path) - 1); + if (len != -1) { + actual_path[len] = '\0'; + int result = strcmp(e->path_name_, actual_path); + if (result == 0) { + if(bpf_map_lookup_elem(map_fd,&e->pid_,&comm)==0){ + printf("get , filename:%s , fd:%d , pid:%d ,comm:%s\n", e->path_name_, i,e->pid_,comm); + }else{ + fprintf(stderr, "Failed to lookup value for key %d\n", e->pid_); + } + } + } + } + return 0; } int main(int argc, char **argv) @@ -33,50 +77,51 @@ int main(int argc, char **argv) struct open_bpf *skel; int err; - libbpf_set_strict_mode(LIBBPF_STRICT_ALL); - /* 设置libbpf错误和调试信息回调 */ + /* Set up libbpf errors and debug info callback */ libbpf_set_print(libbpf_print_fn); - /* 更干净地处理Ctrl-C - SIGINT:由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程 - SIGTERM:请求中止进程,kill命令发送 - */ - signal(SIGINT, sig_handler); //signal设置某一信号的对应动作 + /* Cleaner handling of Ctrl-C */ + signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); - /* 打开BPF应用程序 */ + /* Load and verify BPF application */ skel = open_bpf__open(); if (!skel) { - fprintf(stderr, "Failed to open BPF skeleton\n"); + fprintf(stderr, "Failed to open and load BPF skeleton\n"); return 1; } - - /* 加载并验证BPF程序 */ + + /* Load & verify BPF programs */ err = open_bpf__load(skel); if (err) { fprintf(stderr, "Failed to load and verify BPF skeleton\n"); goto cleanup; } - - /* 附加跟踪点处理程序 */ - err = open_bpf__attach(skel); - if (err) { + + int attach = open_bpf__attach(skel); + if (attach) { fprintf(stderr, "Failed to attach BPF skeleton\n"); + err = -1; goto cleanup; } - - /* 设置环形缓冲区轮询 */ - rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event, NULL, NULL); //ring_buffer__new() API,允许在不使用额外选项数据结构下指定回调 + + int map_fd = bpf_map__fd(skel->maps.data); + if(!map_fd){ + fprintf(stderr, "Failed to find BPF map\n"); + return -1; + } + + rb = ring_buffer__new( + bpf_map__fd(skel->maps.rb), handle, &map_fd, NULL); // 创建一个环形缓冲区,并设置好缓冲区的回调函数 if (!rb) { err = -1; fprintf(stderr, "Failed to create ring buffer\n"); goto cleanup; } - - /* 处理事件 */ + while (!exiting) { - err = ring_buffer__poll(rb, 100 /* timeout, ms */); //ring_buffer__poll(),轮询打开ringbuf缓冲区。如果有事件,handle_event函数会执行 - /* Ctrl-C will cause -EINTR */ + err = ring_buffer__poll(rb, 100); + if (err == -EINTR) { err = 0; break; @@ -85,15 +130,11 @@ int main(int argc, char **argv) printf("Error polling perf buffer: %d\n", err); break; } - - //exiting = true; //使用该程序时,将该行代码注释掉 - } - -/* 卸载BPF程序 */ cleanup: + /* Clean up */ ring_buffer__free(rb); open_bpf__destroy(skel); - + return err < 0 ? -err : 0; -} +} \ No newline at end of file diff --git a/eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.h b/eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.h index 835cd90fa..a8194600c 100644 --- a/eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.h +++ b/eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.h @@ -5,12 +5,11 @@ #define TASK_COMM_LEN 16 #endif -struct fs_t { - int pid; - unsigned long long uid; - int fd; - unsigned long long ts; - char comm[TASK_COMM_LEN]; +struct event { + int pid_; + char path_name_[path_size]; + int n_; + char comm[TASK_COMM_LEN]; }; #endif /* __OPEN_H */ \ No newline at end of file diff --git a/eBPF_Supermarket/Memory_Subsystem/mem_watcher/mem_watcher.c b/eBPF_Supermarket/Memory_Subsystem/mem_watcher/mem_watcher.c index 8f596b55d..2b5f34811 100644 --- a/eBPF_Supermarket/Memory_Subsystem/mem_watcher/mem_watcher.c +++ b/eBPF_Supermarket/Memory_Subsystem/mem_watcher/mem_watcher.c @@ -144,6 +144,7 @@ static struct env { bool sysstat; bool memleak; bool kernel_trace; + bool print_time; bool part2; @@ -157,6 +158,7 @@ static struct env { .sysstat = false, .memleak = false, .kernel_trace = true, + .print_time = false, .rss = false, .part2 = false, .choose_pid = 0, @@ -186,8 +188,10 @@ static const struct argp_option opts[] = { {0, 0, 0, 0, "memleak:", 8}, {"memleak", 'l', 0, 0, "print memleak (内核态内存泄漏检测)", 8}, {"choose_pid", 'P', "PID", 0, "选择进程号打印, print memleak (用户态内存泄漏检测)", 9}, + {"print_time", 'm', 0, 0, "打印申请地址时间 (用户态)", 10}, - {"time", 't', "TIME-SEC", 0, "Max Running Time(0 for infinite)", 10}, + + {"time", 't', "TIME-SEC", 0, "Max Running Time(0 for infinite)", 11}, {NULL, 'h', NULL, OPTION_HIDDEN, "show the full help"}, {0}, }; @@ -203,11 +207,12 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) { case 'r': env.procstat = true; break; case 's': env.sysstat = true; break; case 'n': env.part2 = true; break; - case 'h': argp_state_help(state, stderr, ARGP_HELP_STD_HELP); break; case 'P': env.choose_pid = strtol(arg, NULL, 10); break; case 'R': env.rss = true; break; - case 'l': env.memleak = true; break; - default: return ARGP_ERR_UNKNOWN; + case 'l': env.memleak = true; break; + case 'm': env.print_time = true; break; + case 'h': argp_state_help(state, stderr, ARGP_HELP_STD_HELP); break; + default: return ARGP_ERR_UNKNOWN; } return 0; } @@ -237,6 +242,10 @@ static int process_pr(struct pr_bpf *skel_pr); static int process_procstat(struct procstat_bpf *skel_procstat); static int process_sysstat(struct sysstat_bpf *skel_sysstat); static int process_memleak(struct memleak_bpf *skel_memleak, struct env); +static __u64 adjust_time_to_program_start_time(__u64 first_query_time); +static int update_addr_times(struct memleak_bpf *skel_memleak); +static int print_time(struct memleak_bpf *skel_memleak); + // Main function int main(int argc, char **argv) { @@ -521,6 +530,92 @@ int print_outstanding_combined_allocs(struct memleak_bpf *skel, pid_t pid) { return 0; } +// 在更新时间之前获取当前时间并调整为相对于程序启动时的时间 +static __u64 adjust_time_to_program_start_time(__u64 first_query_time) { + struct timespec current_time; + clock_gettime(CLOCK_MONOTONIC, ¤t_time); + //printf("current_time: %ld\n", current_time.tv_sec); + __u64 adjusted_time; + adjusted_time = current_time.tv_sec - first_query_time; + + //printf("adjusted_time: %lld\n", adjusted_time); + return adjusted_time; +} + + +// 在更新时间时,先将时间调整为相对于程序启动的时间 +static int update_addr_times(struct memleak_bpf *skel) { + const size_t addr_times_key_size = bpf_map__key_size(skel->maps.addr_times); + const size_t first_time_key_size = bpf_map__key_size(skel->maps.first_time); + for (__u64 prev_key = 0, curr_key = 0;; prev_key = curr_key) { + if (bpf_map__get_next_key(skel->maps.addr_times, &prev_key, &curr_key, addr_times_key_size)) { + if (errno == ENOENT) { + break; // no more keys, done! + } + + perror("map get next key failed!"); + return -errno; + } + + // Check if the address exists in the first_time map + __u64 first_query_time; + if (bpf_map__lookup_elem(skel->maps.first_time, &curr_key, first_time_key_size, &first_query_time, sizeof(first_query_time), 0)) { + // Address doesn't exist in the first_time map, add it with the current time + struct timespec first_time_alloc; + clock_gettime(CLOCK_MONOTONIC, &first_time_alloc); + if (bpf_map__update_elem(skel->maps.first_time, &curr_key, first_time_key_size, &first_time_alloc.tv_sec, sizeof(first_time_alloc.tv_sec), 0)) { + perror("map update failed!"); + return -errno; + } + } + else { + // Address exists in the first_time map + // This is the first time updating timestamp + __u64 adjusted_time = adjust_time_to_program_start_time(first_query_time); + //printf("update_addr_times adjusted_time: %lld\n", adjusted_time); + + // Save the adjusted time to addr_times map + __u64 timestamp = adjusted_time; + + // write the updated timestamp back to the map + if (bpf_map__update_elem(skel->maps.addr_times, &curr_key, addr_times_key_size, ×tamp, sizeof(timestamp), 0)) { + perror("map update failed!"); + return -errno; + } + } + } + return 0; +} + +// 在打印时间时,先将时间调整为相对于程序启动的时间 +int print_time(struct memleak_bpf *skel) { + const size_t addr_times_key_size = bpf_map__key_size(skel->maps.addr_times); + + printf("%-16s %12s\n", "AL_ADDR", "AL_Time(s)"); + + // Iterate over the addr_times map to print address and time + for (__u64 prev_key = 0, curr_key = 0;; prev_key = curr_key) { + if (bpf_map__get_next_key(skel->maps.addr_times, &prev_key, &curr_key, addr_times_key_size)) { + if (errno == ENOENT) { + break; // no more keys, done! + } + perror("map get next key failed!"); + return -errno; + } + + // Read the timestamp for the current address + __u64 timestamp; + if (bpf_map__lookup_elem(skel->maps.addr_times, &curr_key, addr_times_key_size, ×tamp, sizeof(timestamp), 0) == 0) { + printf("0x%-16llx %lld\n", curr_key, timestamp); + } + else { + perror("map lookup failed!"); + return -errno; + } + } + return 0; +} + void disable_kernel_tracepoints(struct memleak_bpf *skel) { bpf_program__set_autoload(skel->progs.memleak__kmalloc, false); bpf_program__set_autoload(skel->progs.memleak__kmalloc_node, false); @@ -813,7 +908,13 @@ static int process_memleak(struct memleak_bpf *skel_memleak, struct env env) { for (;;) { if (!env.kernel_trace) - print_outstanding_combined_allocs(skel_memleak, attach_pid); + if (env.print_time) { + system("clear"); + update_addr_times(skel_memleak); + print_time(skel_memleak); + } + else + print_outstanding_combined_allocs(skel_memleak, attach_pid); else print_outstanding_allocs(skel_memleak); diff --git a/eBPF_Supermarket/Memory_Subsystem/mem_watcher/memleak.bpf.c b/eBPF_Supermarket/Memory_Subsystem/mem_watcher/memleak.bpf.c index 4ae642682..00ef2efe1 100644 --- a/eBPF_Supermarket/Memory_Subsystem/mem_watcher/memleak.bpf.c +++ b/eBPF_Supermarket/Memory_Subsystem/mem_watcher/memleak.bpf.c @@ -62,6 +62,20 @@ struct { __type(value, u64); // 用户态指针变量 memptr } memptrs SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __type(key, u64); /* alloc return address */ + __type(value, u64); /* timestamp */ + __uint(max_entries, 10240); +} addr_times SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __type(key, u64); /* alloc return address */ + __type(value, u64); /* timestamp */ + __uint(max_entries, 10240); +} first_time SEC(".maps"); + char LICENSE[] SEC("license") = "Dual BSD/GPL"; static int gen_alloc_enter(size_t size) { @@ -92,6 +106,10 @@ static int gen_alloc_exit2(void *ctx, u64 address) { bpf_map_update_elem(&allocs, &addr, &info, BPF_ANY); + // Initialize the addr_times map to 0 + __u64 zero_ts = 0; + bpf_map_update_elem(&addr_times, &addr, &zero_ts, BPF_ANY); + union combined_alloc_info add_cinfo = { .total_size = info.size, .number_of_allocs = 1 @@ -135,6 +153,10 @@ static int gen_free_enter(const void *address) { bpf_map_delete_elem(&allocs, &addr); + // Initialize the addr_times map to 0 + __u64 zero_ts = 0; + bpf_map_update_elem(&addr_times, &addr, &zero_ts, BPF_ANY); + return 0; } diff --git a/eBPF_Supermarket/Network_Subsystem/TrafficManager/go.mod b/eBPF_Supermarket/Network_Subsystem/TrafficManager/go.mod index 2c47343f5..675073ee9 100644 --- a/eBPF_Supermarket/Network_Subsystem/TrafficManager/go.mod +++ b/eBPF_Supermarket/Network_Subsystem/TrafficManager/go.mod @@ -3,7 +3,7 @@ module lmp/eTrafficManager go 1.20 require ( - github.com/cilium/cilium v1.14.8 + github.com/cilium/cilium v1.14.12 github.com/cilium/ebpf v0.11.0 github.com/prometheus/client_golang v1.16.0 github.com/prometheus/common v0.42.0 @@ -83,7 +83,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect - k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect + k8s.io/utils v0.0.0-20240310230437-4693a0247e57 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect diff --git a/eBPF_Supermarket/Network_Subsystem/TrafficManager/go.sum b/eBPF_Supermarket/Network_Subsystem/TrafficManager/go.sum index 101946f56..183679d98 100644 --- a/eBPF_Supermarket/Network_Subsystem/TrafficManager/go.sum +++ b/eBPF_Supermarket/Network_Subsystem/TrafficManager/go.sum @@ -52,8 +52,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/checkmate v1.0.3 h1:CQC5eOmlAZeEjPrVZY3ZwEBH64lHlx9mXYdUehEwI5w= -github.com/cilium/cilium v1.14.8 h1:Jm54iA7XxWJn+GdZrfzcEyeoNUb58w8y0g8ZB2lVcJw= -github.com/cilium/cilium v1.14.8/go.mod h1:7cWSSEl+dU9Q5CqnEWT//c0w8yLSazShw287Uop6xVs= +github.com/cilium/cilium v1.14.12 h1:lQ4XilTUJK5R6BrZnSm4pYxj6jsBQFWlBuRHA5FHJ1I= +github.com/cilium/cilium v1.14.12/go.mod h1:Pjy+qd1hrrXulp78Hs76ahKCttij64LvjxFui9XquVA= github.com/cilium/ebpf v0.11.0 h1:V8gS/bTCCjX9uUnkUFUpPsksM8n1lXBAvHcpiFk1X2Y= github.com/cilium/ebpf v0.11.0/go.mod h1:WE7CZAnqOL2RouJ4f1uyNhqr2P4CCvXFIqdRDUgWsVs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -756,8 +756,8 @@ k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= -k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY= -k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY= +k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/common.bpf.h b/eBPF_Supermarket/Network_Subsystem/net_watcher/common.bpf.h index b5e3f4aa1..90ad50757 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/common.bpf.h +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/common.bpf.h @@ -102,6 +102,11 @@ struct dns_query { char data[64];// 可变长度数据(域名+类型+类) }; +struct dns{ + u32 saddr; + u32 daddr; +}; + // 操作BPF映射的一个辅助函数 static __always_inline void * //__always_inline强制内联 bpf_map_lookup_or_try_init(void *map, const void *key, const void *init) { @@ -229,6 +234,7 @@ struct { __type(value, __u64); } tcp_state SEC(".maps"); +//sql 耗时 struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 256*1024); @@ -236,6 +242,29 @@ struct { __type(value, __u64); } mysql_time SEC(".maps"); +//sql请求数 +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1024); + __type(key,__u32); + __type(value,__u64); +} sql_count SEC(".maps"); + +//dns计数根据每个saddr、daddr +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1024); + __type(key,struct dns); + __type(value,__u64); +} dns_request_count SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1024); + __type(key,struct dns); + __type(value,__u64); +} dns_response_count SEC(".maps"); + const volatile int filter_dport = 0; const volatile int filter_sport = 0; const volatile int all_conn = 0, err_packet = 0, extra_conn_info = 0, diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/mysql.bpf.h b/eBPF_Supermarket/Network_Subsystem/net_watcher/mysql.bpf.h index b2c065148..cff8c950f 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/mysql.bpf.h +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/mysql.bpf.h @@ -24,6 +24,7 @@ static __always_inline int __handle_mysql_start(struct pt_regs *ctx) { union COM_DATA *com_data = (union COM_DATA *)PT_REGS_PARM2(ctx); pid_t pid = bpf_get_current_pid_tgid() >> 32; + pid_t tid = bpf_get_current_pid_tgid(); void *thd = (void *)PT_REGS_PARM1(ctx); char *sql; u32 size = 0; @@ -32,7 +33,7 @@ static __always_inline int __handle_mysql_start(struct pt_regs *ctx) { return 0; } - u64 start_time = bpf_ktime_get_ns()/1000; + u64 start_time = bpf_ktime_get_ns() / 1000; bpf_map_update_elem(&mysql_time, &pid, &start_time, BPF_ANY); struct mysql_query *message = @@ -45,20 +46,22 @@ static __always_inline int __handle_mysql_start(struct pt_regs *ctx) { &com_data->com_query.length); bpf_probe_read_str(&sql, sizeof(sql), &com_data->com_query.query); bpf_probe_read_str(&message->msql, sizeof(message->msql), sql); - bpf_printk("%s",sql); message->pid = pid; + message->tid = tid; bpf_get_current_comm(&message->comm, sizeof(comm)); - + bpf_ringbuf_submit(message, 0); + return 0; } static __always_inline int __handle_mysql_end(struct pt_regs *ctx) { pid_t pid = bpf_get_current_pid_tgid() >> 32; + pid_t tid = bpf_get_current_pid_tgid(); u64 *start_time_ptr, duration; - u64 end_time = bpf_ktime_get_ns()/1000; + u64 end_time = bpf_ktime_get_ns() / 1000; start_time_ptr = bpf_map_lookup_elem(&mysql_time, &pid); if (!start_time_ptr) { return 0; @@ -70,10 +73,18 @@ static __always_inline int __handle_mysql_end(struct pt_regs *ctx) { if (!message) { return 0; } + u64 *count_ptr, count = 1; + count_ptr = bpf_map_lookup_elem(&sql_count, &tid); + if (count_ptr) { + count = *count_ptr + 1; + } + message->count = count; + bpf_map_update_elem(&sql_count, &tid, &count, BPF_ANY); message->duratime = duration; bpf_ringbuf_submit(message, 0); bpf_map_delete_elem(&mysql_time, &pid); + return 0; } diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.c b/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.c index 7ff8a7bed..c2ba5490e 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.c +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.c @@ -43,7 +43,8 @@ static int sport = 0, dport = 0; // for filter static int all_conn = 0, err_packet = 0, extra_conn_info = 0, layer_time = 0, http_info = 0, retrans_info = 0, udp_info = 0, net_filter = 0, drop_reason = 0, addr_to_func = 0, icmp_info = 0, tcp_info = 0, - time_load = 0, dns_info = 0, stack_info = 0, mysql_info = 0; // flag + time_load = 0, dns_info = 0, stack_info = 0, mysql_info = 0, + count_info = 0; // flag static const char *tcp_states[] = { [1] = "ESTABLISHED", [2] = "SYN_SENT", [3] = "SYN_RECV", @@ -54,7 +55,6 @@ static const char *tcp_states[] = { }; static const char argp_program_doc[] = "Watch tcp/ip in network subsystem \n"; - static const struct argp_option opts[] = { {"all", 'a', 0, 0, "set to trace CLOSED connection"}, {"err", 'e', 0, 0, "set to trace TCP error packets"}, @@ -74,11 +74,14 @@ static const struct argp_option opts[] = { {"dns", 'D', 0, 0, "set to trace dns information info include Id 事务ID、Flags 标志字段、Qd " "问题部分计数、An 应答记录计数、Ns 授权记录计数、Ar 附加记录计数、Qr " - "域名、rx 收发包 "}, + "域名、rx 收发包 、Qc请求数、Sc响应数"}, {"stack", 'A', 0, 0, "set to trace of stack "}, {"mysql", 'M', 0, 0, "set to trace mysql information info include Pid 进程id、Comm " - "进程名、Size sql语句字节大小、Sql 语句"}, + "进程名、Size sql语句字节大小、Sql 语句、Duration Sql耗时、Request " + "Sql请求数"}, + {"count", 'C', "NUMBER", 0, + "specify the time to count the number of requests"}, {}}; static error_t parse_arg(int key, char *arg, struct argp_state *state) { @@ -138,6 +141,9 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) { case 'M': mysql_info = 1; break; + case 'C': + count_info = strtoul(arg, &end, 10); + break; default: return ARGP_ERR_UNKNOWN; } @@ -253,7 +259,6 @@ static const char binary_path[] = "/usr/sbin/mysqld"; __ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, false) #define ATTACH_URETPROBE_CHECKED(skel, sym_name, prog_name) \ __ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, true) - struct SymbolEntry symbols[300000]; int num_symbols = 0; // 定义快表 @@ -357,6 +362,9 @@ struct LayerDelayInfo { #define GRANULARITY 3 #define ALPHA 0.2 // 衰减因子 #define MAXTIME 10000 +#define SLOW_QUERY_THRESHOLD 10000 // +#define ANSI_COLOR_RED "\x1b[31m" +#define ANSI_COLOR_RESET "\x1b[0m" // 全局变量用于存储每层的移动平均值 float ewma_values[NUM_LAYERS] = {0}; @@ -596,17 +604,18 @@ static void print_header(enum MonitorMode mode) { "====================DNS " "INFORMATION====================================================" "============================\n"); - printf("%-20s %-20s %-12s %-12s %-5s %-5s %-5s %-5s %-47s %5s \n", + printf("%-20s %-20s %-12s %-12s %-5s %-5s %-5s %-5s %-47s %-10s %-10s " + "%-10s \n", "Saddr", "Daddr", "Id", "Flags", "Qd", "An", "Ns", "Ar", "Qr", - "RX/direction"); + "Qc", "Sc", "RX/direction"); break; case MODE_MYSQL: printf("===============================================================" "====================MYSQL " "INFORMATION====================================================" "============================\n"); - printf("%-20s %-20s %-20s %-40s %-20s \n", "Pid", "Comm", "Size", "Sql", - "duration/μs"); + printf("%-20s %-20s %-20s %-20s %-40s %-20s %-20s \n", "Pid", "Tid", + "Comm", "Size", "Sql", "Duration/μs", "Request"); break; case MODE_DEFAULT: printf("===============================================================" @@ -921,6 +930,9 @@ static int print_netfilter(void *ctx, void *packet_info, size_t size) { return 0; unsigned int saddr = pack_info->saddr; unsigned int daddr = pack_info->daddr; + // if ((daddr & 0x0000FFFF) == 0x0000007F || + // (saddr & 0x0000FFFF) == 0x0000007F) + // return 0; printf("%-20s %-20s %-12d %-12d %-8lld %-8lld% -8lld %-8lld %-8lld %-8d", inet_ntop(AF_INET, &saddr, s_str, sizeof(s_str)), inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)), pack_info->sport, @@ -1031,6 +1043,7 @@ static int print_icmptime(void *ctx, void *packet_info, size_t size) { printf("\n"); return 0; } + // 从DNS数据包中提取并打印域名 static void print_domain_name(const unsigned char *data, char *output) { const unsigned char *next = data; @@ -1066,30 +1079,41 @@ static int print_dns(void *ctx, void *packet_info, size_t size) { inet_ntop(AF_INET, &daddr, d_str, sizeof(d_str)); print_domain_name((const unsigned char *)pack_info->data, domain_name); - - printf("%-20s %-20s %-#12x %-#12x %-5x %-5x %-5x %-5x %-47s %-10d\n", s_str, - d_str, pack_info->id, pack_info->flags, pack_info->qdcount, + if (pack_info->daddr == 0) { + return 0; + } + printf("%-20s %-20s %-#12x %-#12x %-5x %-5x %-5x %-5x %-47s %-10d %-10d " + "%-10d \n", + s_str, d_str, pack_info->id, pack_info->flags, pack_info->qdcount, pack_info->ancount, pack_info->nscount, pack_info->arcount, - domain_name, pack_info->rx); - + domain_name, pack_info->request_count, pack_info->response_count, + pack_info->rx); return 0; } - static mysql_query last_query; static int print_mysql(void *ctx, void *packet_info, size_t size) { + if (!mysql_info) { + return 0; + } + const mysql_query *pack_info = packet_info; - // 假设duratime总是0 if (pack_info->duratime == 0) { - // 存储开始事件数据 + memcpy(&last_query, pack_info, sizeof(mysql_query)); } else { - // 结束事件 合并 - printf("%-20d %-20s %-20u %-40s %-20llu\n", last_query.pid, - last_query.comm, last_query.size, last_query.msql, - pack_info->duratime); - // 重置 - memset(&last_query, 0, sizeof(last_query)); + + printf("%-20d %-20d %-20s %-20u %-40s", last_query.pid, last_query.tid, + last_query.comm, last_query.size, last_query.msql); + // 当 duratime 大于 count_info 时,才打印 duratime + if (pack_info->duratime > count_info) { + printf("%-21llu", pack_info->duratime); + } else { + printf("%-21s", ""); + } + + printf("%-20d\n", pack_info->count); + memset(&last_query, 0, sizeof(mysql_query)); } return 0; } diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.h b/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.h index c64d351c9..de8aa5e7a 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.h +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.h @@ -155,6 +155,8 @@ struct dns_information { u16 arcount; char data[64]; int rx; + int response_count; + int request_count; }; #define MAX_STACK_DEPTH 128 typedef u64 stack_trace_t[MAX_STACK_DEPTH]; @@ -170,10 +172,12 @@ struct stacktrace_event { typedef struct mysql_query { int pid; + int tid; char comm[20]; u32 size; char msql[256]; u64 duratime; + int count; } mysql_query; #endif /* __NETWATCHER_H */ \ No newline at end of file diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/udp.bpf.h b/eBPF_Supermarket/Network_Subsystem/net_watcher/udp.bpf.h index af739e859..d39da361d 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/udp.bpf.h +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/udp.bpf.h @@ -123,7 +123,8 @@ static __always_inline int __ip_send_skb(struct sk_buff *skb) { static __always_inline int process_dns_packet(struct sk_buff *skb, int rx) { if (skb == NULL) return 0; - + u16 QR_flags; + u64 *count_ptr, response_count = 0, request_count = 0; struct sock *sk = BPF_CORE_READ(skb, sk); struct packet_tuple pkt_tuple = { .saddr = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr), @@ -131,6 +132,8 @@ static __always_inline int process_dns_packet(struct sk_buff *skb, int rx) { .sport = BPF_CORE_READ(sk, __sk_common.skc_num), .dport = __bpf_ntohs(BPF_CORE_READ(sk, __sk_common.skc_dport)), .tran_flag = UDP}; + // 使用saddr、daddr作为key + struct dns key = {.saddr = pkt_tuple.saddr, .daddr = pkt_tuple.daddr}; if ((pkt_tuple.sport != 53) && (pkt_tuple.dport != 53)) return 0; @@ -151,7 +154,39 @@ static __always_inline int process_dns_packet(struct sk_buff *skb, int rx) { bpf_probe_read_kernel(message->data, sizeof(message->data), BPF_CORE_READ(skb, head) + dns_offset + sizeof(struct dns_header)); - + QR_flags = __bpf_ntohs(query.header.flags); + /* + 1000 0000 0000 0000 + &运算提取最高位QR, QR=1 Response QR=0 Request + */ + if (QR_flags & 0x8000) { // 响应 + count_ptr = bpf_map_lookup_elem(&dns_response_count, &key); + if (count_ptr) { + response_count = *count_ptr + 1; + } else { + response_count = 1; + } + bpf_map_update_elem(&dns_response_count, &key, &response_count, + BPF_ANY); + // 保留映射中的请求计数值 + count_ptr = bpf_map_lookup_elem(&dns_request_count, &key); + if (count_ptr) { + request_count = *count_ptr; + } + } else { // 请求 + count_ptr = bpf_map_lookup_elem(&dns_request_count, &key); + if (count_ptr) { + request_count = *count_ptr + 1; + } else { + request_count = 1; + } + bpf_map_update_elem(&dns_request_count, &key, &request_count, BPF_ANY); + // 保留映射中的响应计数值 + count_ptr = bpf_map_lookup_elem(&dns_response_count, &key); + if (count_ptr) { + response_count = *count_ptr; + } + } message->saddr = rx ? pkt_tuple.saddr : pkt_tuple.daddr; message->daddr = rx ? pkt_tuple.daddr : pkt_tuple.saddr; message->id = __bpf_ntohs(query.header.id); @@ -160,6 +195,8 @@ static __always_inline int process_dns_packet(struct sk_buff *skb, int rx) { message->ancount = __bpf_ntohs(query.header.ancount); message->nscount = __bpf_ntohs(query.header.nscount); message->arcount = __bpf_ntohs(query.header.arcount); + message->request_count = request_count; + message->response_count = response_count; message->rx = rx; bpf_ringbuf_submit(message, 0); diff --git a/eBPF_Supermarket/Stack_Analyser/Makefile b/eBPF_Supermarket/Stack_Analyser/Makefile index 0b17426e8..83731b94e 100644 --- a/eBPF_Supermarket/Stack_Analyser/Makefile +++ b/eBPF_Supermarket/Stack_Analyser/Makefile @@ -104,7 +104,7 @@ $(OUTPUT) $(OUTPUT)/libbpf $(BPFTOOL_OUTPUT) $(BPF_SKEL): $(Q)mkdir -p $@ # Build libbpf -$(LIBBPF_OBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)/libbpf +$(LIBBPF_OBJ): $(LIBBPF_SRC) $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)/libbpf $(call msg,LIB,$@) $(Q)$(MAKE) -C $(LIBBPF_SRC) BUILD_STATIC_ONLY=1 \ OBJDIR=$(dir $@)/libbpf DESTDIR=$(dir $@) \ @@ -112,7 +112,7 @@ $(LIBBPF_OBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPU install # Build bpftool -$(BPFTOOL): | $(BPFTOOL_OUTPUT) +$(BPFTOOL): $(BPFTOOL_SRC) | $(BPFTOOL_OUTPUT) $(call msg,BPFTOOL,$@) $(Q)$(MAKE) ARCH= CROSS_COMPILE= OUTPUT=$(BPFTOOL_OUTPUT)/ -C $(BPFTOOL_SRC) bootstrap diff --git a/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h b/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h index 44ba9e125..56ea5549d 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h +++ b/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h @@ -20,6 +20,7 @@ #define STACK_ANALYZER_EBPF #include "sa_common.h" +#include #define PF_KTHREAD 0x00200000 @@ -79,6 +80,9 @@ #define TS bpf_ktime_get_ns() +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0) +#define CHECK_FREQ(_ts) +#else /* 内置函数: bool __atomic_compare_exchange_n ( @@ -113,6 +117,7 @@ __ATOMIC_RELAXED, __ATOMIC_RELAXED)) \ return 0; \ } +#endif #define GET_CURR \ (struct task_struct *)bpf_get_current_task() @@ -129,9 +134,15 @@ #define GET_KNODE(_task) \ BPF_CORE_READ(_task, cgroups, dfl_cgrp, kn) +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0) +#define CHECK_CGID(_knode) \ + if (target_cgroupid > 0 && BPF_CORE_READ(_knode, id.id) != target_cgroupid) \ + return 0; +#else #define CHECK_CGID(_knode) \ if (target_cgroupid > 0 && BPF_CORE_READ(_knode, id) != target_cgroupid) \ return 0; +#endif #define TRY_SAVE_INFO(_task, _pid, _tgid, _knode) \ if (!bpf_map_lookup_elem(&pid_info_map, &_pid)) \ diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/eBPFStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/eBPFStackCollector.cpp index ee599ec51..d3aa81547 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/eBPFStackCollector.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/eBPFStackCollector.cpp @@ -24,6 +24,7 @@ #include #include #include +#include std::string getLocalDateTime(void) { @@ -53,25 +54,44 @@ std::vector *StackCollector::sortedCountList(void) auto val_size = bpf_map__value_size(psid_count_map); auto value_fd = bpf_object__find_map_fd_by_name(obj, "psid_count_map"); + auto D = new std::vector(); +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0) + for (psid prev_key = {0}, curr_key = {0};; prev_key = curr_key) + { + if (bpf_map_get_next_key(value_fd, &prev_key, &curr_key)) + { + if (errno != ENOENT) + perror("map get next key error"); + break; // no more keys, done + } + if (showDelta) + bpf_map_delete_elem(value_fd, &prev_key); + char val[val_size]; + memset(val, 0, val_size); + if (bpf_map_lookup_elem(value_fd, &curr_key, &val)) + { + if (errno != ENOENT) + { + perror("map lookup error"); + break; + } + continue; + } + CountItem d(curr_key, count_values(val)); + D->insert(std::lower_bound(D->begin(), D->end(), d), d); + } +#else auto keys = new psid[MAX_ENTRIES]; auto vals = new char[MAX_ENTRIES * val_size]; uint32_t count = MAX_ENTRIES; psid next_key; int err; if (showDelta) - { err = bpf_map_lookup_and_delete_batch(value_fd, NULL, &next_key, keys, vals, &count, NULL); - } else - { err = bpf_map_lookup_batch(value_fd, NULL, &next_key, keys, vals, &count, NULL); - } if (err == EFAULT) - { return NULL; - } - - auto D = new std::vector(); for (uint32_t i = 0; i < count; i++) { CountItem d(keys[i], count_values(vals + val_size * i)); @@ -79,6 +99,7 @@ std::vector *StackCollector::sortedCountList(void) } delete[] keys; delete[] vals; +#endif return D; }; diff --git a/eBPF_Supermarket/kvm_watcher/docs/grafana_kvm_watcher_dashboard.json b/eBPF_Supermarket/kvm_watcher/docs/grafana_kvm_watcher_dashboard.json new file mode 100644 index 000000000..166cc6917 --- /dev/null +++ b/eBPF_Supermarket/kvm_watcher/docs/grafana_kvm_watcher_dashboard.json @@ -0,0 +1,522 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 5, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"DELAY(us)\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "mmio_delay", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"DELAY\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "irq_delay", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 16 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"MAX_TIME\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"min_time\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"max_time\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "C", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"total_time\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "D", + "useBackend": false + } + ], + "title": "vcpu_load", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 24 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"MAX_TIME\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"MIN_TIME\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "cdncx8i00775sa" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "bpf_metrics{bpf_out_data=\"TOTAL_TIME\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "C", + "useBackend": false + } + ], + "title": "vm_exit", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "123123", + "uid": "edonx3cyzyyv4d", + "version": 1, + "weekStart": "" +} \ No newline at end of file