From a453f4b7068611c510f75c5a75db0386d5d13211 Mon Sep 17 00:00:00 2001
From: hcy1012 <690765764@qq.com>
Date: Thu, 24 Mar 2022 10:11:06 +0800
Subject: [PATCH 01/42] updated releasenotes docs of master
---
...mon-vulnerabilities-and-exposures-(cve).md | 2 +-
.../en/docs/Releasenotes/installing-the-os.md | 30 +++++++--------
docs/en/docs/Releasenotes/key-features.md | 37 +++++++++++--------
docs/en/docs/Releasenotes/release_notes.md | 2 +-
docs/en/docs/Releasenotes/user-notice.md | 5 ++-
docs/en/menu/index.md | 2 +-
6 files changed, 43 insertions(+), 35 deletions(-)
diff --git a/docs/en/docs/Releasenotes/common-vulnerabilities-and-exposures-(cve).md b/docs/en/docs/Releasenotes/common-vulnerabilities-and-exposures-(cve).md
index 4286b2459..1485fd759 100644
--- a/docs/en/docs/Releasenotes/common-vulnerabilities-and-exposures-(cve).md
+++ b/docs/en/docs/Releasenotes/common-vulnerabilities-and-exposures-(cve).md
@@ -1,4 +1,4 @@
# Common Vulnerabilities and Exposures (CVEs)
-For CVEs involved in the version, see the [CVE list](https://www.openeuler.org/en/security/cve/).
+For details about the CVEs involved in the version, see the [CVE list](https://www.openeuler.org/en/security/cve/).
diff --git a/docs/en/docs/Releasenotes/installing-the-os.md b/docs/en/docs/Releasenotes/installing-the-os.md
index 46cb1a80c..80f737499 100644
--- a/docs/en/docs/Releasenotes/installing-the-os.md
+++ b/docs/en/docs/Releasenotes/installing-the-os.md
@@ -1,20 +1,20 @@
-# Installing the OS
+# OS Installation
## Release Files
-The openEuler release files include [ISO release pacakges](http://repo.openeuler.org/openEuler-21.09/ISO/), [VM images](http://repo.openeuler.org/openEuler-21.09/virtual_machine_img/), [containier images](http://repo.openeuler.org/openEuler-21.09/docker_img/), [edge images](http://repo.openeuler.org/openEuler-21.09/edge_img/), [embedded images](https://repo.openeuler.org/openEuler-21.09/edge_img/), and [repo sources](http://repo.openeuler.org/openEuler-21.09/). The following tables describe those files respectively.
+The openEuler release files include [ISO release packages](http://repo.openeuler.org/openEuler-22.03-LTS/ISO/), [VM images](http://repo.openeuler.org/openEuler-22.03-LTS/virtual_machine_img/), [container images](http://repo.openeuler.org/openEuler-22.03-LTS/docker_img/), and [repo sources](http://repo.openeuler.org/openEuler-22.03-LTS/). The following tables describe those files respectively.
Table 1 ISO release packages
| Name | Description |
| ------------------------------------------ | ------------------------------------------------------------ |
-| openEuler-21.03-aarch64-dvd.iso | Basic installation ISO file of the AArch64 architecture, including the core components for running the minimum system. |
-| openEuler-21.03-everything-aarch64-dvd.iso | Full installation ISO file of the AArch64 architecture, including all components for running the entire system. |
-| openEuler-21.03-debuginfo-aarch64-dvd.iso | ISO file for openEuler debugging in the AArch64 architecture, including the symbol table information required for debugging. |
-| openEuler-21.03-x86_64-dvd.iso | Basic installation ISO file of the x86_64 architecture, including the core components for running the minimum system. |
-| openEuler-21.03-everything-x86_64-dvd.iso | Full installation ISO file of the x86_64 architecture, including all components for running the entire system. |
-| openEuler-21.03-debuginfo-x86_64-dvd.iso | ISO file for openEuler debugging in the x86_64 architecture, including the symbol table information required for debugging. |
-| openEuler-21.03-source-dvd.iso | ISO file of the openEuler source code. |
+| openEuler-22.03-LTS-aarch64-dvd.iso | Base installation ISO file of the AArch64 architecture, including the core components for running the minimum system. |
+| openEuler-22.03-LTS-everything-aarch64-dvd.iso | Full installation ISO file of the AArch64 architecture, including all components for running the entire system. |
+| openEuler-22.03-LTS-everything-debug-aarch64-dvd.iso | ISO file for openEuler debugging in the AArch64 architecture, including the symbol table information required for debugging. |
+| openEuler-22.03-LTS-x86_64-dvd.iso | Base installation ISO file of the x86_64 architecture, including the core components for running the minimum system. |
+| openEuler-22.03-LTS-everything-x86_64-dvd.iso | Full installation ISO file of the x86_64 architecture, including all components for running the entire system. |
+| openEuler-22.03-LTS-everything-debuginfo-x86_64-dvd.iso | ISO file for openEuler debugging in the x86_64 architecture, including the symbol table information required for debugging. |
+| openEuler-22.03-LTS-source-dvd.iso | ISO file of the openEuler source code. |
| openEuler-21.09-edge-aarch64-dvd.iso | Edge ISO file in the AArch64 architecture, including the core components for running the minimum system. |
| openEuler-21.09-edge-x86_64-dvd.iso | Edge ISO file in the x86_64 architecture, including the core components for running the minimum system. |
@@ -22,8 +22,8 @@ Table 2 VM images
| Name | Description |
| -------------------------------- | -------------------------------------------------- |
-| openEuler-21.03.aarch64.qcow2.xz | VM image of openEuler in the AArch64 architecture. |
-| openEuler-21.03.x86_64.qcow2.xz | VM image of openEuler in the x86_64 architecture. |
+| openEuler-22.03-LTS-aarch64.qcow2.xz | VM image of openEuler in the AArch64 architecture. |
+| openEuler-22.03-LTS-x86_64.qcow2.xz | VM image of openEuler in the x86_64 architecture. |
Note: The default password of **root** user of the VM image is **openEuler12#$**. Change the password upon the first login.
@@ -51,7 +51,7 @@ Table 4 Repo sources
## Minimum Hardware Specifications
-The following table lists the minimum hardware specifications for openEuler 21.03.
+The following table lists the minimum hardware specifications for openEuler 22.03 LTS.
Table 1 Minimum hardware requirements
@@ -63,7 +63,7 @@ Table 1 Minimum hardware requirements
## Hardware Compatibility
-The following table lists the supported servers and configurations of openEuler.
+The following table describes the servers and configurations supported by openEuler. openEuler will support more servers in the future. Partners and developers are welcome to participate in the contribution and verification. For details about the servers supported by openEuler, see the [Compatibility List](https://www.openeuler.org/en/compatibility/).
Table 1 Supported servers and configurations
@@ -92,7 +92,7 @@ Table 1 Supported servers and configurations
Memory
|
-32G\*4 2933MHz
+ | 4 x 32 GB 2933 MHz
|
RAID card
@@ -118,7 +118,7 @@ Table 1 Supported servers and configurations
|
Memory
|
-32*4 2400MHz
+ | 4 x 32 GB 2400 MHz
|
RAID card
diff --git a/docs/en/docs/Releasenotes/key-features.md b/docs/en/docs/Releasenotes/key-features.md
index b33be6a0a..648020be1 100644
--- a/docs/en/docs/Releasenotes/key-features.md
+++ b/docs/en/docs/Releasenotes/key-features.md
@@ -16,7 +16,7 @@ In-depth optimizations of scheduling, I/O, and memory management have been perfo
- **Huge page vmalloc performance optimization**: When calling vmalloc() to allocate spaces that exceed the minimum size of huge pages, the huge page instead of the base page is used to map the memory, improving the TLB usage and reducing TLB misses.
-- **Uncorrectable error (UCE) fault tolerance**: When a UCE occurs in the copy-on-write (COW) or pagecache scenario in kernel mode, the system kills the user-mode process instead of panicking. This feature is disabled by default, you can enable it by adding **CONFIG_UCE_KERNEL_RECOVERY** to the kernel configuration, and configure it in the kernel boot parameter interface **/proc/cmdline** (add **uce_kernel_recovery=[0,3]**) and proc interface **/proc/sys/kernel/uce_kernel_recovery**.
+- **Uncorrectable error (UCE) fault tolerance**: When a UCE occurs in the copy_from_user scenario, the system kills the associated user-mode process instead of kernel panicking. This feature is disabled by default. You can enable it by adding **CONFIG_UCE_KERNEL_RECOVERY** to the kernel configuration, and configure it in the kernel boot parameter interface **/proc/cmdline** (add **uce_kernel_recovery=[0,4]**) and proc interface **/proc/sys/kernel/uce_kernel_recovery**.
## File System for New Media
@@ -29,6 +29,10 @@ Various memory and storage media can be used to expand the system memory capacit
- **User-mode swap**: The evicted cold memory can be swapped to the user-mode storage based on a preset etMem policy. The user-mode swap delivers a higher performance than the kernel-mode swap and the whole swap process is transparent to users.
+## User-Mode Protocol Stack
+The Gazelle user-mode protocol stack is added. It can be used without application program modification or recompilation, supporting high-performance and low-latency network transmission for upper-layer services.
+
+- **Gazelle user-mode protocol stack**: Powered by dpdk and lwip, Gazelle is a lock-free and multi-thread high-performance user-mode protocol stack to improve the network performance of applications. It can be used without modification, adaptation, or recompilation.
## Enhanced Cloud Native Scheduling
@@ -36,21 +40,26 @@ In cloud service scenarios, online interactive services are sensitive to latenci
- **Quality Aware Scheduler (QAS)**: It ensures that online tasks quickly preempt CPU resources, schedules tasks in a deterministic manner, and suppresses interference from offline tasks.
- **Memory reclamation for OOM**: When OOM occurs, memory reclamation is preferentially performed for process groups with low priorities to ensure the normal running of online services.
+- **Hybrid container deployment framework**: In a hybrid Kubernetes cluster, openEuler users only need to add online or offline labels to services. The system can automatically detect service creation and configure resources based on service priorities to implement resource isolation and preemption.
+
+## QEMU Hot Patch
+- **LibcarePlus**: It is a hot patch framework that can fix QEMU process bugs without affecting VM services.
## KubeOS
KubeOS is a container operating system, which centrally manages cloud native cluster OSs in containers. It has the following features:
-- Supports OS containerization and Kubernetes interconnection for unified OS management and atomized lifecycle management
-- Supports lightweight OS tailoring, which reduces unnecessary packages for quicker upgrades and replacements.
+- **OS containerization**: Interconnection with Kubernetes facilitates unified OS management and atomized lifecycle management.
+- **Lightweight OS tailoring**: This reduces unnecessary packages for quicker upgrades and replacements.
## Enhanced Lightweight Secure Container
Based on Stratovirt, a lightweight virtualization technology, containers have low load and VMs are more secure.
-- Supports UEFI boot, ACPI table construction, and addition of PCIe/PCI devices (including vrtio-pci) to VMs.
-- Supports VFIO, allowing physical devices on the host to be accessed from VMs and enabling VMs to obtain high performance close to raw devices.
+- **UEFI boot**: Supports UEFI boot, ACPI table construction, and addition of PCIe/PCI devices (including vrtio-pci) to VMs.
+- **VFIO**: It allows physical devices on the host to be accessed from VMs and enables VMs to obtain high performance close to raw devices.
+- **Hot swap of passthrough devices**: Devices such as virtio-blk-pci, virtio-net-pci, and VFIO can be hot swapped. This prevents system shutdown and service interruption caused by peripheral replacement.
## Enhanced iSulad
@@ -80,14 +89,10 @@ Basic capabilities, such as lightweight, security hardening, and lightweight con
- **Security hardening**: Security hardening is performed on resources such as account passwords and file permissions. OS security is enabled by default.
- **Lightweight containers**: Standard container images can be deployed and run in lightweight containers in embedded scenarios.
- **Multi-architecture support**: The ARM32 and ARM64 chip architectures are supported.
-
-## Intelligent O&M A-Ops
-
-The basic intelligent O&M framework provides basic capabilities such as configuration tracing, architecture awareness, and fault locating to support quick troubleshooting and reduce O&M costs.
-
-- **Application topology awareness**: The eBPF-based low-load probe framework provides automatic network topology awareness and detection capabilities at the application level.
-- **Configuration tracing**: implements the configuration baseline and comparison functions and quickly rectify configuration problems.
-- **Intelligent fault locating**: A-Ops supports exception detection and user-defined fault tree, and provides an expert-mode engine to detect system faults in real time and rectify system faults in a timely manner, reducing system downtime and O&M costs.
+- **Hybrid deployment**: Hybrid deployment of real-time and non-real-time planes in the SOC is supported.
+- **Small-scale tailoring**: Small-scale tailoring based on the Yocto build package is supported. ARM Cross Compilation
+- **ARM cross compilation tool**: The ARM cross compilation tool chain is provided based on GCC 10.3 of the community.
+- **Distributed soft bus (DSoftBus)**: The DSoftBus of HarmonyOS is integrated to implement interconnection and interworking between embedded devices running on openEuler.
## secPaver
@@ -106,5 +111,7 @@ secPaver is an SELinux policy development tool used to assist developers in deve
More desktop environments are provided to ensure better development experience.
-- DDE is upgraded and supports drawing board, music, and cinema applications.
-- UKUI is upgraded and supports the Chinese input method and multimedia.
\ No newline at end of file
+- **DDE** is upgraded and supports drawing board, music, and cinema applications.
+- **UKUI** is upgraded and supports the Chinese input method and multimedia.
+- **kiran-desktop** is supported.
+- **GNOME** is supported.
\ No newline at end of file
diff --git a/docs/en/docs/Releasenotes/release_notes.md b/docs/en/docs/Releasenotes/release_notes.md
index 146d127b1..ce3d0b760 100644
--- a/docs/en/docs/Releasenotes/release_notes.md
+++ b/docs/en/docs/Releasenotes/release_notes.md
@@ -1,3 +1,3 @@
# Release Notes
-This document is the release notes for the openEuler 21.03 release version.
\ No newline at end of file
+This document is the release notes of openEuler 22.03 LTS.
\ No newline at end of file
diff --git a/docs/en/docs/Releasenotes/user-notice.md b/docs/en/docs/Releasenotes/user-notice.md
index 65e12ded9..60f0e9f9f 100644
--- a/docs/en/docs/Releasenotes/user-notice.md
+++ b/docs/en/docs/Releasenotes/user-notice.md
@@ -1,5 +1,6 @@
# User Notice
-- The version number counting rule of openEuler is changed from openEuler _x.x_ to openEuler _year_._month_. For example, openEuler 21.03 indicates that the version is released in March 2020.
-- The [Python core team](https://www.python.org/dev/peps/pep-0373/#update) has stopped maintaining Python 2 in January 2020. In 2020, openEuler 21.03 fixes only the critical CVE of Python 2 and will reach the end of maintenance \(EOM\) on December 31, 2020. Please switch to Python 3 as soon as possible.
+- The version number counting rule of openEuler is changed from openEuler _x.x_ to openEuler _year_._month_. For example, openEuler 21.03 indicates that the version is released in March 2021.
+- The [Python core team](https://www.python.org/dev/peps/pep-0373/#update) has stopped maintaining Python 2 in January 2020. Python 2 reached end of maintenance (EOM) on December 31, 2020. In 2021, openEuler 21.03 fixed only the critical CVEs related to Python 2. Please switch to Python 3 as soon as possible.
+- From openEuler 22.03 LTS, only Python 3 is supported. Please switch to Python 3 to use the OS.
diff --git a/docs/en/menu/index.md b/docs/en/menu/index.md
index 16cd18d03..d4921b293 100644
--- a/docs/en/menu/index.md
+++ b/docs/en/menu/index.md
@@ -5,7 +5,7 @@ headless: true
- [Release Notes]({{< relref "./docs/Releasenotes/release_notes.md" >}})
- [User Notice]({{< relref "./docs/Releasenotes/user-notice.md" >}})
- [Introduction]({{< relref "./docs/Releasenotes/introduction.md" >}})
- - [Installing the OS]({{< relref "./docs/Releasenotes/installing-the-os.md" >}})
+ - [OS Installation]({{< relref "./docs/Releasenotes/installing-the-os.md" >}})
- [Key Features]({{< relref "./docs/Releasenotes/key-features.md" >}})
- [Known Issues]({{< relref "./docs/Releasenotes/known-issues.md" >}})
- [Resolved Issues]({{< relref "./docs/Releasenotes/resolved-issues.md" >}})
--
Gitee
From aaf41aa2079f6dd80a220cd3d62727b3fe70ed44 Mon Sep 17 00:00:00 2001
From: hcy1012 <690765764@qq.com>
Date: Thu, 24 Mar 2022 10:45:27 +0800
Subject: [PATCH 02/42] updated installation-modes.md
---
docs/en/docs/Installation/installation-modes.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/docs/en/docs/Installation/installation-modes.md b/docs/en/docs/Installation/installation-modes.md
index d291e2077..e06583f90 100644
--- a/docs/en/docs/Installation/installation-modes.md
+++ b/docs/en/docs/Installation/installation-modes.md
@@ -103,12 +103,14 @@ Pay attention to the capacity of the USB flash drive. The USB flash drive must h
```
# dd if=/home/testuser/Downloads/openEuler-21.09-aarch64-dvd.iso of=/dev/sdb bs=512k
```
+> **NOTE**
+>As described in ISOLINUX, the ISO 9660 file system created by the **mkisofs** command will boot through BIOS firmware, but only from the CD-ROM, DVD-ROM, or BD. In this case, you need to run the **isohybrid -u your.iso** command to process the ISO file and then run the **dd** command to write the ISO file to the USB flash drive. (This problem affects only the x86 architecture.)
5. After the image is written, remove the USB flash drive.
No progress is displayed during the image write process. When the number sign (#) appears again, run the following command to write the data to the drive. Then exit the **root** account and remove the USB flash drive. In this case, you can use the USB drive as the installation source of the system.
- ```
+ ```bash
# sync
```
--
Gitee
From 0368f76a05b49ec6a8016c0b6cb3cbba07b3326b Mon Sep 17 00:00:00 2001
From: gomico
Date: Thu, 24 Mar 2022 16:55:32 +0800
Subject: [PATCH 03/42] =?UTF-8?q?update=20translation=20for=20the=20follow?=
=?UTF-8?q?ing=20zh=20docs=20LibcarePlus.md=20at=20f8953c3=20=E5=B7=A5?=
=?UTF-8?q?=E5=85=B7=E4=BD=BF=E7=94=A8=E6=8C=87=E5=8D=97.md=20at=201d2e0d4?=
=?UTF-8?q?=20vmtop.md=20at=201d2e0d4=20FAQ-54.md=20at=203aa66c7=20?=
=?UTF-8?q?=E5=AF=B9=E6=8E=A5iSula=E5=AE=89=E5=85=A8=E5=AE=B9=E5=99=A8.md?=
=?UTF-8?q?=20at=2064692d9=20=E8=B4=A6=E6=88=B7=E5=8F=A3=E4=BB=A4.md=20at?=
=?UTF-8?q?=2072fd461=20KubeEdge=E9=83=A8=E7=BD=B2=E6=8C=87=E5=8D=97.md=20?=
=?UTF-8?q?at=209b782f7=20=E6=8E=A5=E5=8F=A3=E5=8F=82=E8=80=83.md=20at=20b?=
=?UTF-8?q?6e7836=20=E8=99=9A=E6=8B=9F=E6=9C=BA=E7=AE=A1=E7=90=86.md=20at?=
=?UTF-8?q?=20759a34f?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/en/docs/Administration/faqs.md | 42 +-
.../KubeEdge/kubeedge-deployment-guide.md | 1378 ++---------------
docs/en/docs/SecHarden/account-passwords.md | 34 +-
docs/en/docs/StratoVirt/VM_management.md | 206 ++-
docs/en/docs/StratoVirt/interconnect_isula.md | 90 +-
docs/en/docs/Virtualization/LibcarePlus.md | 410 +++++
docs/en/docs/Virtualization/tool-guide.md | 197 +--
docs/en/docs/Virtualization/vmtop.md | 196 +++
docs/en/docs/secGear/api-description.md | 3 +
docs/en/menu/index.md | 2 +
10 files changed, 1049 insertions(+), 1509 deletions(-)
create mode 100644 docs/en/docs/Virtualization/LibcarePlus.md
create mode 100644 docs/en/docs/Virtualization/vmtop.md
diff --git a/docs/en/docs/Administration/faqs.md b/docs/en/docs/Administration/faqs.md
index bf8aeebad..c18ba5615 100644
--- a/docs/en/docs/Administration/faqs.md
+++ b/docs/en/docs/Administration/faqs.md
@@ -2,17 +2,18 @@
- [FAQs](#faqs)
- - [Why Is the Memory Usage of the libvirtd Service Queried by Running the systemctl and top Commands Different?](#why-is-the-memory-usage-of-the-libvirtd-service-queried-by-running-the-systemctl-and-top-commands-different)
- - [An Error Occurs When stripsize Is Set to 4 During RAID 0 Volume Configuration](#an-error-occurs-when-stripsize-is-set-to-4-during-raid-0-volume-configuration)
- - [Failed to Compile MariaDB Using rpmbuild](#failed-to-compile-mariadb-using-rpmbuild)
- - [Failed to Start the SNTP Service Using the Default Configuration](#failed-to-start-the-sntp-service-using-the-default-configuration)
- - [Installation Failure Caused by Software Package Conflict, File Conflict, or Missing Software Package](#installation-failure-caused-by-software-package-conflict-file-conflict-or-missing-software-package)
- - [Failed to Downgrade libiscsi](#failed-to-downgrade-libiscsi)
- - [Failed to Downgrade xfsprogs](#failed-to-downgrade-xfsprogs)
- - [CPython/Lib Detects CVE-2019-9674: Zip Bomb](#cpython/lib-detects-cve-2019-9674:-zip-bomb)
- - [ReDoS Attack Occurs Due to Improper Use of glibc Regular Expressions](#redos-attack-occurs-due-to-improper-use-of-glibc-regular-expressions)
- - [An Error Is Reported When gdbm-devel Is Installed or Uninstalled During the Installation and Uninstallation of httpd-devel and apr-util-devel](#an-error-is-reported-when-gdbm-devel-is-installed-or-uninstalled-during-the-installation-and-uninstallation-of-httpd-devel-and-apr-util-devel)
- - [An rpmdb Error Is Reported When Running the yum or dnf Command After the System Is Rebooted](#an-rpmdb-error-is-reported-when-running-the-yum-or-dnf-command-after-the-system-is-rebooted)
+ - [Why Is the Memory Usage of the libvirtd Service Queried by Running the systemctl and top Commands Different?](#why-is-the-memory-usage-of-the-libvirtd-service-queried-by-running-the-systemctl-and-top-commands-different)
+ - [An Error Occurs When stripsize Is Set to 4 During RAID 0 Volume Configuration](#an-error-occurs-when-stripsize-is-set-to-4-during-raid-0-volume-configuration)
+ - [Failed to Compile MariaDB Using rpmbuild](#failed-to-compile-mariadb-using-rpmbuild)
+ - [Failed to Start the SNTP Service Using the Default Configuration](#failed-to-start-the-sntp-service-using-the-default-configuration)
+ - [Installation Failure Caused by Software Package Conflict, File Conflict, or Missing Software Package](#installation-failure-caused-by-software-package-conflict-file-conflict-or-missing-software-package)
+ - [Failed to Downgrade libiscsi](#failed-to-downgrade-libiscsi)
+ - [Failed to Downgrade xfsprogs](#failed-to-downgrade-xfsprogs)
+ - [CPython/Lib Detects CVE-2019-9674: Zip Bomb](#cpythonlib-detects-cve-2019-9674-zip-bomb)
+ - [ReDoS Attack Occurs Due to Improper Use of glibc Regular Expressions](#redos-attack-occurs-due-to-improper-use-of-glibc-regular-expressions)
+ - [An Error Is Reported When gdbm-devel Is Installed or Uninstalled During the Installation and Uninstallation of httpd-devel and apr-util-devel](#an-error-is-reported-when-gdbm-devel-is-installed-or-uninstalled-during-the-installation-and-uninstallation-of-httpd-devel-and-apr-util-devel)
+ - [An rpmdb Error Is Reported When Running the yum or dnf Command After the System Is Rebooted](#an-rpmdb-error-is-reported-when-running-the-yum-or-dnf-command-after-the-system-is-rebooted)
+ - [Failed to Run `rpmrebuild -d /home/test filesystem` to Rebuild the **filesystem** Package](#failed-to-run-rpmrebuild--d-hometest-filesystem-to-rebuild-the-filesystem-package)
@@ -331,3 +332,22 @@ A core dump occurs on the process that uses the regular expression. The glibc re
Step 1 Run the `kill -9` command to terminate all running RPM-related commands.
Step 2 Delete all **/var/lib/rpm/__db.00*** files.
Step 3 Run the `rpmdb --rebuilddb` command to rebuild the RPM database.
+
+## Failed to Run `rpmrebuild -d /home/test filesystem` to Rebuild the **filesystem** Package
+
+### Symptom
+
+Failed to run the `rpmrebuild --comment-missing=y --keep-perm -b -d /home/test filesystem-3.16-3.oe1.aarch64` command to rebuild the **filesystem** package. The following information is displayed:
+```shell
+/usr/lib/rpmrebuild/rpmrebuild.sh:Error:(RpmBuild) Package 'filesystem-3.16-3.oe1.aarch64' build failed.
+/usr/lib/rpmrebuild/rpmrebuild.sh:Error: RpmBuild
+```
+
+### Possible Cause
+The software package creates the directory in the **%pretrans -p** phase, and modify the diretory in the **%ghost** phase. If you create a file or diretory in the diretory and use `rpmrebuild` to build the package, the created file or directory will be included in the package.
+
+The root cause of the symptom is that **filesystem** creates the **/proc** diretory in the **%pretrans** phase and modifies the directory in the **%ghost** phase, but some small processes are dynamically created during system running. As a result, `rpmrebuild` cannot include the processes in the package because they are not files or diretories and fails to rebuild the package.
+
+### Solution
+
+Do not use `rpmrebuild` to rebuild the **filesystem** package.
\ No newline at end of file
diff --git a/docs/en/docs/KubeEdge/kubeedge-deployment-guide.md b/docs/en/docs/KubeEdge/kubeedge-deployment-guide.md
index ac273dca0..e35d2bd77 100644
--- a/docs/en/docs/KubeEdge/kubeedge-deployment-guide.md
+++ b/docs/en/docs/KubeEdge/kubeedge-deployment-guide.md
@@ -6,19 +6,19 @@
KubeEdge is an open source system dedicated to solving problems in edge scenarios. It extends the capabilities of containerized application orchestration and device management to edge devices. Based on Kubernetes, KubeEdge provides core infrastructure support for networks, application deployment, and metadata synchronization between the cloud and the edge. KubeEdge supports MQTT and allows for custom logic to enable communication for the resource-constrained devices at the edge. KubeEdge consists of components deployed on the cloud and edge nodes. The components are now open source.
-> https://kubeedge.io/
+> https://kubeedge.io/
### iSulad
iSulad is a lightweight container runtime daemon designed for IoT and cloud infrastructure. It is lightweight, fast, and is not restricted by hardware specifications or architectures. It is suitable for wide application in various scenarios, such as cloud, IoT, and edge computing.
-> https://gitee.com/openeuler/iSulad
+> https://gitee.com/openeuler/iSulad
-## Preparations
+## Cluster Overview
### Component Versions
-| Component| Version|
+| Component | Version |
| ---------- | --------------------------------- |
| OS | openEuler 21.09 |
| Kubernetes | 1.20.2-4 |
@@ -27,487 +27,197 @@ iSulad is a lightweight container runtime daemon designed for IoT and cloud infr
### Node Planning Example
-| Node| Location| Components|
-| ------------ | ------------- | -------------------------------- |
-| 9.63.252.224 | Cloud| Kubernetes (Master), iSulad, CloudCore|
-| 9.63.252.227 | Edge| iSulad, EdgeCore|
-
-### Environment Configurations
+| Node | Location | Components |
+| -------------- | -------- | -------------------------------- |
+| cloud.kubeedge | Cloud | Kubernetes (Master), iSulad, CloudCore |
+| edge.kubeedge | Edge | iSulad, EdgeCore |
-Configure the following settings on the cloud and edge nodes:
+> Note: You can run the `hostnamectl set-hostname [cloud,edge].kubeedge` command to set the cloud and edge node names in advance.
-```bash
-# Disable the firewall.
-$ systemctl stop firewalld
-$ systemctl disable firewalld
-
-# Disable SELinux.
-$ setenforce 0
-
-# Configure the network, and enable the required forwarding mechanism.
-$ cat >> /etc/sysctl.d/k8s.conf <> /etc/hosts << EOF
-9.63.252.224 cloud.kubeedge
-9.63.252.227 edge.kubeedge
-EOF
-
-# Choose an accessible NTP server to synchronize the clock.
-$ ntpdate cn.pool.ntp.org
-
-# Install the cri-tools network tool.
-$ wget --no-check-certificate https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.20.0/crictl-v1.20.0-linux-amd64.tar.gz
-$ tar zxvf crictl-v1.20.0-linux-amd64.tar.gz -C /usr/local/bin
-
-# Install the CNI network plugins.
-$ wget --no-check-certificate https://github.com/containernetworking/plugins/releases/download/v0.9.0/cni-plugins-linux-amd64-v0.9.0.tgz
-$ mkdir -p /opt/cni/bin
-$ tar -zxvf cni-plugins-linux-amd64-v0.9.0.tgz -C /opt/cni/bin
-```
+## Preparations
-### Configuring iSulad
+### Tool Package Download
-Configure the following settings on the cloud and edge nodes:
+[kubeedge-tools](https://gitee.com/Poorunga/kubeedge-tools) provides complete offline installation packages and deployment scripts for easy and quick KubeEdge cluster deployment even if the node cannot access the Internet.
```bash
-# Configure iSulad (only the items to be modified are listed).
-$ cat /etc/isulad/daemon.json
-{
- "registry-mirrors": [
- "docker.io"
- ],
- "insecure-registries": [
- "k8s.gcr.io",
- "quay.io",
- "hub.oepkgs.net"
- ],
- "pod-sandbox-image": "k8s.gcr.io/pause:3.2",
- "network-plugin": "cni",
- "cni-bin-dir": "/opt/cni/bin",
- "cni-conf-dir": "/etc/cni/net.d",
-}
-
-# Configure the proxy if the node cannot directly access the Internet. Otherwise, skip this section.
-$ cat /usr/lib/systemd/system/isulad.service
-[Service]
-Type=notify
-Environment="HTTP_PROXY=http://..."
-Environment="HTTPS_PROXY=http://..."
-
-# Restart the iSulad and set it to start upon system startup.
-$ systemctl daemon-reload && systemctl restart isulad
-```
+# Download and decompress the kubeedge-tools package on both the cloud and edge nodes.
+$ wget -O kubeedge-tools.zip https://gitee.com/Poorunga/kubeedge-tools/repository/archive/master.zip
+$ unzip kubeedge-tools.zip
-### Deploying the Kubernetes Components
+# Go to the kubeedge-tools directory for all the subsequent operations.
+$ cd kubeedge-tools-master
+```
-Install and deploy the Kubernetes components on the cloud node only.
+### Kubernetes Deployment
-```bash
-# Install the Kubernetes tools.
-$ yum install kubernetes-master kubernetes-kubeadm kubernetes-client kubernetes-kubelet
-# Set kubelet to start upon system startup.
-$ systemctl enable kubelet --now
+Perform the following operations on the cloud node only.
-# Note that the system proxy must be canceled before using the kubeadm init command.
-$ unset `env | grep -iE "tps?_proxy" | cut -d= -f1`
-$ env | grep proxy
+#### Initializing the Cloud Environment
-# Run the kubeadm init command.
-$ kubeadm init --kubernetes-version v1.20.2 --pod-network-cidr=10.244.0.0/16 --upload-certs --cri-socket=/var/run/isulad.sock
-# The default Kubernetes component image is gcr.k8s.io. You can add the --image-repository=xxx option to configure a custom image repository address (to test your own Kubernetes image).
-
-# Note that the network segment specified by pod-network-cidr cannot overlap the network segment of the host machine. Otherwise, the network is inaccessible.
-# You are advised to run the init command before configuring the network.
-Your Kubernetes control-plane has initialized successfully!
+```bash
+$ ./setup-cloud.sh
+```
-To start using your cluster, you need to run the following as a regular user:
+#### Deploying Kubernetes
- mkdir -p $HOME/.kube
- sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
- sudo chown $(id -u):$(id -g) $HOME/.kube/config
+Deploy Kubernetes by referring to the [Kubernetes Cluster Deployment Guide](https://docs.openeuler.org/en/docs/21.09/docs/Kubernetes/Kubernetes.html).
-You should now deploy a pod network to the cluster.
-Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
- https://kubernetes.io/docs/concepts/cluster-administration/addons/
+> Note: Preferentially, use `kubeadm` to deploy Kubernetes if the cloud node has access to the Internet. The procedure is as follows:
-Then you can join any number of worker nodes by running the following on each as root:
+```bash
+$ kubeadm init --apiserver-advertise-address=[cloud_node_IP_address] --kubernetes-version v1.20.11 --pod-network-cidr=10.244.0.0/16 --upload-certs --cri-socket=/var/run/isulad.sock
+...
+Your Kubernetes control-plane has initialized successfully!
...
-# Run the commands as prompted.
-mkdir -p $HOME/.kube
-cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
-chown $(id -u):$(id -g) $HOME/.kube/config
-# The commands make a copy of admin.conf, which is a kubectl configuration file initialized by the kubeadm command.
-# The file contains important configurations, such as the authentication information.
-
-# You can reset the configurations if an error occurs when running the init command.
-$ kubeadm reset
-
-# If "Unable to read config path "/etc/kubernetes/manifests"" is displayed, run the following command:
-$ mkdir -p /etc/kubernetes/manifests
+# After Kubernetes is installed, copy the specified file to the directory as prompted.
+# mkdir -p $HOME/.kube
+# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
+# sudo chown $(id -u):$(id -g) $HOME/.kube/config
```
-### Configuring the Network
+#### Configuring Network for the Cloud Container
-Because **the Calico network plugin cannot run on edge nodes**, `flannel` is used instead. The [issue](https://github.com/kubeedge/kubeedge/issues/2788#issuecomment-907627687) has been submitted to the KubeEdge community.
-
-The cloud and edge nodes are in different network environments and require different **affinity**. Therefore, two flannel configuration files are required.
+Container Network Interface (CNI) software that provides network for Kubernetes nodes include [flannel](https://github.com/flannel-io/flannel), [Calico](https://github.com/projectcalico/calico), [Cilium](https://github.com/cilium/cilium), and more. If you have not decided which CNI software to use, run the following command to configure network for the cloud container:
```bash
-# Download the flannel network plugin.
-$ wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
-
-# Prepare for network configuration for the cloud node.
-$ cp kube-flannel.yml kube-flannel-cloud.yml
-
-# Modify the network configuration for the cloud node.
-$ patch kube-flannel-cloud.yml - <
-Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.959661 424578 signcerts.go:100] Succeed to creating token
-Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.959716 424578 server.go:44] start unix domain socket server
-Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.959973 424578 uds.go:71] listening on: //var/lib/kubeedge/kubeedge.sock
-Aug 29 10:50:15 cloud.kubeedge cloudcore[424578]: I0829 10:50:15.966693 424578 server.go:64] Starting cloudhub websocket server
-Aug 29 10:50:17 cloud.kubeedge cloudcore[424578]: I0829 10:50:17.847150 424578 upstream.go:63] Start upstream devicecontroller
+# active (running) indicates a normal status
+$ systemctl status cloudcore | grep running
+ Active: active (running) since Fri 2022-03-04 10:54:30 CST; 5min ago
```
CloudCore has been deployed on the cloud node. Then, deploy EdgeCore on the edge node.
-### Managing the Edge Node
-
-Run the `keadm join` command on the edge node to manage it.
+### EdgeCore Deployment
-#### Modifying iSulad Configurations
+Perform the following operations only on the edge node unless otherwise specified.
-File path: `/etc/isulad/daemon.json`
+#### Initializing the Edge Environment
```bash
-{
- # Set pod-sandbox-image.
- "pod-sandbox-image": "kubeedge/pause:3.1",
- # The listening port `10350` of EdgeCore conflicts with the WebSocket port of iSulad. As a result, EdgeCore cannot be started. To resolve the conflict, change the value of `websocket-server-listening-port` in the iSulad configuration file (`/etc/isulad/daemon.json`) to `10351`.
- "websocket-server-listening-port": 10351,
-}
+$ ./setup-edge.sh
```
-After the configuration file is modified, run the `systemctl restart isulad` command to restart iSulad.
+#### Managing the Edge Node
+```bash
+# Run the keadm gettoken command on the cloud node.
+$ keadm gettoken
+96058ab80ffbeb87fe58a79bfb19ea13f9a5a6c3076a17c00f80f01b406b4f7c.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDY0NDg4NzF9.1mJegWB7SUVjgf-OvAqILgbZXeMHR9eOzMxpNFc42SI
+# Save this token for subsequent steps.
-#### Connecting EdgeCore to CloudCore
+
+# Run the keadm join command on the edge node.
+# Set --cloudcore-ipport to the IP address and port number (10000) of the cloud node. Set --token to the token saved in the previous step.
+$ keadm join --cloudcore-ipport=clou_node_IP_address:10000 --kubeedge-version=1.8.0 --token=96058ab80ffbeb87fe58a79bfb19ea13f9a5a6c3076a17c00f80f01b406b4f7c.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDY0NDg4NzF9.1mJegWB7SUVjgf-OvAqILgbZXeMHR9eOzMxpNFc42SI
+...
+KubeEdge edgecore is running...
+```
+
+#### Configuring EdgeCore
```bash
-# Obtain a token on the cloud node.
-$ keadm gettoken
-28c25d3b137593f5bbfb776cf5b19866ab9727cab9e97964dd503f87cd52cbde.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzAyOTE4MTV9.aGUyCi9gdysVtMu0DQzrD5TcV_DcXob647YeqcOxKDA
-
-# Run the keadm join command to connect EdgeCore to CloudCore.
-# --cloudcore-ipport is a mandatory parameter. 10000 is the default port of CloudCore.
-$ keadm join --cloudcore-ipport=9.63.252.224:10000 --kubeedge-version=1.8.0 --token=28c25d3b137593f5bbfb776cf5b19866ab9727cab9e97964dd503f87cd52cbde.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzAyOTE4MTV9.aGUyCi9gdysVtMu0DQzrD5TcV_DcXob647YeqcOxKDA
-Host has mosquit+ already installed and running. Hence skipping the installation steps !!!
-kubeedge-v1.8.0-linux-amd64.tar.gz checksum:
-checksum_kubeedge-v1.8.0-linux-amd64.tar.gz.txt content:
-[Run as service] start to download service file for edgecore
-[Run as service] success to download service file for edgecore
-kubeedge-v1.8.0-linux-amd64/
-kubeedge-v1.8.0-linux-amd64/edge/
-kubeedge-v1.8.0-linux-amd64/edge/edgecore
-kubeedge-v1.8.0-linux-amd64/cloud/
-kubeedge-v1.8.0-linux-amd64/cloud/csidriver/
-kubeedge-v1.8.0-linux-amd64/cloud/csidriver/csidriver
-kubeedge-v1.8.0-linux-amd64/cloud/admission/
-kubeedge-v1.8.0-linux-amd64/cloud/admission/admission
-kubeedge-v1.8.0-linux-amd64/cloud/cloudcore/
-kubeedge-v1.8.0-linux-amd64/cloud/cloudcore/cloudcore
-kubeedge-v1.8.0-linux-amd64/version
-
-KubeEdge edgecore is running, For logs visit: journalctl -u edgecore.service -b
+$ ./patch-edge.sh
```
-At this time, the deployment of EdgeCore is not complete because Docker is used in the default settings. You need to modify the configuration file to connect EdgeCore to iSulad.
+#### Configuring Network for the Edge Container
-#### Modifying EdgeCore Configurations
+If you have not decided which CNI software to use, run the following command to configure network for the edge container:
```bash
-# Enable systemd to manage EdgeCore.
-# Copy edgecore.service to /usr/lib/systemd/system.
-$ cp /etc/kubeedge/edgecore.service /usr/lib/systemd/system
-
-# Modify the EdgeCore configurations.
-$ cd /etc/kubeedge/config
-$ patch edgecore.yaml - <
-
-# You can see that Nginx has been successfully deployed on the edge node.
+# Check whether Nginx is deployed on the edge node and running.
+$ kubectl get pod -owide | grep nginx
+nginx-deployment-84b99f4bf-jb6sz 1/1 Running 0 30s 10.244.1.2 edge.kubeedge
```
#### Testing the Function
```bash
-# Test whether the function is running properly.
-# Run the curl command on the edge node to access the IP address of Nginx, which is 10.244.2.4.
-$ curl 10.244.2.4:80
+# Access the IP address of Nginx on the edge node.
+$ curl 10.244.1.2:80
Welcome to nginx!
@@ -525,868 +235,4 @@ Commercial support is available at
```
-The deployment of KubeEdge and iSulad is complete.
-
-## Deploying the KubeEdge Cluster Using Binary Files
-
-You can also deploy the KubeEdge cluster using binary files. Only two RPM packages are required: `cloudcore` (on the cloud node) and `edgecore` (on the edge node).
-> The KubeEdge deployment using binary files is for testing only. Do not use this method in the production environment.
-
-### Deploying CloudCore on the Cloud Node
-
-> Log in to the cloud host.
-
-#### Installing the `cloudcore` RPM Package
-
-```bash
-$ yum install kubeedge-cloudcore
-```
-
-#### Creating CRDs
-
-```bash
-$ kubectl apply -f /etc/kubeedge/crds/devices/
-$ kubectl apply -f /etc/kubeedge/crds/reliablesyncs/
-$ kubectl apply -f /etc/kubeedge/crds/router/
-```
-
-#### Preparing the Configuration File
-
-```bash
-$ cloudcore --defaultconfig > /etc/kubeedge/config/cloudcore.yaml
-```
-
-Modify CloudCore configurations by referring to **Deploying CloudCore Using Keadm**.
-
-#### Running CloudCore
-
-```bash
-$ pkill cloudcore
-$ systemctl start cloudcore
-```
-
-### Deploying EdgeCore on the Edge Node
-
-> Log in to the edge host.
-
-#### Installing the `edgecore` RPM Package
-
-```bash
-$ yum install kubeedge-edgecore
-```
-
-#### Preparing the Configuration File
-
-```bash
-$ edgecore --defaultconfig > /etc/kubeedge/config/edgecore.yaml
-```
-
-Modify EdgeCore configurations by referring to **Deploying EdgeCore Using Keadm**.
-
-
-
-```bash
-$ kubectl get secret -nkubeedge tokensecret -o=jsonpath='{.data.tokendata}' | base64 -d
-1c4ff11289a14c59f2cbdbab726d1857262d5bda778ddf0de34dd59d125d3f69.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzE0ODM3MzN9.JY77nMVDHIKD9ipo03Y0mSbxief9qOvJ4yMNx1yZpp0
-
-# Add the obtained token to the configuration file.
-sed -i -e "s|token: .*|token: ${token}|g" /etc/kubeedge/config/edgecore.yaml
-
-# The value of the token variable is obtained in the previous step.
-```
-
-#### Running EdgeCore
-
-```bash
-$ pkill edgecore
-$ systemctl start edgecore
-```
-
-## Appendix
-
-### kube-flannel-cloud.yml
-
-```bash
-# Application scenario: cloud node
----
-apiVersion: policy/v1beta1
-kind: PodSecurityPolicy
-metadata:
- name: psp.flannel.unprivileged
- annotations:
- seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
- seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
- apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
- apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
-spec:
- privileged: false
- volumes:
- - configMap
- - secret
- - emptyDir
- - hostPath
- allowedHostPaths:
- - pathPrefix: "/etc/cni/net.d"
- - pathPrefix: "/etc/kube-flannel"
- - pathPrefix: "/run/flannel"
- readOnlyRootFilesystem: false
- # Users and groups
- runAsUser:
- rule: RunAsAny
- supplementalGroups:
- rule: RunAsAny
- fsGroup:
- rule: RunAsAny
- # Privilege Escalation
- allowPrivilegeEscalation: false
- defaultAllowPrivilegeEscalation: false
- # Capabilities
- allowedCapabilities: ['NET_ADMIN', 'NET_RAW']
- defaultAddCapabilities: []
- requiredDropCapabilities: []
- # Host namespaces
- hostPID: false
- hostIPC: false
- hostNetwork: true
- hostPorts:
- - min: 0
- max: 65535
- # SELinux
- seLinux:
- # SELinux is unused in CaaSP
- rule: 'RunAsAny'
----
-kind: ClusterRole
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
- name: flannel
-rules:
-- apiGroups: ['extensions']
- resources: ['podsecuritypolicies']
- verbs: ['use']
- resourceNames: ['psp.flannel.unprivileged']
-- apiGroups:
- - ""
- resources:
- - pods
- verbs:
- - get
-- apiGroups:
- - ""
- resources:
- - nodes
- verbs:
- - list
- - watch
-- apiGroups:
- - ""
- resources:
- - nodes/status
- verbs:
- - patch
----
-kind: ClusterRoleBinding
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
- name: flannel
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: flannel
-subjects:
-- kind: ServiceAccount
- name: flannel
- namespace: kube-system
----
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: flannel
- namespace: kube-system
----
-kind: ConfigMap
-apiVersion: v1
-metadata:
- name: kube-flannel-cfg
- namespace: kube-system
- labels:
- tier: node
- app: flannel
-data:
- cni-conf.json: |
- {
- "name": "cbr0",
- "cniVersion": "0.3.1",
- "plugins": [
- {
- "type": "flannel",
- "delegate": {
- "hairpinMode": true,
- "isDefaultGateway": true
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- }
- ]
- }
- net-conf.json: |
- {
- "Network": "10.244.0.0/16",
- "Backend": {
- "Type": "vxlan"
- }
- }
----
-apiVersion: apps/v1
-kind: DaemonSet
-metadata:
- name: kube-flannel-cloud-ds
- namespace: kube-system
- labels:
- tier: node
- app: flannel
-spec:
- selector:
- matchLabels:
- app: flannel
- template:
- metadata:
- labels:
- tier: node
- app: flannel
- spec:
- affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- - matchExpressions:
- - key: kubernetes.io/os
- operator: In
- values:
- - linux
- - key: node-role.kubernetes.io/agent
- operator: DoesNotExist
- hostNetwork: true
- priorityClassName: system-node-critical
- tolerations:
- - operator: Exists
- effect: NoSchedule
- serviceAccountName: flannel
- initContainers:
- - name: install-cni
- image: quay.io/coreos/flannel:v0.14.0
- command:
- - cp
- args:
- - -f
- - /etc/kube-flannel/cni-conf.json
- - /etc/cni/net.d/10-flannel.conflist
- volumeMounts:
- - name: cni
- mountPath: /etc/cni/net.d
- - name: flannel-cfg
- mountPath: /etc/kube-flannel/
- containers:
- - name: kube-flannel
- image: quay.io/coreos/flannel:v0.14.0
- command:
- - /opt/bin/flanneld
- args:
- - --ip-masq
- - --kube-subnet-mgr
- resources:
- requests:
- cpu: "100m"
- memory: "50Mi"
- limits:
- cpu: "100m"
- memory: "50Mi"
- securityContext:
- privileged: false
- capabilities:
- add: ["NET_ADMIN", "NET_RAW"]
- env:
- - name: POD_NAME
- valueFrom:
- fieldRef:
- fieldPath: metadata.name
- - name: POD_NAMESPACE
- valueFrom:
- fieldRef:
- fieldPath: metadata.namespace
- volumeMounts:
- - name: run
- mountPath: /run/flannel
- - name: flannel-cfg
- mountPath: /etc/kube-flannel/
- volumes:
- - name: run
- hostPath:
- path: /run/flannel
- - name: cni
- hostPath:
- path: /etc/cni/net.d
- - name: flannel-cfg
- configMap:
- name: kube-flannel-cfg
-
-```
-
-### kube-flannel-edge.yml
-
-```bash
-# Application scenario: edge node
----
-apiVersion: policy/v1beta1
-kind: PodSecurityPolicy
-metadata:
- name: psp.flannel.unprivileged
- annotations:
- seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
- seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
- apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
- apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
-spec:
- privileged: false
- volumes:
- - configMap
- - secret
- - emptyDir
- - hostPath
- allowedHostPaths:
- - pathPrefix: "/etc/cni/net.d"
- - pathPrefix: "/etc/kube-flannel"
- - pathPrefix: "/run/flannel"
- readOnlyRootFilesystem: false
- # Users and groups
- runAsUser:
- rule: RunAsAny
- supplementalGroups:
- rule: RunAsAny
- fsGroup:
- rule: RunAsAny
- # Privilege Escalation
- allowPrivilegeEscalation: false
- defaultAllowPrivilegeEscalation: false
- # Capabilities
- allowedCapabilities: ['NET_ADMIN', 'NET_RAW']
- defaultAddCapabilities: []
- requiredDropCapabilities: []
- # Host namespaces
- hostPID: false
- hostIPC: false
- hostNetwork: true
- hostPorts:
- - min: 0
- max: 65535
- # SELinux
- seLinux:
- # SELinux is unused in CaaSP
- rule: 'RunAsAny'
----
-kind: ClusterRole
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
- name: flannel
-rules:
-- apiGroups: ['extensions']
- resources: ['podsecuritypolicies']
- verbs: ['use']
- resourceNames: ['psp.flannel.unprivileged']
-- apiGroups:
- - ""
- resources:
- - pods
- verbs:
- - get
-- apiGroups:
- - ""
- resources:
- - nodes
- verbs:
- - list
- - watch
-- apiGroups:
- - ""
- resources:
- - nodes/status
- verbs:
- - patch
----
-kind: ClusterRoleBinding
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
- name: flannel
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: flannel
-subjects:
-- kind: ServiceAccount
- name: flannel
- namespace: kube-system
----
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: flannel
- namespace: kube-system
----
-kind: ConfigMap
-apiVersion: v1
-metadata:
- name: kube-flannel-cfg
- namespace: kube-system
- labels:
- tier: node
- app: flannel
-data:
- cni-conf.json: |
- {
- "name": "cbr0",
- "cniVersion": "0.3.1",
- "plugins": [
- {
- "type": "flannel",
- "delegate": {
- "hairpinMode": true,
- "isDefaultGateway": true
- }
- },
- {
- "type": "portmap",
- "capabilities": {
- "portMappings": true
- }
- }
- ]
- }
- net-conf.json: |
- {
- "Network": "10.244.0.0/16",
- "Backend": {
- "Type": "vxlan"
- }
- }
----
-apiVersion: apps/v1
-kind: DaemonSet
-metadata:
- name: kube-flannel-edge-ds
- namespace: kube-system
- labels:
- tier: node
- app: flannel
-spec:
- selector:
- matchLabels:
- app: flannel
- template:
- metadata:
- labels:
- tier: node
- app: flannel
- spec:
- affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- - matchExpressions:
- - key: kubernetes.io/os
- operator: In
- values:
- - linux
- - key: node-role.kubernetes.io/agent
- operator: Exists
- hostNetwork: true
- priorityClassName: system-node-critical
- tolerations:
- - operator: Exists
- effect: NoSchedule
- serviceAccountName: flannel
- initContainers:
- - name: install-cni
- image: quay.io/coreos/flannel:v0.14.0
- command:
- - cp
- args:
- - -f
- - /etc/kube-flannel/cni-conf.json
- - /etc/cni/net.d/10-flannel.conflist
- volumeMounts:
- - name: cni
- mountPath: /etc/cni/net.d
- - name: flannel-cfg
- mountPath: /etc/kube-flannel/
- containers:
- - name: kube-flannel
- image: quay.io/coreos/flannel:v0.14.0
- command:
- - /opt/bin/flanneld
- args:
- - --ip-masq
- - --kube-subnet-mgr
- - --kube-api-url=http://127.0.0.1:10550
- resources:
- requests:
- cpu: "100m"
- memory: "50Mi"
- limits:
- cpu: "100m"
- memory: "50Mi"
- securityContext:
- privileged: false
- capabilities:
- add: ["NET_ADMIN", "NET_RAW"]
- env:
- - name: POD_NAME
- valueFrom:
- fieldRef:
- fieldPath: metadata.name
- - name: POD_NAMESPACE
- valueFrom:
- fieldRef:
- fieldPath: metadata.namespace
- volumeMounts:
- - name: run
- mountPath: /run/flannel
- - name: flannel-cfg
- mountPath: /etc/kube-flannel/
- volumes:
- - name: run
- hostPath:
- path: /run/flannel
- - name: cni
- hostPath:
- path: /etc/cni/net.d
- - name: flannel-cfg
- configMap:
- name: kube-flannel-cfg
-
-```
-
-### cloudcore.service
-
-```bash
-# Application scenario: cloud node
-# File path: /usr/lib/systemd/system/cloudcore.service
-[Unit]
-Description=cloudcore.service
-
-[Service]
-Type=simple
-ExecStart=/usr/local/bin/cloudcore
-Restart=always
-RestartSec=10
-
-[Install]
-WantedBy=multi-user.target
-```
-
-### cloudcore.yaml
-
-```bash
-# Application scenario: cloud node
-# File path: /etc/kubeedge/config/cloudcore.yaml
-apiVersion: cloudcore.config.kubeedge.io/v1alpha1
-commonConfig:
- tunnelPort: 10351
-kind: CloudCore
-kubeAPIConfig:
- burst: 200
- contentType: application/vnd.kubernetes.protobuf
- kubeConfig: /root/.kube/config
- master: ""
- qps: 100
-modules:
- cloudHub:
- advertiseAddress:
- - 9.63.252.224
- dnsNames:
- - ""
- edgeCertSigningDuration: 365
- enable: true
- https:
- address: 0.0.0.0
- enable: true
- port: 10002
- keepaliveInterval: 30
- nodeLimit: 1000
- quic:
- address: 0.0.0.0
- enable: false
- maxIncomingStreams: 10000
- port: 10001
- tlsCAFile: /etc/kubeedge/ca/rootCA.crt
- tlsCAKeyFile: /etc/kubeedge/ca/rootCA.key
- tlsCertFile: /etc/kubeedge/certs/server.crt
- tlsPrivateKeyFile: /etc/kubeedge/certs/server.key
- tokenRefreshDuration: 12
- unixsocket:
- address: unix:///var/lib/kubeedge/kubeedge.sock
- enable: true
- websocket:
- address: 0.0.0.0
- enable: true
- port: 10000
- writeTimeout: 30
- cloudStream:
- enable: false
- streamPort: 10003
- tlsStreamCAFile: /etc/kubeedge/ca/streamCA.crt
- tlsStreamCertFile: /etc/kubeedge/certs/stream.crt
- tlsStreamPrivateKeyFile: /etc/kubeedge/certs/stream.key
- tlsTunnelCAFile: /etc/kubeedge/ca/rootCA.crt
- tlsTunnelCertFile: /etc/kubeedge/certs/server.crt
- tlsTunnelPrivateKeyFile: /etc/kubeedge/certs/server.key
- tunnelPort: 10004
- deviceController:
- buffer:
- deviceEvent: 1
- deviceModelEvent: 1
- updateDeviceStatus: 1024
- context:
- receiveModule: devicecontroller
- responseModule: cloudhub
- sendModule: cloudhub
- enable: true
- load:
- updateDeviceStatusWorkers: 1
- dynamicController:
- enable: true
- edgeController:
- buffer:
- configMapEvent: 1
- deletePod: 1024
- endpointsEvent: 1
- podEvent: 1
- queryConfigMap: 1024
- queryEndpoints: 1024
- queryNode: 1024
- queryPersistentVolume: 1024
- queryPersistentVolumeClaim: 1024
- querySecret: 1024
- queryService: 1024
- queryVolumeAttachment: 1024
- ruleEndpointsEvent: 1
- rulesEvent: 1
- secretEvent: 1
- serviceAccountToken: 1024
- serviceEvent: 1
- updateNode: 1024
- updateNodeStatus: 1024
- updatePodStatus: 1024
- context:
- receiveModule: edgecontroller
- responseModule: cloudhub
- sendModule: cloudhub
- sendRouterModule: router
- enable: true
- load:
- ServiceAccountTokenWorkers: 4
- UpdateRuleStatusWorkers: 4
- deletePodWorkers: 4
- queryConfigMapWorkers: 4
- queryEndpointsWorkers: 4
- queryNodeWorkers: 4
- queryPersistentVolumeClaimWorkers: 4
- queryPersistentVolumeWorkers: 4
- querySecretWorkers: 4
- queryServiceWorkers: 4
- queryVolumeAttachmentWorkers: 4
- updateNodeStatusWorkers: 1
- updateNodeWorkers: 4
- updatePodStatusWorkers: 1
- nodeUpdateFrequency: 10
- router:
- address: 0.0.0.0
- enable: false
- port: 9443
- restTimeout: 60
- syncController:
- enable: true
-
-```
-
-### edgecore.service
-
-```bash
-# Application scenario: edge node
-# File path: /etc/systemd/system/edgecore.service
-[Unit]
-Description=edgecore.service
-
-[Service]
-Type=simple
-ExecStart=/usr/local/bin/edgecore
-Restart=always
-RestartSec=10
-
-[Install]
-WantedBy=multi-user.target
-```
-
-### edgecore.yaml
-
-```bash
-# Application scenario: edge node
-# File path: /etc/kubeedge/config/edgecore.yaml
-apiVersion: edgecore.config.kubeedge.io/v1alpha1
-database:
- aliasName: default
- dataSource: /var/lib/kubeedge/edgecore.db
- driverName: sqlite3
-kind: EdgeCore
-modules:
- dbTest:
- enable: false
- deviceTwin:
- enable: true
- edgeHub:
- enable: true
- heartbeat: 15
- httpServer: https://9.63.252.224:10002
- projectID: e632aba927ea4ac2b575ec1603d56f10
- quic:
- enable: false
- handshakeTimeout: 30
- readDeadline: 15
- server: 9.63.252.227:10001
- writeDeadline: 15
- rotateCertificates: true
- tlsCaFile: /etc/kubeedge/ca/rootCA.crt
- tlsCertFile: /etc/kubeedge/certs/server.crt
- tlsPrivateKeyFile: /etc/kubeedge/certs/server.key
- token: ""# Enter the token obtained from the cloud side.
- websocket:
- enable: true
- handshakeTimeout: 30
- readDeadline: 15
- server: 9.63.252.224:10000
- writeDeadline: 15
- edgeMesh:
- enable: false
- lbStrategy: RoundRobin
- listenInterface: docker0
- listenPort: 40001
- subNet: 9.251.0.0/16
- edgeStream:
- enable: false
- handshakeTimeout: 30
- readDeadline: 15
- server: 9.63.252.224:10004
- tlsTunnelCAFile: /etc/kubeedge/ca/rootCA.crt
- tlsTunnelCertFile: /etc/kubeedge/certs/server.crt
- tlsTunnelPrivateKeyFile: /etc/kubeedge/certs/server.key
- writeDeadline: 15
- edged:
- cgroupDriver: cgroupfs
- cgroupRoot: ""
- cgroupsPerQOS: true
- clusterDNS: ""
- clusterDomain: ""
- cniBinDir: /opt/cni/bin
- cniCacheDirs: /var/lib/cni/cache
- cniConfDir: /etc/cni/net.d
- concurrentConsumers: 5
- devicePluginEnabled: false
- dockerAddress: unix:///var/run/docker.sock
- edgedMemoryCapacity: 7852396000
- enable: true
- enableMetrics: true
- gpuPluginEnabled: false
- hostnameOverride: edge.kubeedge
- imageGCHighThreshold: 80
- imageGCLowThreshold: 40
- imagePullProgressDeadline: 60
- maximumDeadContainersPerPod: 1
- networkPluginMTU: 1500
- nodeIP: 9.63.252.227
- nodeStatusUpdateFrequency: 10
- podSandboxImage: kubeedge/pause:3.1
- registerNode: true
- registerNodeNamespace: default
- remoteImageEndpoint: unix:///var/run/isulad.sock
- remoteRuntimeEndpoint: unix:///var/run/isulad.sock
- runtimeRequestTimeout: 2
- runtimeType: remote
- volumeStatsAggPeriod: 60000000000
- eventBus:
- enable: true
- eventBusTLS:
- enable: false
- tlsMqttCAFile: /etc/kubeedge/ca/rootCA.crt
- tlsMqttCertFile: /etc/kubeedge/certs/server.crt
- tlsMqttPrivateKeyFile: /etc/kubeedge/certs/server.key
- mqttMode: 2
- mqttQOS: 0
- mqttRetain: false
- mqttServerExternal: tcp://127.0.0.1:1883
- mqttServerInternal: tcp://127.0.0.1:1884
- mqttSessionQueueSize: 100
- metaManager:
- contextSendGroup: hub
- contextSendModule: websocket
- enable: true
- metaServer:
- debug: false
- enable: true
- podStatusSyncInterval: 60
- remoteQueryTimeout: 60
- serviceBus:
- enable: false
-
-```
-
-### daemon.json
-
-```bash
-# Application scenarios: cloud and edge nodes
-# File path: /etc/isulad/daemon.json
-{
- "group": "isula",
- "default-runtime": "lcr",
- "graph": "/var/lib/isulad",
- "state": "/var/run/isulad",
- "engine": "lcr",
- "log-level": "ERROR",
- "pidfile": "/var/run/isulad.pid",
- "log-opts": {
- "log-file-mode": "0600",
- "log-path": "/var/lib/isulad",
- "max-file": "1",
- "max-size": "30KB"
- },
- "log-driver": "stdout",
- "container-log": {
- "driver": "json-file"
- },
- "hook-spec": "/etc/default/isulad/hooks/default.json",
- "start-timeout": "2m",
- "storage-driver": "overlay2",
- "storage-opts": [
- "overlay2.override_kernel_check=true"
- ],
- "registry-mirrors": [
- "docker.io"
- ],
- "insecure-registries": [
- "k8s.gcr.io",
- "quay.io",
- "hub.oepkgs.net"
- ],
- "pod-sandbox-image": "k8s.gcr.io/pause:3.2", # Set this parameter to kubeedge/pause:3.1 for edge nodes.
- "websocket-server-listening-port": 10351,
- "native.umask": "secure",
- "network-plugin": "cni",
- "cni-bin-dir": "/opt/cni/bin",
- "cni-conf-dir": "/etc/cni/net.d",
- "image-layer-check": false,
- "use-decrypted-key": true,
- "insecure-skip-verify-enforce": false
-}
-```
+The deployment of KubeEdge is complete.
diff --git a/docs/en/docs/SecHarden/account-passwords.md b/docs/en/docs/SecHarden/account-passwords.md
index 66c373ad5..4ccfd0c14 100644
--- a/docs/en/docs/SecHarden/account-passwords.md
+++ b/docs/en/docs/SecHarden/account-passwords.md
@@ -1,13 +1,13 @@
# Account Passwords
- [Account Passwords](#account-passwords)
- - [Shielding System Accounts](#shielding-system-accounts)
- - [Restricting Permissions on the su Command](#restricting-permissions-on-the-su-command)
- - [Setting Password Complexity](#setting-password-complexity)
- - [Setting the Password Validity Period](#setting-the-password-validity-period)
- - [Setting Password Encryption Algorithms](#setting-password-encryption-algorithms)
- - [Locking an Account After Three Login Failures](#locking-an-account-after-three-login-failures)
- - [Hardening the su Command](#hardening-the-su-command)
+ - [Shielding System Accounts](#shielding-system-accounts)
+ - [Restricting Account Permissions on the su Command](#restricting-account-permissions-on-the-su-command)
+ - [Setting Password Complexity](#setting-password-complexity)
+ - [Setting the Password Validity Period](#setting-the-password-validity-period)
+ - [Setting Password Encryption Algorithms](#setting-password-encryption-algorithms)
+ - [Locking an Account After Three Login Failures](#locking-an-account-after-three-login-failures)
+ - [Hardening the su Command](#hardening-the-su-command)
## Shielding System Accounts
@@ -26,11 +26,11 @@ usermod -L -s /sbin/nologin $systemaccount
> **NOTE:**
>_$systemaccount_ indicates the system account.
-## Restricting Permissions on the su Command
+## Restricting Account Permissions on the su Command
### Description
-The **su** command is used to switch user accounts. To improve system security, only the user **root** and users in the wheel group can use the **su** command.
+The **su** command is used to switch user accounts. To improve system security, only the user **root** and users in the **wheel** group can use the **su** command.
### Implementation
@@ -86,12 +86,12 @@ This section provides an example for configuring password complexity.
- At least one space or one of the following special characters: \` \~ ! @ \# $ % ^ & \* \( \) - \_ = + \\ | \[ \{ \} \] ; : ' " , < . \> / ?
-3. Cannot be the same as an account or the account in reverse order.
+3. Cannot be the same as an account name or the account name in reverse order.
4. Cannot be the last five passwords used.
**Implementation**
-Add the following content to the first two lines of password in the **/etc/pam.d/password-auth** and **/etc/pam.d/system-auth** files:
+Add the following content to the first two lines of the **password** configuration item in the **/etc/pam.d/password-auth** and **/etc/pam.d/system-auth** files:
```
password requisite pam_pwquality.so minlen=8 minclass=3 enforce_for_root try_first_pass local_users_only retry=3 dcredit=0 ucredit=0 lcredit=0 ocredit=0
@@ -271,16 +271,16 @@ password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_au
### Description
-To ensure user system security, you are advised to set the maximum number of incorrect password attempts \(three attempts are recommended\) and the automatic unlocking time \(300 seconds are recommended\) for a locked account.
+To ensure user system security, you are advised to set the maximum number of failed login attempts \(three attempts are recommended\) and the automatic unlocking time \(300 seconds are recommended\) for a locked account.
-If an account is locked, any input is invalid but does not cause the locking timer to recount. Records of the user's invalid inputs are cleared once unlocked. The preceding settings protect passwords from being forcibly cracked and improve system security.
+If an account is locked, any input is invalid but does not reset the locking countdown timer. Records of the user's invalid inputs are cleared once unlocked. The preceding settings protect passwords from being forcibly cracked and improve system security.
> **NOTE:**
->By default, the maximum number of incorrect password attempts is 3 in openEuler. After the system is locked, the automatic unlock time is 60 seconds.
+>By default, the maximum number of failed login attempts is 3 in openEuler. After an account is locked, the automatic unlock time is 60 seconds.
### Implementation
-The password complexity is set by modifying the **/etc/pam.d/password-auth** and **/etc/pam.d/system-auth** files. The maximum number of incorrect password attempts is set to **3**, and the unlocking time after the system is locked is set to **300** seconds. The configuration is as follows:
+The password complexity is set by modifying the **/etc/pam.d/password-auth** and **/etc/pam.d/system-auth** files. The maximum number of failed login attempts is set to **3**, and the unlocking time after an account is locked is set to **300** seconds. The configuration is as follows:
```
auth required pam_faillock.so preauth audit deny=3 even_deny_root unlock_time=300
@@ -304,12 +304,12 @@ auth sufficient pam_faillock.so authsucc audit deny=3 even_deny_root u
|
deny=3
|
-A user account will be locked after three login attempts.
+ | A user account will be locked after three failed login attempts.
|
unlock_time=300
|
-A locked common user account is automatically unlocked in 300 seconds.
+ | A locked common user account is automatically unlocked after 300 seconds.
|
even_deny_root
diff --git a/docs/en/docs/StratoVirt/VM_management.md b/docs/en/docs/StratoVirt/VM_management.md
index c58a74382..7796925b1 100644
--- a/docs/en/docs/StratoVirt/VM_management.md
+++ b/docs/en/docs/StratoVirt/VM_management.md
@@ -165,25 +165,51 @@ QMP provides the quit command to exit a VM, that is, to exit the StratoVirt proc
StratoVirt allows you to adjust the number of disks when a VM is running. That is, you can add or delete VM disks without interrupting services.
-#### Hot Plugged-in Disks
+**Note**
+
+* For a standard VM, the **CONFIG_HOTPLUG_PCI_PCIE=y** configuration must be enabled for the VM kernel.
+
+* For a standard VM, devices can be hot added to the root port. The root port device must be configured before the VM is started.
+
+* You are not advised to hot swap a device when the VM is being started, stopped, or under high internal pressure. Otherwise, the VM may become abnormal because the drivers on the VM cannot respond in a timely manner.
+
+#### Hot Adding Disks
**Usage:**
+Lightweight VM:
+
```
{"execute": "blockdev-add", "arguments": {"node-name": "drive-0", "file": {"driver": "file", "filename": "/path/to/block"}, "cache": {"direct": true}, "read-only": false}}
{"execute": "device_add", "arguments": {"id": "drive-0", "driver": "virtio-blk-mmio", "addr": "0x1"}}
```
+Standard VM:
+
+```
+{"execute": "blockdev-add", "arguments": {"node-name": "drive-0", "file": {"driver": "file", "filename": "/path/to/block"}, "cache": {"direct": true}, "read-only": false}}
+{"execute":"device_add", "arguments":{"id":"drive-0", "driver":"virtio-blk-pci", "drive": "drive-0", "addr":"0x0", "bus": "pcie.1"}}
+```
+
**Parameters:**
-- The value of **node-name** in **blockdev-add** must be the same as the value of **id** in **device_add**. For example, both values are **drive-0** in the preceding example.
-- **/path/to/block** is the image path of the hot plugged-in disks. It cannot be the path of the disk image that boots the rootfs.
-- For **addr**, **0x0** is mapped to **vda** of the VM, **0x1** is mapped to **vdb**, and so on. To be compatible with the QMP protocol, **addr** can be replaced by **lun**, but **lun=0** is mapped to the **vdb** of the client.
-- StratoVirt supports a maximum of six virtio-blk disks. Note this when hot plugging in disks.
+- For a lightweight VM, the value of **node-name** in **blockdev-add** must be the same as that of **id** in **device_add**. For example, the values of **node-name** and **id** are both **drive-0** as shown above.
+
+- For a standard VM, the value of **drive** must be the same as that of **node-name** in **blockdev-add**.
+
+- **/path/to/block** is the image path of the hot added disks. It cannot be the path of the disk image that boots the rootfs.
+
+- For a lightweight VM, the value of **addr**, starting from **0x0**, is mapped to a virtio device on the VM. **0x0** is mapped to **vda**, **0x1** is mapped to **vdb**, and so on. To be compatible with the QMP protocol, **addr** can be replaced by **lun**, but **lun=0** is mapped to the **vdb** of the guest machine. For a standard VM, the value of **addr** must be **0x0**.
+
+- For a standard VM, **bus** indicates the name of the bus to mount the device. Currently, the device can be hot added only to the root port device. The value of **bus** must be the ID of the root port device.
+
+- For a lightweight VM, StratoVirt supports a maximum of six virtio-blk disks. Note this when hot adding disks. For a standard VM, the maximum number of hot added disks depends on the number of root port devices.
**Example:**
+Lightweight VM:
+
```
<- {"execute": "blockdev-add", "arguments": {"node-name": "drive-0", "file": {"driver": "file", "filename": "/path/to/block"}, "cache": {"direct": true}, "read-only": false}}
-> {"return": {}}
@@ -191,29 +217,70 @@ StratoVirt allows you to adjust the number of disks when a VM is running. That i
-> {"return": {}}
```
-#### Hot Plugged-out Disks
+Standard VM:
+
+```
+<- {"execute": "blockdev-add", "arguments": {"node-name": "drive-0", "file": {"driver": "file", "filename": "/path/to/block"}, "cache": {"direct": true}, "read-only": false}}
+-> {"return": {}}
+<- {"execute":"device_add", "arguments":{"id":"drive-0", "driver":"virtio-blk-pci", "drive": "drive-0", "addr":"0x0", "bus": "pcie.1"}}
+-> {"return": {}}
+```
+#### Hot Removing Disks
**Usage:**
-**{"execute": "device_del", "arguments": {"id":"drive-0"}}**
+Lightweight VM:
+
+```
+{"execute": "device_del", "arguments": {"id":"drive-0"}}
+```
+
+Standard VM:
+
+```
+{"execute": "device_del", "arguments": {"id":"drive-0"}}
+{"execute": "blockdev-del", "arguments": {"node-name": "drive-0"}}
+```
**Parameters:**
-**id** indicates the ID of the hot plugged-out disk.
+**id** indicates the ID of the disk to be hot removed.
+- **node-name** indicates the backend name of the disk.
**Example:**
+Lightweight VM:
+
```
<- {"execute": "device_del", "arguments": {"id": "drive-0"}}
-> {"event":"DEVICE_DELETED","data":{"device":"drive-0","path":"drive-0"},"timestamp":{"seconds":1598513162,"microseconds":367129}}
-> {"return": {}}
```
+Standard VM:
+
+```
+<- {"execute": "device_del", "arguments": {"id":"drive-0"}}
+-> {"return": {}}
+-> {"event":"DEVICE_DELETED","data":{"device":"drive-0","path":"drive-0"},"timestamp":{"seconds":1598513162,"microseconds":367129}}
+<- {"execute": "blockdev-del", "arguments": {"node-name": "drive-0"}}
+-> {"return": {}}
+```
+
+A **DEVICE_DELETED** event indicates that the device is removed from StratoVirt.
### Hot-Pluggable NICs
StratoVirt allows you to adjust the number of NICs when a VM is running. That is, you can add or delete VM NICs without interrupting services.
-#### Hot Plugged-in NICs
+**Note**
+
+* For a standard VM, the **CONFIG_HOTPLUG_PCI_PCIE=y** configuration must be enabled for the VM kernel.
+
+* For a standard VM, devices can be hot added to the root port. The root port device must be configured before the VM is started.
+
+* You are not advised to hot swap a device when the VM is being started, stopped, or under high internal pressure. Otherwise, the VM may become abnormal because the drivers on the VM cannot respond in a timely manner.
+
+#### Hot Adding NICs
**Preparations (Requiring the root Permission)**
@@ -239,21 +306,36 @@ StratoVirt allows you to adjust the number of NICs when a VM is running. That is
**Usage:**
+Lightweight VM:
+
```
{"execute":"netdev_add", "arguments":{"id":"net-0", "ifname":"tap0"}}
{"execute":"device_add", "arguments":{"id":"net-0", "driver":"virtio-net-mmio", "addr":"0x0"}}
```
+Standard VM:
+
+```
+{"execute":"netdev_add", "arguments":{"id":"net-0", "ifname":"tap0"}}
+{"execute":"device_add", "arguments":{"id":"net-0", "driver":"virtio-net-pci", "addr":"0x0", "netdev": "net-0", "bus": "pcie.1"}}
+```
+
**Parameters:**
-- **id** in **netdev_add** must be the same as that in **device_add**. **ifname** is the name of the backend tap device.
+- For a lightweight VM, **id** in **netdev_add** must be the same as that in **device_add**. **ifname** is the name of the backend tap device.
+
+- For a standard VM, the value of **netdev** must be the value of **id** in **netdev_add**.
-- For **addr**, **0x0** is mapped to **eth0** of the VM, **0x1** is mapped to **eth1**, and so on.
+- For a lightweight VM, the value of **addr**, starting from **0x0**, is mapped to an NIC on the VM. **0x0** is mapped to **eth0 **, **0x1** is mapped to **eth1**. For a standard VM, the value of **addr** must be **0x0**.
-- StratoVirt supports a maximum of two virtio-net NICs. Therefore, pay attention to the specification restrictions when hot plugging in NICs.
+- For a standard VM, **bus** indicates the name of the bus to mount the device. Currently, the device can be hot added only to the root port device. The value of **bus** must be the ID of the root port device.
+
+- For a lightweight VM, StratoVirt supports a maximum of two virtio-net NICs. Therefore, pay attention to the specification restrictions when hot adding in NICs. For a standard VM, the maximum number of hot added disks depends on the number of root port devices.
**Example:**
+Lightweight VM:
+
```
<- {"execute":"netdev_add", "arguments":{"id":"net-0", "ifname":"tap0"}}
-> {"return": {}}
@@ -263,24 +345,120 @@ StratoVirt allows you to adjust the number of NICs when a VM is running. That is
**addr:0x0** corresponds to **eth0** in the VM.
-#### Hot Plugged-out NICs
+Standard VM:
+
+```
+<- {"execute":"netdev_add", "arguments":{"id":"net-0", "ifname":"tap0"}}
+-> {"return": {}}
+<- {"execute":"device_add", "arguments":{"id":"net-0", "driver":"virtio-net-pci", "addr":"0x0", "netdev": "net-0", "bus": "pcie.1"}}
+-> {"return": {}}
+```
+
+#### Hot Removing NICs
**Usage:**
-**{"execute": "device_del", "arguments": {"id": "net-0"}}**
+Lightweight VM:
+
+```
+{"execute": "device_del", "arguments": {"id": "net-0"}}
+```
+
+Standard VM:
+
+```
+{"execute": "device_del", "arguments": {"id":"net-0"}}
+{"execute": "netdev_del", "arguments": {"id": "net-0"}}
+```
+
**Parameters:**
**id**: NIC ID, for example, **net-0**.
+- **id** in **netdev_del** indicates the backend name of the NIC.
+
**Example:**
+Lightweight VM:
+
```
<- {"execute": "device_del", "arguments": {"id": "net-0"}}
-> {"event":"DEVICE_DELETED","data":{"device":"net-0","path":"net-0"},"timestamp":{"seconds":1598513339,"microseconds":97310}}
-> {"return": {}}
```
+Standard VM:
+
+```
+<- {"execute": "device_del", "arguments": {"id":"net-0"}}
+-> {"return": {}}
+-> {"event":"DEVICE_DELETED","data":{"device":"net-0","path":"net-0"},"timestamp":{"seconds":1598513339,"microseconds":97310}}
+<- {"execute": "netdev_del", "arguments": {"id": "net-0"}}
+-> {"return": {}}
+```
+
+A **DEVICE_DELETED** event indicates that the device is removed from StratoVirt.
+
+### Hot-swappable Pass-through Devices
+
+You can add or delete the passthrough devices of a StratoVirt standard VM when it is running.
+
+**Note**
+
+* The **CONFIG_HOTPLUG_PCI_PCIE=y** configuration must be enabled for the VM kernel.
+
+* Devices can be hot added to the root port. The root port device must be configured before the VM is started.
+
+* You are not advised to hot swap a device when the VM is being started, stopped, or under high internal pressure. Otherwise, the VM may become abnormal because the drivers on the VM cannot respond in a timely manner.
+
+#### Hot Adding Pass-through Devices
+
+**Usage:**
+
+```
+{"execute":"device_add", "arguments":{"id":"vfio-0", "driver":"vfio-pci", "bus": "pcie.1", "addr":"0x0", "host": "0000:1a:00.3"}}
+```
+
+**Parameters:**
+
+- **id** indicates the ID of the hot added device.
+
+- **bus** indicates the name of the bus to mount the device.
+
+- **addr** indicates the slot and function numbers to mount the device. Currently, **addr** must be set to **0x0**.
+
+- **host** indicates the domain number, bus number, slot number, and function number of the passthrough device on the host machine.
+
+**Example:**
+
+```
+<- {"execute":"device_add", "arguments":{"id":"vfio-0", "driver":"vfio-pci", "bus": "pcie.1", "addr":"0x0", "host": "0000:1a:00.3"}}
+-> {"return": {}}
+```
+
+#### Hot Removing Pass-through Devices
+
+**Usage:**
+
+```
+{"execute": "device_del", "arguments": {"id": "vfio-0"}}
+```
+
+**Parameters:**
+
+- **id** indicates the ID of the device to be hot removed, which is specified when the device is hot added.
+
+**Example:**
+
+```
+<- {"execute": "device_del", "arguments": {"id": "vfio-0"}}
+-> {"return": {}}
+-> {"event":"DEVICE_DELETED","data":{"device":"vfio-0","path":"vfio-0"},"timestamp":{"seconds":1614310541,"microseconds":554250}}
+```
+
+A **DEVICE_DELETED** event indicates that the device is removed from StratoVirt.
+
## Using Ballon Devices
The balloon device is used to reclaim idle memory from a VM. It called by running the QMP command.
diff --git a/docs/en/docs/StratoVirt/interconnect_isula.md b/docs/en/docs/StratoVirt/interconnect_isula.md
index 02ee4d5cb..baa77be73 100644
--- a/docs/en/docs/StratoVirt/interconnect_isula.md
+++ b/docs/en/docs/StratoVirt/interconnect_isula.md
@@ -51,7 +51,7 @@ The following describes how to install and configure iSulad and kata-containers.
],
```
-3. Restart isulad.
+3. Restart **isulad**.
```shell
# systemctl daemon-reload
@@ -76,15 +76,18 @@ The following describes how to install and configure iSulad and kata-containers.
This section describes how to interconnect StratoVirt with kata-containers to access the iSula container ecosystem.
-1. Modify the kata configuration file. Its default path is **/usr/share/defaults/kata-containers/configuration.toml**. You can also configure the file by referring to **configuration-stratovirt.toml** in the same directory. Set the Hypervisor type of the secure container to **stratovirt**, kernel to the absolute path of the kernel image of kata-containers, and initrd to the **initrd** image file of kata-containers. (If you use Yum to install kata-containers, the two image files are downloaded and stored in the **/var/lib/kata/** directory by default. You can also use other images during the configuration.)
+#### Connecting to a Lightweight VM
- The configurations are as follows:
+1. Modify the kata configuration file. Its default path is **/usr/share/defaults/kata-containers/configuration.toml**. You can also configure the file by referring to **configuration-stratovirt.toml** in the same directory. Modify the **hypervisor** type of the secure container to **stratovirt**, **kernel** to the absolute path of the kernel image of kata-containers, and **initrd** to the **initrd** image file of kata-containers. (If you use Yum to install kata-containers, the two image files are downloaded and stored in the **/var/lib/kata/** directory by default. You can also use other images during the configuration.)
+
+ The modified configurations are as follows:
```shell
[hypervisor.stratovirt]
path = "/usr/bin/stratovirt"
kernel = "/var/lib/kata/kernel"
initrd = "/var/lib/kata/kata-containers-initrd.img"
+ machine_type = "microvm"
block_device_driver = "virtio-mmio"
use_vsock = true
enable_netmon = true
@@ -95,7 +98,7 @@ This section describes how to interconnect StratoVirt with kata-containers to ac
disable_vhost_net = true
```
-2. Run the `isula` command **root** permissions to start the BusyBox secure container and interconnect StratoVirt with it.
+2. Run the `isula` command with **root** permissions to start the BusyBox secure container and interconnect StratoVirt with it.
```shell
# isula run -tid --runtime "io.containerd.kata.v2" --net=none --name test busybox:latest sh
@@ -103,7 +106,7 @@ This section describes how to interconnect StratoVirt with kata-containers to ac
3. Run the `isula ps` command to check whether the secure container **test** is running properly. Then run the following command to access the container:
- ```
+ ```shell
# isula exec –ti test sh
```
@@ -141,3 +144,80 @@ This section describes how to interconnect StratoVirt with kata-containers to ac
```
You can now run container commands in the **test** container.
+
+#### Connecting to a Standard VM
+
+To use a StratoVirt standard VM as the sandbox of a secure container, you need to modify some other configurations.
+
+1. The configurations are as follows:
+
+ ```shell
+ [hypervisor.stratovirt]
+ path = "/usr/bin/stratovirt"
+ kernel = "/var/lib/kata/kernel"
+ initrd = "/var/lib/kata/kata-containers-initrd.img"
+ # x86_64 architecture
+ machine_type = "q35"
+ # AArch64 architecture
+ machine_type = "virt"
+ block_device_driver = "virtio-blk"
+ pcie_root_port = 2
+ use_vsock = true
+ enable_netmon = true
+ internetworking_model = "tcfilter"
+ sandbox_cgroup_with_emulator = false
+ disable_new_netns = false
+ disable_block_device_use = false
+ disable_vhost_net = true
+ ```
+
+ In the configurations above, modify the VM type according to the architecture of the host machine. Change the value of **block_device_driver** to **virtio-blk**. StratoVirt supports only devices hot-plugged to the root port. Set a proper value of **pcie_root_port** based on the number of devices to be hot-plugged.
+
+2. Install the firmware required for starting a standard VM.
+
+ x86_64 architecture:
+
+ ```shell
+ # yum install -y edk2-ovmf
+ ```
+
+ AArch64 architecture:
+
+ ```shell
+ # yum install -y edk2-aarch64
+ ```
+
+3. Build and replace the binary file of kata-containers 2.x.
+
+ Currently, a StratoVirt standard VMs can only be used as the sandbox of a kata-containers 2.x container (corresponding to the openEuler-21.09 branch in the kata-containers repository). You need to download and compile the kata-containers source code and replace the **containerd-shim-kata-v2** binary file in the **/usr/bin** directory.
+
+ ```shell
+ # mkdir -p /root/go/src/github.com/
+ # cd /root/go/src/github.com/
+ # git clone https://gitee.com/src-openeuler/kata-containers.git
+ # cd kata-containers
+ # git checkout openEuler-21.09
+ # ./apply-patches
+ # cd src/runtime
+ # make
+ ```
+
+ Back up the kata binary file in the **/usr/bin/** directory and replace it with the compiled binary file **containerd-shim-kata-v2**.
+
+ ```shell
+ # cp /usr/bin/containerd-shim-kata-v2 /usr/bin/containerd-shim-kata-v2.bk
+ # cp containerd-shim-kata-v2 /usr/bin/containerd-shim-kata-v2
+ ```
+
+4. Run the `isula` command with **root** permissions to start the BusyBox secure container and interconnect StratoVirt with it.
+
+ ```shell
+ # isula run -tid --runtime "io.containerd.kata.v2" --net=none --name test busybox:latest sh
+ ```
+
+5. Run the `isula ps` command to check whether the secure container **test** is running properly. Then run the following command to access the container:
+
+ ```shell
+ # isula exec -ti test sh
+ ```
+
diff --git a/docs/en/docs/Virtualization/LibcarePlus.md b/docs/en/docs/Virtualization/LibcarePlus.md
new file mode 100644
index 000000000..d554c3fc5
--- /dev/null
+++ b/docs/en/docs/Virtualization/LibcarePlus.md
@@ -0,0 +1,410 @@
+# LibcarePlus
+
+
+
+- [LibcarePlus](#libcareplus)
+ - [Overview](#overview)
+ - [Hardware and Software Requirements](#hardware-and-software-requirements)
+ - [Precautions and Constraints](#precautions-and-constraints)
+ - [Installing LibcarePlus](#installing-libcareplus)
+ - [Software Installation Dependencies](#software-installation-dependencies)
+ - [Installing LibcarePlus](#installing-libcareplus-1)
+ - [Creating LibcarePlus Hot Patches](#creating-libcareplus-hot-patches)
+ - [Introduction](#introduction)
+ - [Manual Creation](#manual-creation)
+ - [Creation Through a Script](#creation-through-a-script)
+ - [Applying the LibcarePlus Hot Patch](#applying-the-libcareplus-hot-patch)
+ - [Preparation](#preparation)
+ - [Loading the Hot Patch](#loading-the-hot-patch)
+ - [Querying a Hot Patch](#querying-a-hot-patch)
+ - [Uninstalling the Hot Patch](#uninstalling-the-hot-patch)
+
+
+
+## Overview
+
+LibcarePlus is a hot patch framework for user-mode processes. It can perform hot patch operations on target processes running on the Linux system without restarting the processes. Hot patches can be used to fix CVEs and urgent bugs that do not interrupt application services.
+
+## Hardware and Software Requirements
+
+The following software and hardware requirements must be met to use LibcarePlus on openEuler:
+
+- Currently, the x86 and ARM64 architectures are supported.
+
+- LibcarePlus can run on any Linux distribution that supports **libunwind**, **elfutils**, and **binutils**.
+- LibcarePlus uses the **ptrace()** system call, which requires the kernel configuration option enabled for the corresponding Linux distribution.
+- LibcarePlus needs the symbol table of the original executable file when creating a hot patch. Do not strip the symbol table too early.
+- On the Linux OS where SELinux is enabled, manually adapt the SELinux policies.
+
+## Precautions and Constraints
+
+When using LibcarePlus, comply with the following hot patch specifications and constraints:
+
+- Only the code written in the C language is supported. The assembly language is not supported.
+- Only user-mode programs are supported. Dynamic library patches are not supported.
+- The code file name must comply with the C language identifier naming specifications. That is, the code file name consists of letters (A-Z and a-z), digits (0-9), and underscores (_) but the first character cannot be a digit. Special characters such as hyphens (-) and dollar signs ($) are not allowed.
+- Incremental patches are supported. Multiple patches can be installed on a process. However, you need to design the patch installation and uninstallation management. Generally, the installation and uninstallation comply with the first-in, last-out (FILO) rule.
+- Automatic patch loading is not natively supported. You can design an automatic patch loading method for a specific process.
+- Patch query is supported.
+- The static function patch is restricted by the symbol table that can find the function in the system.
+- Hot patches are process-specific. That is, a hot patch of a dynamic library can be applied only to process that invoke the dynamic library.
+- The number of patches that can be applied to a process is limited by the range of the jump instruction and the size of the hole in the virtual memory address space. Generally, up to 512 patches can be applied to a process.
+- Thread local storage (TLS) variables of the initial executable (IE) model can be modified.
+- Symbols defined in a patch cannot be used in subsequent patches.
+- Hot patches are not supported in the following scenarios:
+ - Infinite loop function, non-exit function, inline function, initialization function, and non-maskable interrupt (NMI) function
+ - Replacing global variables
+ - Functions less than 5 bytes
+ - Modifying the header file
+ - Adding or deleting the input and output parameters of the target function
+ - Changing (adding, deleting, or modifying) data structure members
+ - Modifying the C files that contain GCC macros such as __LINE__ and __FILE__
+ - Modifying the Intel vector assembly instruction
+
+## Installing LibcarePlus
+
+### Software Installation Dependencies
+
+The LibcarePlus running depends on **libunwind**, **elfutils**, and **binutils**. On the openEuler system configured with the Yum repo, you can run the following commands to install the software on which LibcarePlus depends:
+
+``` shell
+# yum install -y binutils elfutils elfutils-libelf-devel libunwind-devel
+```
+
+#### Installing LibcarePlus
+
+```shell
+# yum install libcareplus -y
+```
+
+Check whether LibcarePlus is installed.
+
+``` shell
+# libcare-ctl -h
+usage: libcare-ctl [options] [args]
+
+Options:
+ -v - verbose mode
+ -h - this message
+
+Commands:
+ patch - apply patch to a user-space process
+ unpatch- unapply patch from a user-space process
+ info - show info on applied patches
+```
+
+## Creating LibcarePlus Hot Patches
+
+### Introduction
+
+LibcarePlus hot patch creation methods:
+
+- Manual creation
+- Creation through a script
+
+The process of manually creating a hot patch is complex. For a project with a large amount of code, for example, QEMU, it is extremely difficult to manually create a hot patch. You are advised to use the script provided by LibcarePlus to generate a hot patch file with one click.
+
+#### Manual Creation
+
+The following takes the original file **foo.c** and the patch file **bar.c** as examples to describe how to manually create a hot patch.
+
+1. Prepare the original file and patch file written in the C language. For example, **foo.c** and **bar.c**.
+
+
+ Expand foo.c
+
+
+ ``` c
+ // foo.c
+ #include
+ #include
+
+ void print_hello(void)
+ {
+ printf("Hello world!\n");
+ }
+
+ int main(void)
+ {
+ while (1) {
+ print_hello();
+ sleep(1);
+ }
+ }
+ ```
+
+
+
+
+
+ Expand bar.c
+
+
+ ``` c
+ // bar.c
+ #include
+ #include
+
+ void print_hello(void)
+ {
+ printf("Hello world %s!\n", "being patched");
+ }
+
+ int main(void)
+ {
+ while (1) {
+ print_hello();
+ sleep(1);
+ }
+ }
+ ```
+
+
+
+
+2. Build the original file and patch file to obtain the assembly files **foo.s** and **bar.s**.
+
+ ``` shell
+ # gcc -S foo.c
+ # gcc -S bar.c
+ # ls
+ bar.c bar.s foo.c foo.s
+ ```
+
+3. Run `kpatch_gensrc` to compare **foo.s** and **bar.s** and generate the **foobar.s** file that contains the assembly content of the original file and the differences.
+
+ ``` shell
+ # sed -i 's/bar.c/foo.c/' bar.s
+ # kpatch_gensrc --os=rhel6 -i foo.s -i bar.s -o foobar.s --force-global
+ ```
+
+ By default, `kpatch_gensrc` compares the original files in the same C language. Therefore, before the comparison, you need to run the `sed` command to change the file name **bar.c** in the patch assembly file **bar.s** to the original file name **foo.c**. Call `kpatch_gensrc` to specify the input files as **foo.s** and **bar.s** and the output file as **foobar.s**.
+
+4. Build the assembly file **foo.s** in the original file and the generated assembly file **foobar.s** to obtain the executable files **foo** and **foobar**.
+
+ ``` shell
+ # gcc -o foo foo.s
+ # gcc -o foobar foobar.s -Wl,-q
+ ```
+
+ The **-Wl, -q** linker options reserve the relocation sections in **foobar**.
+
+5. Use `kpatch_strip` to remove the duplicate content from the executables **foo** and **foobar** and reserve the content required for creating hot patches.
+
+ ``` shell
+ # kpatch_strip --strip foobar foobar.stripped
+ # kpatch_strip --rel-fixup foo foobar.stripped
+ # strip --strip-unneeded foobar.stripped
+ # kpatch_strip --undo-link foo foobar.stripped
+ ```
+
+ The options in the preceding command are described as follows:
+
+ - **--strip** removes useless sections for patch creation from **foobar**.
+ - **--rel-fixup** repairs the address of the variables and functions accessed in the patch.
+ - **strip --strip-unneeded** removes the useless symbol information for hot patch relocation.
+ - **--undo-link** changes the symbol address in a patch from absolute to relative.
+
+6. Create a hot patch file.
+
+ After the preceding operations, the contents required for creating the hot patch are obtained. Run the `kpatch_make` command to input parameters Build ID of the original executable file and **foobar.stripped** (output file of `kpatch_strip`) to `kpatch_make` to generate a hot patch file.
+
+ ``` shell
+ # str=$(readelf -n foo | grep 'Build ID')
+ # substr=${str##* }
+ # kpatch_make -b $substr -i 0001 foobar.stripped -o foo.kpatch
+ # ls
+ bar.c bar.s foo foobar foobar.s foobar.stripped foo.c foo.kpatch foo.s
+ ```
+
+ The final hot patch file **foo.kpatch** whose patch ID is **0001** is obtained.
+
+#### Creation Through a Script
+
+This section describes how to use LibcarePlus built-in **libcare-patch-make** script to create a hot patch file. The original file **foo.c** and patch file **bar.c** are used as an example.
+
+1. Run the `diff` command to generate the comparison file of **foo.c** and **bar.c**.
+
+ ``` shell
+ # diff -up foo.c bar.c > foo.patch
+ ```
+
+ The content of the **foo.patch** file is as follows:
+
+
+ Expand foo.patch
+
+
+
+ ``` diff
+ --- foo.c 2020-12-09 15:39:51.159632075 +0800
+ +++ bar.c 2020-12-09 15:40:03.818632220 +0800
+ @@ -1,10 +1,10 @@
+ -// foo.c
+ +// bar.c
+ #include
+ #include
+
+ void print_hello(void)
+ {
+ - printf("Hello world!\n");
+ + printf("Hello world %s!\n", "being patched");
+ }
+
+ int main(void)
+ ```
+
+
+
+
+
+2. Write the **makefile** for building **foo.c** as follows:
+
+
+ Expand makefile
+
+
+ ``` makefile
+ all: foo
+
+ foo: foo.c
+ $(CC) -o $@ $<
+
+ clean:
+ rm -f foo
+
+ install: foo
+ mkdir $$DESTDIR || :
+ cp foo $$DESTDIR
+ ```
+
+
+
+
+
+3. After the **makefile** is done, directly call `libcare-patch-make`. If `libcare-patch-make` asks you which file to install the patch, enter the original file name, as shown in the following:
+
+ ``` shell
+ # libcare-patch-make --clean -i 0001 foo.patch
+ rm -f foo
+ BUILDING ORIGINAL CODE
+ /usr/local/bin/libcare-cc -o foo foo.c
+ INSTALLING ORIGINAL OBJECTS INTO /libcareplus/test/lpmake
+ mkdir $DESTDIR || :
+ cp foo $DESTDIR
+ applying foo.patch...
+ can't find file to patch at input line 3
+ Perhaps you used the wrong -p or --strip option?
+ The text leading up to this was:
+ --------------------------
+ |--- foo.c 2020-12-10 09:43:04.445375845 +0800
+ |+++ bar.c 2020-12-10 09:48:36.778379648 +0800
+ --------------------------
+ File to patch: foo.c
+ patching file foo.c
+ BUILDING PATCHED CODE
+ /usr/local/bin/libcare-cc -o foo foo.c
+ INSTALLING PATCHED OBJECTS INTO /libcareplus/test/.lpmaketmp/patched
+ mkdir $DESTDIR || :
+ cp foo $DESTDIR
+ MAKING PATCHES
+ Fixing up relocation printf@@GLIBC_2.2.5+fffffffffffffffc
+ Fixing up relocation print_hello+0
+ patch for /libcareplus/test/lpmake/foo is in /libcareplus/test/patchroot/700297b7bc56a11e1d5a6fb564c2a5bc5b282082.kpatch
+ ```
+
+ After the command is executed, the output indicates that the hot patch file is in the **patchroot** directory of the current directory, and the executable file is in the **lpmake** directory. By default, the Build ID is used to name a hot patch file generated by a script.
+
+
+
+## Applying the LibcarePlus Hot Patch
+
+This following uses the original file **foo.c** and patch file **bar.c** as an example to describe how to use the LibcarePlus hot patch.
+
+### Preparation
+
+Before using the LibcarePlus hot patch, prepare the original executable file **foo** and hot patch file **foo.kpatch**.
+
+### Loading the Hot Patch
+
+The procedure for applying the LibcarePlus hot patch is as follows:
+
+1. In the first shell window, run the executable file to be patched:
+
+ ``` shell
+ # ./lpmake/foo
+ Hello world!
+ Hello world!
+ Hello world!
+ ```
+
+2. In the second shell window, run the `libcare-ctl` command to apply the hot patch:
+
+ ``` shell
+ # libcare-ctl -v patch -p $(pidof foo) ./foo.kpatch
+ ```
+
+ If the hot patch is applied successfully, the following information is displayed in the second shell window:
+
+ ``` shell
+ 1 patch hunk(s) have been successfully applied to PID '10999'
+ ```
+
+ The following information is displayed for the target process running in the first shell window:
+
+ ``` shell
+ Hello world!
+ Hello world!
+ Hello world being patched!
+ Hello world being patched!
+ ```
+
+
+### Querying a Hot Patch
+
+The procedure for querying a LibcarePlus hot patch is as follows:
+
+1. Run the following command in the second shell window:
+
+ ```shell
+ # libcare-ctl info -p $(pidof foo)
+
+ ```
+
+ If a hot patch is installed, the following information is displayed in the second shell window:
+
+ ```shell
+ Pid: 551763
+ Target: foo
+ Build id: df05a25bdadd282812d3ee5f0a460e69038575de
+ Applied patch number: 1
+ Patch id: 0001
+ ```
+
+
+
+
+### Uninstalling the Hot Patch
+
+The procedure for uninstalling the LibcarePlus hot patch is as follows:
+
+1. Run the following command in the second shell window:
+
+ ``` shell
+ # libcare-ctl unpatch -p $(pidof foo)
+ ```
+
+ If the hot patch is uninstalled successfully, the following information is displayed in the second shell window:
+
+ ``` shell
+ 1 patch hunk(s) were successfully cancelled from PID '10999'
+ ```
+
+2. The following information is displayed for the target process running in the first shell window:
+
+ ``` shell
+ Hello world being patched!
+ Hello world being patched!
+ Hello world!
+ Hello world!
+ ```
diff --git a/docs/en/docs/Virtualization/tool-guide.md b/docs/en/docs/Virtualization/tool-guide.md
index 06bbb1650..565ebecf3 100644
--- a/docs/en/docs/Virtualization/tool-guide.md
+++ b/docs/en/docs/Virtualization/tool-guide.md
@@ -1,196 +1 @@
-# Tool Guide
-
-- [vmtop](#vmtop)
-
-## vmtop
-
-### Overview
-
-vmtop is a user-mode tool running on the host machine. You can use the vmtop tool to dynamically view the usage of VM resources in real time, such as CPU usage, memory usage, and the number of vCPU traps. Therefore, the vmtop tool can be used to locate virtualization problems and optimize performance.
-
-#### Multi-Architecture Support
-
-Currently, the vmtop supports the AArch64 and x86_64 processor architectures.
-
-#### Display Item Description
-
-The vmtop display items vary according to the processor architecture. This document describes the meaning of each display item and whether it is displayed in the corresponding architecture.
-Note: The following sampling difference refers to the difference between two times of data obtained in a specified interval.
-
-##### **Display Items of the AArch64 and x86_64 Architectures**
-
-- VM/task-name: VM/Process name
-- DID: VM ID
-- PID: PID of the qemu process of the VM
-- %CPU: CPU usage of a process
-- EXTsum: Total number of KVM exits (sampling difference)
-- S: Process status
-- P: ID of the physical CPU occupied by a process
-- %ST: Ratio of the preemption time to the CPU running time
-- %GUE: Ratio of the VM internal occupation time to the CPU running time
-- %HYP: Virtualization overhead ratio
-
-##### Display Items Only for the Aarch64 Architecture
-
-- EXThvc: Number of hvc-exits (sampling difference)
-- EXTwfe: Number of wfe-exits (sampling difference)
-- EXTwfi: Number of wfi-exits (sampling difference)
-- EXTmmioU: Number of mmioU-exits (sampling difference)
-- EXTmmioK: Number of mmioK-exits (sampling difference)
-- EXTfp: Number of fp-exits (sampling difference)
-- EXTirq: Number of irq-exits (sampling difference)
-- EXTsys64: Number of sys64 exits (sampling difference)
-- EXTmabt: Number of mem abort exits (sampling difference)
-
-##### Display Items Only for the x86_64 Architecture
-
-- PFfix: Number of page faults (sampling difference)
-- PFgu: Number of times that page faults are injected to the guest OS (sampling difference)
-- INvlpg: Number of times that a TLB item is flushed (one of the TLB items, which is not fixed)
-- EXTio: Number of io VM-exit times (sampling difference)
-- EXTmmio: Number of mmio VM-exit times (sampling difference)
-- EXThalt: Number of halt VM-exit times (sampling difference)
-- EXTsig: Number of VM-exits caused by signal processing (sampling difference)
-- EXTirq: Number of VM-exits caused by interrupts (sampling difference)
-- EXTnmiW: Number of VM-exit times caused by non-maskable interrupts (sampling difference)
-- EXTirqW: Interruptwindow mechanism. When the interrupt function is enabled, exit is used to inject interrupts (sampling difference)
-- IrqIn: Number of times that IRQ interrupts are injected (sampling difference)
-- NmiIn: Number of times that NMI interrupts are injected (sampling difference)
-- TLBfl: Number of times that the entire TLB is flushed (sampling difference)
-- HostReL: Number of times that the host status is overloaded (sampling difference)
-- Hyperv: Number of times that the guest OS is simulated to call hypercal in virtualization-assistant mode (sampling difference)
-- EXTcr: Number of times that the access to the CR register exits (sampling difference)
-- EXTrmsr: Number of times that the read MSR exits (sampling difference)
-- EXTwmsr: Number of times that the write MSR exits (sampling difference)
-- EXTapic: Number of APIC write times (sampling difference)
-- EXTeptv: Ept page fault exit times (sampling difference)
-- EXTeptm: Number of Ept error exits (sampling difference)
-- EXTpau: Number of times that the VCPU pauses and exits (sampling difference)
-
-### Usage
-
-vmtop is a command line tool. You can directly run the vmtop in command line mode.
-In addition, the vmtop tool provides different options for querying different information.
-
-#### Syntax
-
-```sh
-vmtop [option]
-```
-
-#### Option Description
-
-- -d: sets the refresh interval, in seconds.
-- -H: displays the VM thread information.
-- -n: sets the number of refresh times and exits after the refresh is complete.
-- -b: displays Batch mode, which can be used to redirect to a file.
-- -h: displays help information.
-- -v: displays versions.
-- -p: monitors the VM with a specified ID.
-
-#### Keyboard Shortcut
-
-Shortcut key used when the vmtop is running.
-
-- H: displays or stops the VM thread information. The information is displayed by default.
-- up/down: moves the VM list upwards or downwards.
-- left/right: moves the cursor leftwards or rightwards to display the columns that are hidden due to the screen width.
-- f: enters the editing mode of a monitoring item and selects the monitoring item to be enabled.
-- q: exits the vmtop process.
-
-### Example
-
-Run the vmtop command on the host.
-
-```sh
-vmtop
-```
-
-The command output is as follows:
-
-```sh
-vmtop - 2020-09-14 09:54:48 - 1.0
-Domains: 1 running
-
- DID VM/task-name PID %CPU EXThvc EXTwfe EXTwfi EXTmmioU EXTmmioK EXTfp EXTirq EXTsys64 EXTmabt EXTsum S P %ST %GUE %HYP
- 2 example 4054916 13.0 0 0 1206 10 0 144 62 174 0 1452 S 106 0.0 99.7 16.0
-```
-
-As shown in the output, there is only one VM named "example" on the host. The ID is 2. The CPU usage is 13.0%. The total number of traps within one second is 1452. The physical CPU occupied by the VM process is CPU 106. The ratio of the VM internal occupation time to the CPU running time is 99.7%.
-
-1. Display VM thread information.
-Press H to display the thread information.
-
-```sh
-vmtop - 2020-09-14 10:11:27 - 1.0
-Domains: 1 running
-
- DID VM/task-name PID %CPU EXThvc EXTwfe EXTwfi EXTmmioU EXTmmioK EXTfp EXTirq EXTsys64 EXTmabt EXTsum S P %ST %GUE %HYP
- 2 example 4054916 13.0 0 0 1191 17 4 120 76 147 0 1435 S 119 0.0 123.7 4.0
- |_ qemu-kvm 4054916 0.0 0 0 0 0 0 0 0 0 0 0 S 119 0.0 0.0 0.0
- |_ qemu-kvm 4054928 0.0 0 0 0 0 0 0 0 0 0 0 S 119 0.0 0.0 0.0
- |_ signalfd_com 4054929 0.0 0 0 0 0 0 0 0 0 0 0 S 120 0.0 0.0 0.0
- |_ IO mon_iothr 4054932 0.0 0 0 0 0 0 0 0 0 0 0 S 117 0.0 0.0 0.0
- |_ CPU 0/KVM 4054933 3.0 0 0 280 6 4 28 19 41 0 350 S 105 0.0 27.9 0.0
- |_ CPU 1/KVM 4054934 3.0 0 0 260 0 0 16 12 36 0 308 S 31 0.0 20.0 0.0
- |_ CPU 2/KVM 4054935 3.0 0 0 341 0 0 44 20 26 0 387 R 108 0.0 27.9 4.0
- |_ CPU 3/KVM 4054936 5.0 0 0 310 11 0 32 25 44 0 390 S 103 0.0 47.9 0.0
- |_ memory_lock 4054940 0.0 0 0 0 0 0 0 0 0 0 0 S 126 0.0 0.0 0.0
- |_ vnc_worker 4054944 0.0 0 0 0 0 0 0 0 0 0 0 S 118 0.0 0.0 0.0
- |_ worker 4143738 0.0 0 0 0 0 0 0 0 0 0 0 S 120 0.0 0.0 0.0
-```
-
-The example VM has 11 threads, including the vCPU thread, vnc_worker, and IO mon_iotreads. Each thread also displays detailed CPU usage and trap information.
-
-2. Select the monitoring item.
-Enter f to edit the monitoring item.
-
-```sh
-field filter - select which field to be showed
-Use up/down to navigate, use space to set whether chosen filed to be showed
-'q' to quit to normal display
-
- * DID
- * VM/task-name
- * PID
- * %CPU
- * EXThvc
- * EXTwfe
- * EXTwfi
- * EXTmmioU
- * EXTmmioK
- * EXTfp
- * EXTirq
- * EXTsys64
- * EXTmabt
- * EXTsum
- * S
- * P
- * %ST
- * %GUE
- * %HYP
-```
-
-All monitoring items are displayed by default. You can press the up or down key to select a monitoring item, press the space key to set whether to display or hide the monitoring item, and press the q key to exit.
-After %ST, %GUE, and %HYP are hidden, the following information is displayed:
-
-```sh
-vmtop - 2020-09-14 10:23:25 - 1.0
-Domains: 1 running
-
- DID VM/task-name PID %CPU EXThvc EXTwfe EXTwfi EXTmmioU EXTmmioK EXTfp EXTirq EXTsys64 EXTmabt EXTsum S P
- 2 example 4054916 12.0 0 0 1213 14 1 144 68 168 0 1464 S 125
- |_ qemu-kvm 4054916 0.0 0 0 0 0 0 0 0 0 0 0 S 125
- |_ qemu-kvm 4054928 0.0 0 0 0 0 0 0 0 0 0 0 S 119
- |_ signalfd_com 4054929 0.0 0 0 0 0 0 0 0 0 0 0 S 120
- |_ IO mon_iothr 4054932 0.0 0 0 0 0 0 0 0 0 0 0 S 117
- |_ CPU 0/KVM 4054933 2.0 0 0 303 6 0 29 10 35 0 354 S 98
- |_ CPU 1/KVM 4054934 4.0 0 0 279 0 0 39 17 49 0 345 S 1
- |_ CPU 2/KVM 4054935 3.0 0 0 283 0 0 33 20 40 0 343 S 122
- |_ CPU 3/KVM 4054936 3.0 0 0 348 8 1 43 21 44 0 422 S 110
- |_ memory_lock 4054940 0.0 0 0 0 0 0 0 0 0 0 0 S 126
- |_ vnc_worker 4054944 0.0 0 0 0 0 0 0 0 0 0 0 S 118
- |_ worker 1794 0.0 0 0 0 0 0 0 0 0 0 0 S 126
-```
-
-%ST, %GUE, and %HYP will not be displayed on the screen.
+To help users better use virtualization, openEuler provides a set of tools, including vmtop and LibcarePlus. This section describes how to install and use these tools.
\ No newline at end of file
diff --git a/docs/en/docs/Virtualization/vmtop.md b/docs/en/docs/Virtualization/vmtop.md
new file mode 100644
index 000000000..346cc01c2
--- /dev/null
+++ b/docs/en/docs/Virtualization/vmtop.md
@@ -0,0 +1,196 @@
+# Tool Guide
+
+- [vmtop](#vmtop)
+
+## vmtop
+
+### Overview
+
+vmtop is a user-mode tool running on the host machine. You can use the vmtop tool to dynamically view the usage of VM resources in real time, such as CPU usage, memory usage, and the number of vCPU traps. Therefore, the vmtop tool can be used to locate virtualization problems and optimize performance.
+
+#### Multi-Architecture Support
+
+Currently, the vmtop supports the AArch64 and x86_64 processor architectures.
+
+#### Display Item Description
+
+The vmtop display items vary according to the processor architecture. This document describes the meaning of each display item and whether it is displayed in the corresponding architecture.
+Note: The following sampling difference refers to the difference between two times of data obtained in a specified interval.
+
+##### **Display Items of the AArch64 and x86_64 Architectures**
+
+- VM/task-name: VM/Process name
+- DID: VM ID
+- PID: PID of the qemu process of the VM
+- %CPU: CPU usage of a process
+- EXTsum: Total number of KVM exits (sampling difference)
+- S: Process status
+- P: ID of the physical CPU occupied by a process
+- %ST: Ratio of the preemption time to the CPU running time
+- %GUE: Ratio of the VM internal occupation time to the CPU running time
+- %HYP: Virtualization overhead ratio
+
+##### Display Items Only for the Aarch64 Architecture
+
+- EXThvc: Number of hvc-exits (sampling difference)
+- EXTwfe: Number of wfe-exits (sampling difference)
+- EXTwfi: Number of wfi-exits (sampling difference)
+- EXTmmioU: Number of mmioU-exits (sampling difference)
+- EXTmmioK: Number of mmioK-exits (sampling difference)
+- EXTfp: Number of fp-exits (sampling difference)
+- EXTirq: Number of irq-exits (sampling difference)
+- EXTsys64: Number of sys64 exits (sampling difference)
+- EXTmabt: Number of mem abort exits (sampling difference)
+
+##### Display Items Only for the x86_64 Architecture
+
+- PFfix: Number of page faults (sampling difference)
+- PFgu: Number of times that page faults are injected to the guest OS (sampling difference)
+- INvlpg: Number of times that a TLB item is flushed (one of the TLB items, which is not fixed)
+- EXTio: Number of io VM-exit times (sampling difference)
+- EXTmmio: Number of mmio VM-exit times (sampling difference)
+- EXThalt: Number of halt VM-exit times (sampling difference)
+- EXTsig: Number of VM-exits caused by signal processing (sampling difference)
+- EXTirq: Number of VM-exits caused by interrupts (sampling difference)
+- EXTnmiW: Number of VM-exit times caused by non-maskable interrupts (sampling difference)
+- EXTirqW: Interruptwindow mechanism. When the interrupt function is enabled, exit is used to inject interrupts (sampling difference)
+- IrqIn: Number of times that IRQ interrupts are injected (sampling difference)
+- NmiIn: Number of times that NMI interrupts are injected (sampling difference)
+- TLBfl: Number of times that the entire TLB is flushed (sampling difference)
+- HostReL: Number of times that the host status is overloaded (sampling difference)
+- Hyperv: Number of times that the guest OS is simulated to call hypercall in virtualization-assistant mode (sampling difference)
+- EXTcr: Number of times that the access to the CR register exits (sampling difference)
+- EXTrmsr: Number of times that the read MSR exits (sampling difference)
+- EXTwmsr: Number of times that the write MSR exits (sampling difference)
+- EXTapic: Number of APIC write times (sampling difference)
+- EXTeptv: Ept page fault exit times (sampling difference)
+- EXTeptm: Number of Ept error exits (sampling difference)
+- EXTpau: Number of times that the VCPU pauses and exits (sampling difference)
+
+### Usage
+
+vmtop is a command line tool. You can directly run the vmtop in command line mode.
+In addition, the vmtop tool provides different options for querying different information.
+
+#### Syntax
+
+```sh
+vmtop [option]
+```
+
+#### Option Description
+
+- -d: sets the refresh interval, in seconds.
+- -H: displays the VM thread information.
+- -n: sets the number of refresh times and exits after the refresh is complete.
+- -b: displays Batch mode, which can be used to redirect to a file.
+- -h: displays help information.
+- -v: displays versions.
+- -p: monitors the VM with a specified ID.
+
+#### Keyboard Shortcut
+
+Shortcut key used when the vmtop is running.
+
+- H: displays or stops the VM thread information. The information is displayed by default.
+- up/down: moves the VM list upwards or downwards.
+- left/right: moves the cursor leftwards or rightwards to display the columns that are hidden due to the screen width.
+- f: enters the editing mode of a monitoring item and selects the monitoring item to be enabled.
+- q: exits the vmtop process.
+
+### Example
+
+Run the vmtop command on the host.
+
+```sh
+vmtop
+```
+
+The command output is as follows:
+
+```sh
+vmtop - 2020-09-14 09:54:48 - 1.0
+Domains: 1 running
+
+ DID VM/task-name PID %CPU EXThvc EXTwfe EXTwfi EXTmmioU EXTmmioK EXTfp EXTirq EXTsys64 EXTmabt EXTsum S P %ST %GUE %HYP
+ 2 example 4054916 13.0 0 0 1206 10 0 144 62 174 0 1452 S 106 0.0 99.7 16.0
+```
+
+As shown in the output, there is only one VM named "example" on the host. The ID is 2. The CPU usage is 13.0%. The total number of traps within one second is 1452. The physical CPU occupied by the VM process is CPU 106. The ratio of the VM internal occupation time to the CPU running time is 99.7%.
+
+1. Display VM thread information.
+Press H to display the thread information.
+
+```sh
+vmtop - 2020-09-14 10:11:27 - 1.0
+Domains: 1 running
+
+ DID VM/task-name PID %CPU EXThvc EXTwfe EXTwfi EXTmmioU EXTmmioK EXTfp EXTirq EXTsys64 EXTmabt EXTsum S P %ST %GUE %HYP
+ 2 example 4054916 13.0 0 0 1191 17 4 120 76 147 0 1435 S 119 0.0 123.7 4.0
+ |_ qemu-kvm 4054916 0.0 0 0 0 0 0 0 0 0 0 0 S 119 0.0 0.0 0.0
+ |_ qemu-kvm 4054928 0.0 0 0 0 0 0 0 0 0 0 0 S 119 0.0 0.0 0.0
+ |_ signalfd_com 4054929 0.0 0 0 0 0 0 0 0 0 0 0 S 120 0.0 0.0 0.0
+ |_ IO mon_iothr 4054932 0.0 0 0 0 0 0 0 0 0 0 0 S 117 0.0 0.0 0.0
+ |_ CPU 0/KVM 4054933 3.0 0 0 280 6 4 28 19 41 0 350 S 105 0.0 27.9 0.0
+ |_ CPU 1/KVM 4054934 3.0 0 0 260 0 0 16 12 36 0 308 S 31 0.0 20.0 0.0
+ |_ CPU 2/KVM 4054935 3.0 0 0 341 0 0 44 20 26 0 387 R 108 0.0 27.9 4.0
+ |_ CPU 3/KVM 4054936 5.0 0 0 310 11 0 32 25 44 0 390 S 103 0.0 47.9 0.0
+ |_ memory_lock 4054940 0.0 0 0 0 0 0 0 0 0 0 0 S 126 0.0 0.0 0.0
+ |_ vnc_worker 4054944 0.0 0 0 0 0 0 0 0 0 0 0 S 118 0.0 0.0 0.0
+ |_ worker 4143738 0.0 0 0 0 0 0 0 0 0 0 0 S 120 0.0 0.0 0.0
+```
+
+The example VM has 11 threads, including the vCPU thread, vnc_worker, and IO mon_iotreads. Each thread also displays detailed CPU usage and trap information.
+
+2. Select the monitoring item.
+Enter f to edit the monitoring item.
+
+```sh
+field filter - select which field to be showed
+Use up/down to navigate, use space to set whether chosen filed to be showed
+'q' to quit to normal display
+
+ * DID
+ * VM/task-name
+ * PID
+ * %CPU
+ * EXThvc
+ * EXTwfe
+ * EXTwfi
+ * EXTmmioU
+ * EXTmmioK
+ * EXTfp
+ * EXTirq
+ * EXTsys64
+ * EXTmabt
+ * EXTsum
+ * S
+ * P
+ * %ST
+ * %GUE
+ * %HYP
+```
+
+All monitoring items are displayed by default. You can press the up or down key to select a monitoring item, press the space key to set whether to display or hide the monitoring item, and press the q key to exit.
+After %ST, %GUE, and %HYP are hidden, the following information is displayed:
+
+```sh
+vmtop - 2020-09-14 10:23:25 - 1.0
+Domains: 1 running
+
+ DID VM/task-name PID %CPU EXThvc EXTwfe EXTwfi EXTmmioU EXTmmioK EXTfp EXTirq EXTsys64 EXTmabt EXTsum S P
+ 2 example 4054916 12.0 0 0 1213 14 1 144 68 168 0 1464 S 125
+ |_ qemu-kvm 4054916 0.0 0 0 0 0 0 0 0 0 0 0 S 125
+ |_ qemu-kvm 4054928 0.0 0 0 0 0 0 0 0 0 0 0 S 119
+ |_ signalfd_com 4054929 0.0 0 0 0 0 0 0 0 0 0 0 S 120
+ |_ IO mon_iothr 4054932 0.0 0 0 0 0 0 0 0 0 0 0 S 117
+ |_ CPU 0/KVM 4054933 2.0 0 0 303 6 0 29 10 35 0 354 S 98
+ |_ CPU 1/KVM 4054934 4.0 0 0 279 0 0 39 17 49 0 345 S 1
+ |_ CPU 2/KVM 4054935 3.0 0 0 283 0 0 33 20 40 0 343 S 122
+ |_ CPU 3/KVM 4054936 3.0 0 0 348 8 1 43 21 44 0 422 S 110
+ |_ memory_lock 4054940 0.0 0 0 0 0 0 0 0 0 0 0 S 126
+ |_ vnc_worker 4054944 0.0 0 0 0 0 0 0 0 0 0 0 S 118
+ |_ worker 1794 0.0 0 0 0 0 0 0 0 0 0 0 S 126
+```
+
+%ST, %GUE, and %HYP will not be displayed on the screen.
diff --git a/docs/en/docs/secGear/api-description.md b/docs/en/docs/secGear/api-description.md
index 6e48a8c83..ec94310aa 100644
--- a/docs/en/docs/secGear/api-description.md
+++ b/docs/en/docs/secGear/api-description.md
@@ -10,6 +10,9 @@ Creates an enclave API.
Initialization API. The function calls different TEE creation functions based on the type to initialize the enclave context in different TEE solutions. This API is called by the REE.
+> **说明:**
+> Due to Intel SGX restrictions, memory mapping contention exists when multiple thread invoke cc_enclave_create concurrently. As a result, the creation of the enclave API may fail. Avoid concurrent invocations of cc_enclave_create in your code.
+
**Function Declarations:**
cc_enclave_result_t cc_enclave_create(const char* path, enclave_type_t type, uint32_t version,uint32_t flags,const enclave_features_t* features,uint32_t features_count,
diff --git a/docs/en/menu/index.md b/docs/en/menu/index.md
index 16cd18d03..0aaaacf6d 100644
--- a/docs/en/menu/index.md
+++ b/docs/en/menu/index.md
@@ -67,6 +67,8 @@ headless: true
- [VM Maintainability Management]({{< relref "./docs/Virtualization/vm-maintainability-management.md" >}})
- [Best Practices]({{< relref "./docs/Virtualization/best-practices.md" >}})
- [Tool Guide]({{< relref "./docs/Virtualization/tool-guide.md" >}})
+ - [vmtop]({{< relref "./docs/Virtualization/vmtop.md" >}})
+ - [LibcarePlus]({{< relref "./docs/Virtualization/LibcarePlus.md" >}})
- [Appendix]({{< relref "./docs/Virtualization/appendix.md" >}})
- [StratoVirt Virtualization User Guide]({{< relref "./docs/StratoVirt/StratoVrit_guidence.md" >}})
- [Introduction to StratoVirt]({{< relref "./docs/StratoVirt/StratoVirt_intoduction.md" >}})
--
Gitee
From 91b84794931e2cd36d097bf6f7070e69bfff93dc Mon Sep 17 00:00:00 2001
From: hwyytw
Date: Thu, 24 Mar 2022 17:51:12 +0800
Subject: [PATCH 04/42] =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=9E=84=E5=BB=BA?=
=?UTF-8?q?=E6=8C=87=E5=AF=BC=E6=96=87=E6=A1=A3=EF=BC=8C=E5=88=B7=E6=96=B0?=
=?UTF-8?q?=E5=BA=94=E7=94=A8=E5=BC=80=E5=8F=91=E6=96=87=E6=A1=A3=EF=BC=8C?=
=?UTF-8?q?=E5=88=B7=E6=96=B0=E7=B4=A2=E5=BC=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: hwyytw
---
...24\347\224\250\345\274\200\345\217\221.md" | 100 ++++++++++++
...\273\272\346\214\207\345\257\274.markdown" | 152 ++++++++++++++++++
...\273\272\346\214\207\345\257\274.markdown" | 143 ++++++++++++++++
.../public_sys-resources/hosttools.png | Bin 0 -> 175700 bytes
...77\347\224\250\346\226\271\346\263\225.md" | 45 ------
...05\344\270\216\350\277\220\350\241\214.md" | 49 ++++--
...\273\272\346\214\207\345\257\274.markdown" | 4 +
docs/zh/menu/index.md | 5 +-
8 files changed, 436 insertions(+), 62 deletions(-)
create mode 100644 "docs/zh/docs/Embedded/SDK\345\272\224\347\224\250\345\274\200\345\217\221.md"
create mode 100644 "docs/zh/docs/Embedded/openEuler Embedded\345\256\271\345\231\250\346\236\204\345\273\272\346\214\207\345\257\274.markdown"
create mode 100644 "docs/zh/docs/Embedded/openEuler Embedded\346\236\204\345\273\272\346\214\207\345\257\274.markdown"
create mode 100644 docs/zh/docs/Embedded/public_sys-resources/hosttools.png
delete mode 100644 "docs/zh/docs/Embedded/\344\275\277\347\224\250\346\226\271\346\263\225.md"
create mode 100644 "docs/zh/docs/Embedded/\346\236\204\345\273\272\346\214\207\345\257\274.markdown"
diff --git "a/docs/zh/docs/Embedded/SDK\345\272\224\347\224\250\345\274\200\345\217\221.md" "b/docs/zh/docs/Embedded/SDK\345\272\224\347\224\250\345\274\200\345\217\221.md"
new file mode 100644
index 000000000..283757eed
--- /dev/null
+++ "b/docs/zh/docs/Embedded/SDK\345\272\224\347\224\250\345\274\200\345\217\221.md"
@@ -0,0 +1,100 @@
+# 基于openEuler Embedded的SDK应用开发
+
+当前发布的镜像除了体验openEuler Embedded的基本功能外,还可以进行基本的应用开发,也即在openEuler Embedded上运行用户自己的程序。本章主要介绍如何基于openEuler Embedded的SDK进行应用开发。
+
+
+
+- [安装SDK](#安装SDK)
+- [使用SDK编译](#使用SDK编译)
+
+
+### 安装SDK
+
+1. **执行SDK自解压安装脚本**
+
+运行如下命令:
+
+``` {.sourceCode .console}
+sh openeuler-glibc-x86_64-openeuler-image-aarch64-qemu-aarch64-toolchain-22.03.sh
+```
+
+根据提示输入工具链的安装路径,默认路径是/opt/openeuler/\/;若不设置,则按默认路径安装;也可以配置相对路径或绝对路径。
+
+举例如下:
+
+```
+sh ./openeuler-glibc-x86_64-openeuler-image-armv7a-qemu-arm-toolchain-22.03.sh``
+openEuler embedded(openEuler Embedded Reference Distro) SDK installer version 22.03
+================================================================
+Enter target directory for SDK (default: /opt/openeuler/22.03): sdk
+You are about to install the SDK to "/usr1/openeuler/sdk". Proceed [Y/n]? y
+Extracting SDK...............................................done
+Setting it up...SDK has been successfully set up and is ready to be used.
+Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
+$ . /usr1/openeuler/sdk/environment-setup-armv7a-openeuler-linux-gnueabi
+```
+
+2. **设置SDK环境变量**
+
+运行source命令。上例中前一步执行结束最后已打印source命令,运行即可。
+
+``` {.sourceCode .console}
+. /usr1/openeuler/myfiles/sdk/environment-setup-armv7a-openeuler-linux-gnueabi
+```
+
+3. **查看是否安装成功**
+
+运行如下命令,查看是否安装成功、环境设置成功。
+
+``` {.sourceCode .console}
+arm-openeuler-linux-gnueabi-gcc -v
+```
+
+### 使用SDK编译
+
+下面以使用SDK编译hello world为样例。
+
+1. **准备代码**
+
+以构建一个hello world程序为例,运行在openEuler Embedded根文件系统镜像中。
+
+创建一个hello.c文件,源码如下:
+
+``` c
+#include
+
+int main(void)
+{
+ printf("hello world\n");
+}
+```
+
+编写CMakelist.txt,和hello.c文件放在同一个目录。
+
+```
+project(hello C)
+
+add_executable(hello hello.c)
+```
+
+2. **编译生成二进制**
+
+进入hello.c文件所在目录,使用工具链编译,命令如下:
+
+``` {.sourceCode .console}
+cmake ..
+make
+```
+
+把编译好的hello程序拷贝到openEuler Embedded系统的/tmp/某个目录下(例如/tmp/myfiles/)。如何拷贝可以参考前文所述使能共享文件系统场景。
+
+3. **运行用户态程序**
+
+在openEuler Embedded系统中运行hello程序。
+
+``` {.sourceCode .console}
+cd /tmp/myfiles/
+./hello
+```
+
+如运行成功,则会输出\"hello world\"。
\ No newline at end of file
diff --git "a/docs/zh/docs/Embedded/openEuler Embedded\345\256\271\345\231\250\346\236\204\345\273\272\346\214\207\345\257\274.markdown" "b/docs/zh/docs/Embedded/openEuler Embedded\345\256\271\345\231\250\346\236\204\345\273\272\346\214\207\345\257\274.markdown"
new file mode 100644
index 000000000..2074cf578
--- /dev/null
+++ "b/docs/zh/docs/Embedded/openEuler Embedded\345\256\271\345\231\250\346\236\204\345\273\272\346\214\207\345\257\274.markdown"
@@ -0,0 +1,152 @@
+openEuler Embedded容器构建指导
+==============================
+
+由于openEuler Embedded构建过程需要基于openEuler操作系统,且需要安装较多系统工具和构建工具。为方便开发人员快速搭建构建环境,我们将构建过程所依赖的操作系统和工具封装到一个容器中,这就使得开发人员可以快速搭建一个构建环境,进而投入到代码开发中去,避免在准备环境阶段消耗大量时间。
+
+
+
+- [环境准备](#环境准备)
+ - [安装docker](#安装docker)
+ - [获取容器镜像](#获取容器镜像)
+ - [准备容器构建环境](#准备容器构建环境)
+- [openEuler Embedded版本构建](#openEuler Embedded版本构建)
+ - [下载源码](#下载源码)
+ - [编译构建](#编译构建)
+ - [构建结果说明](#构建结果说明)
+
+
+## 环境准备
+
+需要使用docker创建容器环境,为了确保docker成功安装,需满足以下软件硬件要求:
+
+- 操作系统: 推荐使用Ubuntu、Debian和RHEL(Centos、Fedora等)
+- 内核: 推荐3.8及以上的内核
+- 驱动: 内核必须支持一种合适的存储驱动,例如: Device Mapper、AUFS、vfs、btrfs、ZFS
+- 架构: 运行64位架构的计算机(x86\_64和amd64)
+
+### 安装docker
+
+-------------
+
+1. 检查当前环境是否已安装docker工具
+
+运行如下命令,可以看到当前docker版本信息,则说明当前环境已安装docker,无需再次安装。
+
+``` {.sourceCode .console}
+docker version
+```
+
+2. 如果没有安装,可参考官方链接安装
+
+官网地址: ,openEuler环境可参考Centos安装Docker。
+
+例如openEuler环境docker安装命令如下:
+
+```
+sudo yum install docker
+```
+
+### 获取容器镜像
+
+---------------
+
+通过docker pull命令拉取华为云中的镜像到宿主机。命令如下:
+
+```
+docker pull swr.cn-north-4.myhuaweicloud.com/openeuler-embedded/openeuler-container:lastest
+```
+
+### 准备容器构建环境
+
+-------------------
+
+#### 1.启动容器
+
+可通过docker run命令启动容器,为了保证容器启动后可以在后台运行,且可以正常访问网络,建议使用如下命令启动:
+
+```
+docker run -idt --network host swr.cn-north-4.myhuaweicloud.com/openeuler-embedded/openeuler-container:lastest bash
+```
+
+参数说明:
+
+- -i 让容器的标准输入保持打开
+- -d 让 Docker 容器在后台以守护态(Daemonized)形式运行
+- -t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上
+- \--network 将容器连接到(host)网络
+- swr.cn-north-4.myhuaweicloud.com/openeuler-embedded/openeuler-container:lastest
+ (镜像名称:镜像版本)
+- bash 进入容器的方式
+
+#### 2.查看已启动的容器id
+
+```
+docker ps
+```
+
+#### 3.进入容器
+
+```
+docker exec -it 容器id bash
+```
+
+构建环境已准备完成,下面就可以在容器中进行构建了。
+
+## openEuler Embedded版本构建
+
+### 下载源码
+
+1. 获取源码下载脚本
+
+```
+git clone https://gitee.com/openeuler/yocto-meta-openeuler.git -b openEuler-22.03-LTS -v /usr1/openeuler/src/yocto-meta-openeuler
+```
+
+2. 通过脚本下载源码
+
+```
+cd /usr1/openeuler/src/yocto-meta-openeuler/scripts
+sh download_code.sh /usr1/openeuler/src
+```
+
+### 编译构建
+
+- 编译架构: aarch64-std、aarch64-pro、arm-std、raspberrypi4-64
+- 构建目录: /usr1/build
+- 源码目录: /usr1/openeuler/src
+- 编译器所在路径: /usr1/openeuler/gcc/openeuler\_gcc\_arm64le
+
+> **说明:**
+>- 不同的编译架构使用不同的编译器,aarch64-std、aarch64-pro、raspberrypi4-64使用openeuler\_gcc\_arm64le编译器,arm-std使用openeuler\_gcc\_arm32le编译器。
+>- 下面以以aarch64-std目标架构编译为例。
+
+1. 将/usr1目录所属群组改为openeuler,否则切换至openeuler用户构建会存在权限问题。
+
+```
+chown -R openeuler:users /usr1
+```
+
+2. 切换至openeuler用户。
+
+```
+su openeuler
+```
+
+3. 进入构建脚本所在路径,运行编译脚本。
+
+```
+cd /usr1/openeuler/src/yocto-meta-openeuler/scripts
+source compile.sh aarch64-std /usr1/build /usr1/openeuler/gcc/openeuler_gcc_arm64le
+bitbake openeuler-image
+```
+
+### 构建结果说明
+
+结果件默认生成在构建目录下的output目录下,例如上面aarch64-std的构建结果件生成在/usr1/build/output目录下,如下表:
+
+| filename | description |
+| --------------------------------------------------------- | ----------------------------------- |
+| Image-5.10.0 | openEuler Embedded image |
+| openeuler-glibc-x86\_64-openeuler-image-*-toolchain-**.sh | openEuler Embedded sdk toolchain |
+| openeuler-image-qemu-aarch64-*.rootfs.cpio.gz | openEuler Embedded file system |
+| zImage | openEuler Embedded compressed image |
\ No newline at end of file
diff --git "a/docs/zh/docs/Embedded/openEuler Embedded\346\236\204\345\273\272\346\214\207\345\257\274.markdown" "b/docs/zh/docs/Embedded/openEuler Embedded\346\236\204\345\273\272\346\214\207\345\257\274.markdown"
new file mode 100644
index 000000000..fc4974d26
--- /dev/null
+++ "b/docs/zh/docs/Embedded/openEuler Embedded\346\236\204\345\273\272\346\214\207\345\257\274.markdown"
@@ -0,0 +1,143 @@
+openEuler Embedded构建指导
+=====================
+
+本章主要介绍如何构建openEuler Embedded。
+
+
+
+- [环境准备](#环境准备)
+ - [Yocto中主机端命令使用](#Yocto中主机端命令使用)
+ - [openEuler Embedded所需构建工具](#openEuler Embedded所需构建工具)
+ - [已安装好工具的构建容器](#已安装好工具的构建容器)
+- [openEuler Embedded版本构建](#openEuler Embedded版本构建)
+ - [构建代码下载](#构建代码下载)
+ - [编译构建](#编译构建)
+ - [构建结果说明](#构建结果说明)
+
+
+环境准备
+--------------
+
+### Yocto中主机端命令使用
+
+Yocto或者说Bitbake本质上是一组python程序,其最小运行环境要求如下:
+
+- Python3 \> 3.6.0
+- Git \> 1.8.3.1
+- Tar \> 1.28
+
+在构建过程中所需要的其他工具,Yocto都可以根据相应的软件包配方自行构建出来,从而达到自包含的效果。在这个过程中,Yocto还会依据自身需要,对相应的工具打上yocto专属补丁(如dnf,rpm等)。这些主机工具会在第一次的构建中从源码开始构建,因此Yocto第一次构建比较费时。
+
+为了加速构建特别是第一次构建,openEuler Embedded采取了"能用原生工具就用原生工具,能不构建就不构建"的策略,尽可能使用主机上预编译的原生的工具。这就需要依赖主机上软件包管理工具(apt, dnf, yum, zypper等)实现安装好。
+
+Yocto是通过HOSTTOOLS变量来实现主机工具的引入,为会每个在HOSTTOOLS中列出的工具建立相应的软链接。为了避免来自主机对构建环境的污染,Yocto会重新准备不同于主机的环境,例如PATH变量等,因此如果新增依赖主机上的某个命令,需显示在Yocto的HOSTTOOLS变量中增加,否则即使主机上存在,Yocto构建时也会报错找不到相应的工具。相应流程如下图所示:
+
+
+
+当前openEuler Embedded所需要主机工具已经默认在local.conf.sample中的HOSTTOOLS定义,主要工具描述如下:
+
+| 工具名 | 用途 |
+| ------ | ------------- |
+| cmake | cmake构建工具 |
+| ninjia | ninja构建系统 |
+
+### openEuler Embedded所需构建工具
+
+- 构建OS
+
+ [操作系统:openEuler-20.03-LTS-SP2](https://repo.openeuler.org/openEuler-20.03-LTS-SP2/docker_img/x86_64/openEuler-docker.x86_64.tar.xz)
+
+- 安装系统额外工具
+
+```
+yum -y install tar cmake gperf sqlite-devel chrpath gcc-c++ patch rpm-build flex autoconf automake m4 bison bc libtool gettext-devel createrepo\_c rpcgen texinfo hostname python meson dosfstools mtools parted ninja-build autoconf-archive libmpc-devel gmp-devel
+```
+
+- 预编译的交叉工具链和库
+
+ Yocto可以构建出交叉编译所需的交叉工具链和C库,但整个流程复杂且耗时,不亚于内核乃至镜像的构建,而且除了第一次构建,后面很少会再涉及。同时,绝大部分开发者都不会直接与工具链和C库构建打交道。所以为了简化该流程,openEuler Embedded采取的策略是采用预编译的交叉工具链和库,会专门维护和发布相应的带有C库的工具链。
+
+ 目前我们提供了对arm32位和aarch64位两种架构的工具链支持,通过下方链接可以获得:
+
+ - [ARM 32位工具链](https://gitee.com/openeuler/yocto-embedded-tools/attach_files/1003463/download/openeuler_gcc_arm32le.tar.xz)
+ - [ARM64位工具链](https://gitee.com/openeuler/yocto-embedded-tools/attach_files/1003462/download/openeuler_gcc_arm64le.tar.xz)
+
+### 已安装好工具的构建容器
+
+openEuler Embedded的构建过程中会使用到大量的各式各样的主机工具。如前文所述,为了加速构建,openEuler Embedded依赖主机事先安装好相应的工具,但这也会带来一不同主机环境会有不同的工具版本的问题,例如构建需要cmake高于1.9版本,但主机上最高只有cmake 1.8。为了解决这一问题,openEuler Embedded提供了专门的构建容器,提供统一的构建环境。
+
+使用者可以通过如下链接获得容器镜像直接用于编译:
+
+ [openEuler Embedded构建容器的基础镜像](https://repo.openeuler.org/openEuler-21.03/docker_img/x86_64/openEuler-docker.x86_64.tar.xz)
+
+具体构建指导请参考[openEuler Embedded容器构建指导](https://docs.openeuler.org/zh/22.03_LTS/docs/Embedded/openEuler Embedded容器构建指导.html)。
+
+## openEuler Embedded版本构建
+
+### 构建代码下载
+
+openEuler Embedded整个构建工程的文件布局如下,假设openeuler\_embedded为顶层目录:
+
+><顶层目录openeuler_embedded>
+>├── src 源代码目录,包含所有软件包代码、内核代码和Yocto构建代码
+>├── build openEuler Embedded的构建目录,生成的各种镜像放在此目录下
+
+1. 获取源码下载脚本
+
+ 将脚本下载到指定目录,例如下载到src/yocto-meta-openeuler目录下:
+
+ ```
+ git clone https://gitee.com/openeuler/yocto-meta-openeuler.git -b openEuler-22.03-LTS -v src/yocto-meta-openeuler
+ ```
+
+ 脚本为src/yocto-meta-openeuler/scripts/download\_code.sh,此脚本有3个参数:
+
+ - 参数1:下载的源码路径,默认相对脚本位置下载,例如前面样例,代码仓会下到src/下
+ - 参数2:下载的分支,默认值见脚本,不同分支按版本确定
+ - 参数3:下代码的xml文件,标准manifest格式,按xml配置下代码
+
+2. 通过脚本下载源码
+
+ - 下载最新代码:
+
+ ```
+ sh src/yocto-meta-openeuler/scripts/download_code.sh
+ ```
+
+ - 下载指定版本代码:
+
+ ```
+ sh src/yocto-meta-openeuler/scripts/download_code.sh "" "" "manifest.xml"
+ ```
+
+ 指定openEuler Embedded版本的代码的manifest.xml文件从openEuler Embedded发布件目录embedded\_img/source-list/下获取。
+
+### 编译构建
+
+一键式构建脚本:src/yocto-meta-openeuler/scripts/compile.sh, 具体细节可以参考该脚本。
+
+编译脚本的主要流程说明:
+
+1. 设置PATH增加额外工具路径
+2. TEMPLATECONF指定local.conf.sample等配置文件路径
+3. 调用poky仓的oe-init-build-env进行初始化配置
+4. 在编译目录的conf/local.conf中配置MACHINE,按需增加额外新增的层
+5. 在编译目录执行bitbake openeuler-image编译openEuler
+ Embedded的image和sdk
+6. 执行完发布件在编译目录的output目录下
+
+运行编译脚本,以编译标准arm架构为例,编译方法如下:
+
+ source src/yocto-meta-openeuler/scripts/compile.sh arm-std
+ bitbake openeuler-image #执行第一条source后,会提示出bitbake命令
+
+### 构建结果说明
+
+结果件默认生成在构建目录下的output目录下,例如上面arm的构建结果件生成在/usr1/build/output目录下,如下表:
+
+| filename | description |
+| --------------------------------------------------------- | ----------------------------------- |
+| Image-5.10.0 | openEuler Embedded image |
+| openeuler-glibc-x86\_64-openeuler-image-*-toolchain-**.sh | openEuler Embedded sdk toolchain |
+| openeuler-image-qemu-aarch64-*.rootfs.cpio.gz | openEuler Embedded file system |
+| zImage | openEuler Embedded compressed image |
\ No newline at end of file
diff --git a/docs/zh/docs/Embedded/public_sys-resources/hosttools.png b/docs/zh/docs/Embedded/public_sys-resources/hosttools.png
new file mode 100644
index 0000000000000000000000000000000000000000..83bb076a7763d522dde36168b1f713e524141531
GIT binary patch
literal 175700
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 |