BPF开发: 从Hello World开始

news2024/11/24 14:39:10

Part 1 概述

1. 背景

BPF技术被列为近些年Linux内核领域最火热的新领域之一。它成功的给Linux内核赋予了少量的动态可编程性,可以在Linux内核运行时,实时修改内核的行为,但不需要重新编译和重启内核。据此,BPF在Linux世界中:

  • 网络
  • 可观测性
  • 安全

三大领域大放异彩,学习好BPF技术,对于Linux内核和应用开发者来说,是一件非常有意义的事情。

2. 什么是BPF?

BPF在Linux内核中,被实现为一个非常精简的虚拟机,具有几乎性能无损的执行效率。我们可以用类似C语言的语法,编写代码,编译成可以在BPF虚拟机中运行的汇编代码,实现其强大的逻辑处理能力。

今天,我们将从 Hello World 开始,带您进入 BPF 的世界。

3. 开始BPF

按照计算机程序设计语言学习的传统,我们从经典的Hello World程序开始我们的eBPF开发之旅。首先简单对比下标准C程序和eBPF程序的异同。

C语言程序

# HelloWorld.c

#include <stdio.h>

int main()
{
 printf("HelloWorld\n");
 return 0;
}

# C语言的编译与运行

eBPF程序

# HelloWorld.bpf.c

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

int helloworld(void *ctx)
{
 bpf_printk("Hello world!\n");
 return 0;
}

# eBPF程序的编译与运行

eBPF的编译、加载、运行比标准C程序要麻烦一些。接下来会一步一步介绍全流程。

Part 2 开发环境

我们使用vagrant + virtualbox +Ubuntu22.04组建我们的开发环境。注意,只支持X86的CPU(Windows, Linux或Mac)。苹果M芯片不支持。

保存虚拟机描述文件Vagrantfile:

Vagrant.configure('2') do |config|
  config.vm.define 'bpf' do |bpf|
    bpf.vm.provider 'virtualbox' do |vb|
      vb.gui = false
      vb.memory = '4096'
      vb.cpus = 2
    end
    bpf.vm.synced_folder '.', '/vagrant', disabled: true
    bpf.vm.box = 'bento/ubuntu-22.04'
    bpf.vm.network 'private_network', type: 'dhcp'
    bpf.vm.provision 'shell', inline: <<-SHELL
        set -x
        set -e
        apt-get install -y linux-tools-generic linux-tools-$(uname -r) gcc-multilib clang libbpf0 libbpf-dev
    SHELL
  end
end

一些常用命令:

  • vagrant up: 启动虚拟机
  • vagrant halt: 关闭虚拟机电源
  • vagrant detroy: 销毁虚拟机
  • vagrant ssh: 登入虚拟机

Part 3 开始开发


以上文提到的HelloWorld.bpf.c为例子。

1. 编译eBPF

生成eBPF字节码,并带有调试信息:

clang -target bpf -Wall -O2 -g -c HelloWorld.bpf.c -o HelloWorld.o

查看eBPF编译后的字节码:

llvm-objdump -d -r -S --print-imm-hex HelloWorld.o
root@vagrant:~# llvm-objdump -d -r -S --print-imm-hex HelloWorld.o

HelloWorld.o:   file format elf64-bpf

Disassembly of section .text:

0000000000000000 <helloworld>:
; {
       0:       b7 01 00 00 0a 00 00 00 r1 = 0xa
;  bpf_printk("Hello world!\n");
       1:       6b 1a fc ff 00 00 00 00 *(u16*)(r10 - 0x4) = r1
       2:       b7 01 00 00 72 6c 64 21 r1 = 0x21646c72
       3:       63 1a f8 ff 00 00 00 00 *(u32*)(r10 - 0x8) = r1
       4:       18 01 00 00 48 65 6c 6c 00 00 00 00 6f 20 77 6f r1 = 0x6f77206f6c6c6548 ll
       6:       7b 1a f0 ff 00 00 00 00 *(u64*)(r10 - 0x10) = r1
       7:       bf a1 00 00 00 00 00 00 r1 = r10
       8:       07 01 00 00 f0 ff ff ff r1 += -0x10
;  bpf_printk("Hello world!\n");
       9:       b7 02 00 00 0e 00 00 00 r2 = 0xe
      10:       85 00 00 00 06 00 00 00 call 0x6
;  return 0;
      11:       b7 00 00 00 00 00 00 00 r0 = 0x0
      12:       95 00 00 00 00 00 00 00 exit

这一坨eBPF汇编代码,感兴趣的同学可以参考eBPF Instruction Set Specification, v1.0[link:https://docs.kernel.org/bpf/standardization/instruction-set.html]

2. 运行BPF

流程

Linux内核中支持eBPF的事件很多。挂载eBPF程序后,需要等待事件异步触发才能看到效果。

加载eBPF字节码

Linux内核官方工具bpftool帮我们封装了对eBPF字节码各种操作。本文我们用它来挂载和调试eBPF。

# 在内核生成eBPF文件结构

eBPF在Linux内核以特殊文件形式存在,如果进程退出了则会自动销毁。为了让eBPF程序独立于进程持久存在于Linux内核中,内核提供了bpf文件系统,可以把eBPF程序pin在其中。Ubuntu 22.04默认挂载了bpf文件系统,位于/sys/fs/bpf,可以直接使用。

现在的eBPF字节码只是一段单纯的代码,要把它传入内核,还需要指定该eBPF字节码的类型,可以通过bpftool feature列出内核支持的所有eBPF类型:

 
...
Scanning eBPF program types...
eBPF program_type socket_filter is available
eBPF program_type kprobe is available
eBPF program_type sched_cls is available
eBPF program_type sched_act is available
eBPF program_type tracepoint is available
eBPF program_type xdp is available
eBPF program_type perf_event is available
eBPF program_type cgroup_skb is available
eBPF program_type cgroup_sock is available
eBPF program_type lwt_in is available
eBPF program_type lwt_out is available
...

HelloWorld.bpf.c是一个"万能"的eBPF程序,因为它仅仅输出"HelloWorld",因此,它可以指定为任何eBPF程序类型,这里我们选用raw_tracepoint。

bpftool prog load HelloWorld.o /sys/fs/bpf/HelloWorld type raw_tracepoint

现在可以在/sys/fs/bpf/中看到:

root@vagrant:~# ls /sys/fs/bpf/HelloWorld
/sys/fs/bpf/HelloWorld

或者:

root@vagrant:~# bpftool prog show pinned /sys/fs/bpf/HelloWorld
353: raw_tracepoint  name helloworld  tag fc3c56cde923df12  gpl
        loaded_at 2023-03-11T01:59:48+0000  uid 0
        xlated 104B  jited 71B  memlock 4096B
        btf_id 118

这说明我们的eBPF程序已经成功加载到内核中。

#把内核中的eBPF程序挂载到事件上

正常情况下,我们会把eBPF挂载到特定事件上,然后等待事件异步触发时,再执行eBPF程序。

本文我们为了方便,选择最简单的,用于调试和测试用的接口:BPF_PROG_TEST_RUN,也叫BPF_PROG_RUN,

他们是完全等价的。这个接口可以直接同步执行eBPF程序,而不需要挂载到事件上再等待事件异步发生。

BPF_PROG_TEST_RUN只支持有限的eBPF程序类型:

BPF_PROG_TYPE_SOCKET_FILTER
BPF_PROG_TYPE_SCHED_CLS
BPF_PROG_TYPE_SCHED_ACT
BPF_PROG_TYPE_XDP
BPF_PROG_TYPE_SK_LOOKUP
BPF_PROG_TYPE_CGROUP_SKB
BPF_PROG_TYPE_LWT_IN
BPF_PROG_TYPE_LWT_OUT
BPF_PROG_TYPE_LWT_XMIT
BPF_PROG_TYPE_LWT_SEG6LOCAL
BPF_PROG_TYPE_FLOW_DISSECTOR
BPF_PROG_TYPE_STRUCT_OPS
BPF_PROG_TYPE_RAW_TRACEPOINT
BPF_PROG_TYPE_SYSCALL

上文我们把eBPF字节码指定为raw_tracepoint,正好满足该接口的要求。

利用bpftool使用BPF_PROG_TEST_RUN接口来运行它(参数如何设置,之后会有专题分析,这里不要修改bpftool参数):

bpftool prog run pinned /sys/fs/bpf/HelloWorld repeat 0

查看输出结果:

root@vagrant:~# cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 1/1   #P:4
#
#                                _-----=> irqs-off
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| / _-=> migrate-disable
#                              |||| /     delay
#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
#              | |         |   |||||     |         |
         bpftool-39498   [001] d.... 979047.864950: bpf_trace_printk: Hello world!

OK,我们现在成功的执行了第一个最简单的BPF程序。

Part 4 BPF in MatrixOne

MatrixOne作为我司主打数据库产品,未来在MatrixOne中将全面使用BPF技术,用于增强数据库集群的性能,稳定性和安全性。

网络

MatrixOne作为云原生数据库,运行在标准的Kubernetes集群中,网络是其最重要的基础设施之一。我们将利用BPF技术,减少Linux内核网络协议栈的开销,实现MatrixOne的网络性能优化。

可观测性

我们将在自带的可观测性组件中,利用BPF实时采集和分析数据库运行时的各种指标,用于自动化分析和故障诊断。同时,我们将提供一系列BPF工具,用于SRE人工分析和调优MatrixOne。

安全性

我们将在附属的安全组件中,提供基于BPF得关键操作监控和禁止操作,用于实时检测和防御数据库的安全威胁。

关于MatrixOne

MatrixOne 是一款基于云原生技术,可同时在公有云和私有云部署的多模数据库。该产品使用存算分离、读写分离、冷热分离的原创技术架构,能够在一套存储和计算系统下同时支持事务、分析、流、时序和向量等多种负载,并能够实时、按需的隔离或共享存储和计算资源。云原生数据库MatrixOne能够帮助用户大幅简化日益复杂的IT架构,提供极简、极灵活、高性价比和高性能的数据服务。

MatrixOne企业版和MatrixOne云服务自发布以来,已经在互联网、金融、能源、制造、教育、医疗等多个行业得到应用。得益于其独特的架构设计,用户可以降低多达70%的硬件和运维成本,增加3-5倍的开发效率,同时更加灵活的响应市场需求变化和更加高效的抓住创新机会。在相同硬件投入时,MatrixOne可获得数倍以上的性能提升。

MatrixOne秉持开源开放、生态共建的理念,核心代码全部开源,全面兼容MySQL协议,并与合作伙伴打造了多个端到端解决方案,大幅降低用户的迁移和使用成本,也帮助用户避免了供应商锁定风险。

关键词:超融合数据库、多模数据库、云原生数据库、国产数据库

MatrixOrigin 官网:新一代超融合异构开源数据库-矩阵起源(深圳)信息科技有限公司 MatrixOne

Github 仓库:GitHub - matrixorigin/matrixone: Hyperconverged cloud-edge native database

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1422473.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用.NET6 Avalonia开发跨平台三维应用

本文介绍在Vistual Studio 2022中使用Avalonia和集成AnyCAD Rapid AvaloniaUI三维控件的过程。 0 初始化环境 安装Avalonia.Templates dotnet new install Avalonia.Templates若之前安装过可忽略此步骤。 1 创建项目 选择创建AvaloniaUI项目 选一下.NET6版本和Avalonia版…

ADB的配置和使用及刷机root

ADB的配置和使用 ADB即Android Debug Bridge&#xff0c;安卓调试桥&#xff0c;是谷歌为安卓开发者提供的开发工具之一&#xff0c;可以让你的电脑以指令窗口的方式控制手机。可以在安卓开发者网页中的 SDK 平台工具页面下直接下载对应系统的 adb 配置文件&#xff0c;大小只…

腾讯云0基础10秒搭建幻兽帕鲁游戏联机服务器

幻兽帕鲁&#xff08;Palworld&#xff09;是一款多人在线游戏&#xff0c;为了获得更好的游戏体验&#xff0c;需要搭建一个稳定、高效的游戏联机服务器。腾讯云提供了一种简单、快速的方法&#xff0c;让新手小白也能0基础10秒搭建幻兽帕鲁游戏联机服务器&#xff01; 本文将…

人工视觉仍然需要图像采集卡

最初&#xff0c;图像采集卡被用作模拟视频数字转换器和图像缓冲器&#xff0c;但如今它们能够执行复杂的任务&#xff0c;例如图像处理。图像采集卡的设计不断发展&#xff0c;旨在提高系统性能并减少计算机处理需求。 除了图像采集之外&#xff0c;图像采集卡还执行机器视觉…

【前端-VUE+TS】Vue3组件化-下(五)

一. 插槽的使用 1.1. 认识插槽slot 在开发中&#xff0c;我们会经常封装一个个可复用的组件&#xff1a; 前面我们会通过props传递给组件一些数据&#xff0c;让组件来进行展示&#xff1b;但是为了让这个组件具备更强的通用性&#xff0c;我们不能将组件中的内容限制为固定的d…

如何在Excel中清除单元格的格式?这里有详细步骤

Microsoft Excel提供了大量样式选项来自定义电子表格的外观。但是&#xff0c;如果你需要删除格式&#xff0c;则可以很容易地删除选定单元格和整个工作表的格式。我们将向你展示如何操作。 ​注意&#xff1a;清除格式只会删除文本的样式&#xff1b;将保留你的实际文本。 如…

基于Android的成人教育课程学习考试系统uniAPP的 小程序_12lo1

APP性能需求 &#xff08;1&#xff09;会员在安卓App页面各种操作可及时得到反馈。 &#xff08;2&#xff09;该平台是提供给多个会员使用的平台&#xff0c;会员使用之前需要注册登录。登录验证后&#xff0c;会员才可进行各种操作[10]。 &#xff08;3&#xff09;管理员用…

在线视频链接怎么做成二维码?扫码播放在线视频的制作方法

怎么把在线视频链接做成二维码图片分享给其他人呢&#xff1f;现在通过二维码来传递内容是很多人在用的一种方式&#xff0c;比如文件、视频、音频、网址等都可以用二维码生成器来做成二维码图片后使用。 采用二维码图片的方式可以有效的降低成本&#xff0c;提高传播的速度&a…

马哈鱼SQLFlow Lite的python版本

Gudu SQLFlow 是一款用来分析各种数据库的 SQL 语句和存储过程来获取复杂的数据血缘关系并进行可视化的工具。 Gudu SQLFlow Lite version for python 可以让 python 开发者把数据血缘分析和可视化能力快速集成到他们自己的 python 应用中。 Gudu SQLFlow Lite version for p…

【web | CTF】攻防世界 easyupload

天命&#xff1a;好像也不太easy 目录 步骤一&#xff1a;准备文件 步骤二&#xff1a;上传文件 本条题目有好几个防御点&#xff1a; 后缀名防御&#xff1a;只能上传图片格式内容防御&#xff1a;内容不能有php图片头防御&#xff1a;检测文件的头部信息&#xff0c;是否是…

[NCTF2019]Fake XML cookbook(特详解)

先试了一下弱口令&#xff0c;哈哈习惯了 查看页面源码发现xml function doLogin(){var username $("#username").val();var password $("#password").val();if(username "" || password ""){alert("Please enter the usern…

iZotope RX 10.4.2 mac激活版 音频修复和增强工具

iZotope RX 10 for Mac是一款专业的音频修复软件&#xff0c;旨在提供强大、精确的工具&#xff0c;让用户能够清晰、纯净地处理音频。以下是其主要功能和特点&#xff1a; 软件下载&#xff1a;iZotope RX 10.4.2 mac激活版下载 强大的降噪功能&#xff1a;iZotope RX 10采用了…

Mushroom Monsters - Fantasy RPG

蘑菇怪物PBR是一个2米高的生物。他可以摆出三种静态姿势中的任何一种,等待他的对手感到惊讶,或者他可以四处奔跑,攻击和施放法术,甚至冲锋。他用头撞击敌人,可以跳起来撞击他们,也可以低头直冲。他还有一个“魔法”攻击,扭动头部并切削。 使用混合形状功能将网格变形为无…

【项目日记(六)】第二层: 中心缓存的具体实现(下)

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:项目日记-高并发内存池⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你做项目   &#x1f51d;&#x1f51d; 开发环境: Visual Studio 2022 项目日…

fullcalendar案例

fullcalendar案例 <script srchttps://cdn.jsdelivr.net/npm/fullcalendar6.1.10/index.global.min.js></script><script srchttps://code.jquery.com/jquery-3.6.0.min.js></script> <!-- 引入 jQuery CDN --><script>document.addEventL…

防御挂马攻击:从防御到清除的最佳实践

挂马攻击&#xff0c;也称为马式攻击&#xff08;Horse Attack&#xff09;&#xff0c;是一种常见的网络攻击手段。攻击者通过在目标服务器或网站中植入恶意程序&#xff0c;以获取系统权限或窃取敏感信息。为了应对这种威胁&#xff0c;本文将重点介绍防御挂马攻击的最佳实践…

D6282——4.6W 双路音频功率放大电路,开机噪音小内置热保护电路,最佳电源电压 9V、12V, 工作电源电压范围:Vcc=6~15V

D6282 是双路音频功率放大集成电路&#xff0c;内置温度过热保护电路、功率调 整开关。适用于便携式收录机作音频功率放大。 该电路采用 FSIP12 的封装形式封装。 主要特点&#xff1a;  输出功率大 P OUT 2.5W/CH( 典型 ) (Vcc9V,R L 4 Ω ,f1kHz,THD10%) P OUT 4.6W/…

深度学习与神经网络pytorch版 2.3 线性代数

深度学习与神经网络pytorch版 2.3 线性代数 目录 深度学习与神经网络pytorch版 2.3 线性代数 1. 简介 2. 线性代数 2.3.1 标量 ​编辑2.3.2 向量 2.3.3 矩阵 2.3.4 张量及其性质 2.3.5 降维 2.3.6 非降维求和 2.3.7 点积 2.3.8 矩阵-向量积 2.3.9 矩阵-矩阵乘法 …

什么是八木天线,八木天线的作用是什么?

八木天线的得名其实不是由于其有八根天线。 八木天线由一个有源振子&#xff08;一般用折合振子&#xff09;、一个无源反射器和若干个无源引向器平行排列而成的端射式天线&#xff0c;由提出者的名字命名。 上个世纪二十年代&#xff0c;日本东北大学的八木秀次和宇田太郞两人…

JS逆向实战27——pdd的anti_content 分析与逆向

声明 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; 本文已在微信公众号发布 …