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

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

ทรัพยากร Dependency ของบิลด์

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

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

การใช้ Bazel

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

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

Debian 10 (Buster)

วิธีติดตั้งการอ้างอิงบิลด์

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

Gentoo

ต้องระบุตัวเลือกเคอร์เนลต่อไปนี้

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

วิธีติดตั้งการอ้างอิงบิลด์

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

การใช้ CMake

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

Debian 10 (Buster)

วิธีติดตั้งการอ้างอิงบิลด์

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

Gentoo

ต้องระบุตัวเลือกเคอร์เนลต่อไปนี้

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

วิธีติดตั้งการอ้างอิงบิลด์

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คําจํากัดความสําหรับ SAPI ของ zlib ตัวอย่าง การใช้แอตทริบิวต์ 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 Object หากตัดสินใจใช้แนวทาง "เปลี่ยน" คุณต้องตรวจสอบว่า พารามิเตอร์ฟังก์ชันตรงกับค่าที่คาดไว้

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

  • 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 Transaction จะก้าวไปอีกขั้นและทำกระบวนการที่ไม่สำเร็จซ้ำโดยอัตโนมัติ

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

ตัวอย่าง

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