เริ่มต้นใช้งาน API ที่แซนด์บ็อกซ์

ในหน้านี้ คุณจะได้เรียนรู้วิธีสร้างไลบรารี C/C++ แบบแซนด์บ็อกซ์ของคุณเองด้วย Sandboxed API (SAPI) ใช้เอกสารนี้เป็นแนวทางควบคู่ไปกับตัวอย่างและเอกสารโค้ดในไฟล์ส่วนหัว

สร้างทรัพยากร Dependency

ต้องติดตั้งทรัพยากร Dependency ต่อไปนี้ในระบบ

  • เคอร์เนล Linux ที่รองรับ UTS, IPC, ผู้ใช้, PID และเนมสเปซของเครือข่าย
  • ส่วนหัว Linux userspace API
  • วิธีคอมไพล์โค้ด: GCC 6 (แนะนำให้ใช้เวอร์ชัน 7 หรือสูงกว่า) หรือ Clang 7 (หรือสูงกว่า)
  • สําหรับไฟล์ส่วนหัวที่สร้างอัตโนมัติ: การเชื่อมโยง Clang Python
  • Python 3.5 ขึ้นไป
  • Bazel เวอร์ชัน 2.2.0 หรือ CMake เวอร์ชัน 3.12 ขึ้นไป
    • CMake เท่านั้น: GNU Make หรือเวอร์ชันของส่วนหัวไลบรารี libcap และเครื่องมือบิลด์ เช่น Ninja (แนะนำ)

การใช้ Bazel

Bazel เป็นระบบบิลด์ที่แนะนำและผสานรวมได้ง่ายที่สุด

เอกสารของเราใช้คอมไพเลอร์ Clang หากต้องการเครื่องมือเชนที่เฉพาะเจาะจง (เช่น คอมไพเลอร์, Linker ฯลฯ) โปรดอ่านเอกสารของ Belle เพื่อดูวิธีเปลี่ยนเชนเครื่องมือคอมไพเลอร์เริ่มต้น

Debian 10 (ป้องกัน)

วิธีติดตั้งทรัพยากร Dependency ของบิลด์

echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \
  sudo tee /etc/apt/sources.list.d/bazel.list
wget -qO - https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install -qy build-essential linux-libc-dev bazel python3 \
  python3-pip libclang-dev
pip3 install clang

เจนทู

ตัวเลือกเคอร์เนลที่จำเป็น:

General setup  --->
-*- Namespaces support
[*]   UTS namespace
[*]   IPC namespace
[*]   User namespace (EXPERIMENTAL)
[*]   PID Namespaces
[*]   Network namespace

วิธีติดตั้งทรัพยากร Dependency ของบิลด์

emerge dev-util/bazel dev-python/typing dev-python/clang-python

การใช้ CMake

CMake เป็นระบบสร้างเมตาโอเพนซอร์สยอดนิยมที่สร้างไฟล์โปรเจ็กต์สำหรับเครื่องมือสร้าง เช่น Ninja หรือ Make

Debian 10 (ป้องกัน)

วิธีติดตั้งทรัพยากร Dependency ของบิลด์

sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \
  python3 python3-pip libclang-dev libcap-dev
pip3 install absl-py clang

เจนทู

ตัวเลือกเคอร์เนลที่จำเป็น:

General setup  --->
-*- Namespaces support
[*]   UTS namespace
[*]   IPC namespace
[*]   User namespace (EXPERIMENTAL)
[*]   PID Namespaces
[*]   Network namespace

วิธีติดตั้งทรัพยากร Dependency ของบิลด์

emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-python

กระบวนการพัฒนา

ในการทำแซนด์บ็อกซ์กับไลบรารี C/C++ คุณจะต้องเตรียมรายการ 2 รายการสำหรับโปรเจ็กต์ของคุณ ดังนี้

คุณอาจคุ้นเคยกับ zlib จากตัวอย่าง Sandbox2 ที่นี่ซึ่งทั้งโปรแกรม (zpipe.c) ถูกแซนด์บ็อกซ์ไว้ ในขั้นตอนต่อไปนี้ คุณจะได้เรียนรู้วิธีใช้ SAPI เพื่อทำแซนด์บ็อกซ์ของไลบรารี zlib และใช้ประโยชน์จากไลบรารีที่แซนด์บ็อกซ์ไว้

1. เลือกฟังก์ชันที่จำเป็น

หากคุณดูโค้ดโฮสต์ของ zlib (main_zlib.cc) คุณจะเห็นได้ว่าฟังก์ชันการทำงานของเครื่องมือคือการอ่านข้อมูลจาก stdin และใช้ฟังก์ชัน deflate() ของ zlib เพื่อบีบอัดข้อมูลจนกว่าจะมีการอ่านเครื่องหมาย EOF โดยรวมแล้ว โปรแกรมนี้ใช้ฟังก์ชัน 3 อย่างจาก zlib ดังนี้

  • deflateInit_(): วิธีเริ่มต้นสำหรับการบีบอัด
  • deflate(): เพื่อบีบอัดกลุ่มข้อมูล
  • deflateEnd(): วิธีสิ้นสุดการบีบอัดและปล่อยโครงสร้างข้อมูลที่จัดสรรแบบไดนามิก

ในชีวิตจริง คุณจะตรวจสอบไลบรารี C/C++ และตัดสินใจว่าจำเป็นต้องใช้ฟังก์ชันใดบ้าง กลยุทธ์ที่เป็นไปได้คือ การเริ่มต้นด้วยโค้ดโฮสต์และใช้ไลบรารีที่ไม่ได้อยู่ในแซนด์บ็อกซ์ จากนั้นในขั้นที่ 2 คุณสามารถสร้างไลบรารีแซนด์บ็อกซ์ และปรับโค้ดโฮสต์เพื่อใช้การเรียกฟังก์ชันที่ทำแซนด์บ็อกซ์

2. เขียนกฎการสร้าง sapi_library

หลังจากระบุฟังก์ชัน zlib ทั้ง 3 รายการที่จำเป็นต้องใช้จากไลบรารี zlib ที่ทำแซนด์บ็อกซ์แล้ว คุณจะกำหนดกฎการสร้างในไฟล์ BUILD ได้ เอกสารสำหรับกฎการสร้าง sapi_library จะมีอยู่ในหน้าสร้างกฎ

ข้อมูลโค้ดด้านล่างแสดงคําจํากัดความของ sapi_library สําหรับตัวอย่าง zlib SAPI เมื่อใช้แอตทริบิวต์ lib Bazel จะได้รับคำสั่งให้หาไลบรารี zlib ในไฟล์ WORKSPACE

sapi_library(
    name = "zlib-sapi",
    srcs = [],
    hdrs = [],
    functions = [
        "deflateInit_",
        "deflate",
        "deflateEnd",
    ],
    lib = "@net_zlib//:zlib",
    lib_name = "Zlib",
    namespace = "sapi::zlib",
)

ผลที่ได้คือระบบจะสร้างไลบรารี zlib ที่ทำแซนด์บ็อกซ์ เอาต์พุตคือออบเจ็กต์ SAPI ซึ่งสามารถรวมไว้ในโค้ดโฮสต์และใช้เพื่อสื่อสารกับไลบรารีที่ทำแซนด์บ็อกซ์ผ่านการเรียก RPC นโยบายแซนด์บ็อกซ์ที่ใช้ในตัวอย่างนี้เป็นนโยบายเริ่มต้น

3. เขียนหรือเปลี่ยนโค้ดโฮสต์

ถึงเวลารวมไลบรารี SAPI ที่สร้างขึ้นกับโค้ดโฮสต์แล้ว

สร้างแซนด์บ็อกซ์

ใช้ sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create()); เพื่อสร้างออบเจ็กต์แซนด์บ็อกซ์

ใช้ sapi::zlib::ZlibApi api(&sandbox); เพื่อสร้างอินสแตนซ์ออบเจ็กต์ SAPI ซึ่งทำให้ฟังก์ชันแซนด์บ็อกซ์พร้อมใช้งาน

ใช้ประเภท SAPI

ประเภท SAPI คือประเภทพิเศษในรูปแบบคลาส C++ ที่ SAPI มีให้ เนื่องจากบางครั้งประเภท C ปกติจะใช้ไม่ได้

คุณจะดูการใช้ประเภท SAPI ครั้งแรกได้ในการประกาศ strm ซึ่งเป็นส่วนที่ใช้โครงสร้าง SAPI: sapi::v::Struct<sapi::zlib::z_stream> strm;

ประเภทเทมเพลต (sapi::zlib::z_stream) เป็นตัวอย่างที่ดีของโค้ดที่สร้างขึ้นโดยกฎการสร้างโดยอัตโนมัติ

ดูรายละเอียดเพิ่มเติมที่หน้าตัวแปร

เรียก API

หากต้องการเรียกใช้ defalteInit_, deflate หรือ deflateEnd ให้ใช้ออบเจ็กต์ SAPI หากคุณตัดสินใจที่จะใช้วิธี "เปลี่ยนแปลง" คุณต้องตรวจสอบว่าพารามิเตอร์ของฟังก์ชันตรงกับค่าที่คาดไว้

ตัวอย่างการเรียกแต่ละครั้งในตัวอย่าง zlib

  • api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION,
        version.PtrBefore(), sizeof(sapi::zlib::z_stream));
  • api.deflate(strm.PtrBoth(), flush);
  • api.deflateEnd(strm.PtrBoth()).IgnoreError();

การใช้ธุรกรรม SAPI

SAPI จะแยกโค้ดโฮสต์ออกจากไลบรารีแซนด์บ็อกซ์และทำให้ผู้เรียกใช้สามารถรีสตาร์ทหรือล้มเลิกคำขอการประมวลผลข้อมูลที่มีปัญหาได้ ธุรกรรม SAPI จะล้ำหน้าไปอีกขั้นและทำซ้ำกระบวนการที่ล้มเหลวโดยอัตโนมัติ

ดูรายละเอียดเพิ่มเติมได้ที่หน้าธุรกรรม SAPI

ตัวอย่าง

ในส่วนตัวอย่าง คุณจะเห็นไลบรารีบางรายการที่ทีม SAPI จัดเตรียมไว้ให้แล้ว