Skip to content

antony@notes:~/misc$ cat "Unshare-program.md"

Unshare program

2022-08-14· misc ·系統工程

Unshare program

uc.sh

#!/bin/bash

# run daemon
bash /home/bigred/suc.sh &

# var
alp_url="http://dl-cdn.alpinelinux.org/alpine/v3.16/releases/x86_64/alpine-minirootfs-3.16.1-x86_64.tar.gz"
CGROUP="/sys/fs/cgroup"

# 建立 rootfs 目錄
if [ ! -d "~/rootfs" ]; then
  mkdir -p ~/rootfs && echo -e "\nrootfs dir 建立成功 !"
else
  echo -e "\nrootfs dir 已存在!"
fi

# 下載和解壓縮 Alpine linux 最小的檔案系統
if [ ! -f ~/rootfs/alpine.tar.gz ]; then
  cd ~/rootfs; curl -s -o alpine.tar.gz ${alp_url}
  [ -f ~/rootfs/alpine.tar.gz ] && tar xvf alpine.tar.gz &>/dev/null && rm alpine.tar.gz; cd ..
  [ -d ~/rootfs/bin/ ] && sudo chown -R root:root ~/rootfs && echo "Alpine 最小的檔案系統已下載和解壓縮完畢 !"
else
  cd ~
  [ -d ~/rootfs/bin/ ] && sudo chown -R root:root ~/rootfs && echo "Alpine 最小的檔案系統已存在!!"
fi

# 建立 Overlay2 檔案系統所需的目錄
if [ ! -d ~/ov22 ]; then
  cd ~;mkdir -p ~/ov22/{upper,lower,merged,work}
  [ "$?" == "0" ] && sudo chown -R root:root ~/ov22/
  [ "$?" == "0" ] && echo "Overlay2 檔案系統所需的目錄建立成功!"
else
  echo "Overlay2 檔案系統所需的目錄已存在 !"
fi

# 掛載 Overlay2
if ! mount | grep -w "^overlay" &>/dev/null; then
  sudo mount -t overlay overlay -o lowerdir=${HOME}/ov22/lower:${HOME}/rootfs,upperdir=${HOME}/ov22/upper,workdir=${HOME}/ov22/work  ${HOME}/ov22/merged
  [ "$?" == "0" ] && echo "掛載 Overlay2 成功 !"
else
  echo "Overlay2 已存在 !"
fi

# mount 零號裝置
if ! mount | grep 'devtmpfs on ${HOME}/ov22/merged/dev' &>/dev/null; then
  sudo mount --bind -o ro  /dev  ${HOME}/ov22/merged/dev
  [ "$?" == "0" ] && echo "零號裝置安裝成功!"
else
  echo "零號裝置已存在!"
fi

# 在 /sys/fs/cgroup/memory/ 目錄下建立 demo2 目錄
if [ ! -d ${CGROUP}/memory/demo2 ]; then
  sudo mkdir ${CGROUP}/memory/demo2
  [ "$?" == "0" ] && echo "${CGROUP}/memory/demo2 建立成功!"
else
  echo "${CGROUP}/memory/demo2 已存在"
fi


# 關閉記憶體不夠自動拿硬碟來使用的功能
if echo "0" | sudo tee ${CGROUP}/memory/demo2/memory.swappiness &>/dev/null; then
  echo "memory.swappiness 已關閉 !"
else
  echo "memory.swappiness 異常 !" && exit 1
fi

# 限制記憶體大小 ,Default : 1 G
meml="1073741824"
if echo "$meml" | sudo tee ${CGROUP}/memory/demo2/memory.limit_in_bytes &>/dev/null; then
  echo "限制記憶體大小 ${meml} !"
else
  echo "記憶體限制 ${mem1} 失敗!" && exit 1
fi


# 建立和設定 cpuset 控制子群組 - first
if [ ! -d ${CGROUP}/cpuset/first ]; then
  sudo mkdir ${CGROUP}/cpuset/first
  [ "$?" == "0" ] && sudo chown bigred:root -R ${CGROUP}/cpuset/first
  [ "$?" == "0" ] && echo "${CGROUP}/cpuset/first 建立和設定成功!"
else
  echo "${CGROUP}/cpuset/first 已存在!"
fi

# 關閉 CPU 直接存取記憶體的功能
if echo "0" | sudo tee ${CGROUP}/cpuset/first/cpuset.mems &>/dev/null; then
  echo "已關閉 CPU 直接存取記憶體的功能"
else
  echo "關閉 CPU 直接存取記憶體的功能 not ok , Error !!!" && exit 1
fi

# 以 root 來建立 low 控制子群組,low 繼承了 cpu controller 的所有屬性
cpulow="512"
if sudo mkdir ${CGROUP}/cpu/low &>/dev/null; then
  sudo chown bigred:root -R ${CGROUP}/cpu/low
  [ "$?" == "0" ] && echo "$cpulow" | sudo tee ${CGROUP}/cpu/low/cpu.shares &>/dev/null
  [ "$?" == "0" ] && echo "已將 low 控制子群組分配比率設成 $cpulow"
fi

# 建立 cpu 的 high 控制子群組
cpuhigh="2048"
if sudo mkdir ${CGROUP}/cpu/high &>/dev/null; then
  sudo chown bigred:root -R ${CGROUP}/cpu/high
  [ "$?" == "0" ] && echo "$cpuhigh" | sudo tee ${CGROUP}/cpu/high/cpu.shares &>/dev/null
  [ "$?" == "0" ] && echo "已將 high 控制子群組分配比率設成 $cpuhigh"
else
  echo "${CGROUP}/cpu/high existed !"
fi


# 檢視原本 cpuset 裡的設定:
core=$(cat ${CGROUP}/cpuset/cpuset.cpus | grep -e "0-1")
if [ "$core" == "0-1" ]; then
  echo "有二個 cpu core, 分別是 0 和 1"
else
  echo "請確認 cpu core : ${core}" && exit 1
fi


# 設定 first 控制子群組, 將 first 控制子群組設成第一個 cpu core
if echo 0 | sudo tee ${CGROUP}/cpuset/first/cpuset.cpus &>/dev/null; then
  echo "已成功將 first 控制子群組設成第一個 cpu core !"
else
  echo "設定 first 控制子群組設成第一個 cpu core,出現異常,Error !!!" && exit 1
fi

# 啟動 Namespace 的功能
echo ""; read -s -n1 -p "按任意鍵啟動 sh unshare 電腦"
clear; sudo unshare --pid --fork --mount-proc --net --uts -R ~/ov22/merged sh

suc.sh

#!/bin/bash

# var
shPID=$(pidof sh)

# daemon
until [ "$shPID" != "" ]
do
  shPID=$(pidof sh)
  sleep 1
done

sleep 5

# var
shNPID=$(sudo lsns -t net | fmt -u | tail -n 2 | head -n 1 | cut -d" " -f 1)

# 將 sh process 設定只能使用 1 G 的限制
if echo ${shPID} | sudo tee /sys/fs/cgroup/memory/demo2/tasks &>/dev/null; then
  echo "${shPID} process 受到記憶體 1G 的限制"
else
  echo "${shPID} process set memory error !"
fi

# 將 sh process 的 PID 加入到 first 控制子群組
if echo ${shPID} | sudo tee /sys/fs/cgroup/cpuset/first/tasks &>/dev/null; then
  echo "${shPID} process 只能使用 CPU Core 0 "
fi

# 新增 ve1 虛擬網路卡到 Default Namespace
# 新增 ve2 虛擬網路卡到 ${shNPID} 的 Network Namespace
# 以上這兩張網路卡會透過 ip link 用一條網路線連接起來
# veth ,Virtual Ethernet Device
# peer ,一組的意思
if ! ifconfig -a ve1 &>/dev/null; then
  sudo ip link add ve1 netns 1 type veth peer name ve2 netns ${shNPID}
  [ "$?" == "0" ] && echo -e "成功新增 ve1 虛擬網路卡到 Default Namespace \n成功新增 ve2 虛擬網路卡到 ${shNPID} 的 Network Namespace"
else
  echo "ve1 and ve2 existed !"
fi

# 將 ve1 這張網路卡啟動,因為內定網路卡沒有啟動
if ! ifconfig vel &>/dev/null; then
  sudo ip link set ve1 up && echo "ve1 網路卡啟動成功 !"
else
  echo "ve1 網路卡已啟動 !"
fi

# 設定 ve1 網路卡 IP 位址
if ! ip -4 addr | grep ve1 &>/dev/null; then
  sudo ip addr add 192.168.1.100/24 dev ve1 && echo "已設定 ve1 網路卡的 ip 位址為 : 192.168.1.100/24"
else
  echo "ve1 ip existed !" && exit 1
fi

PTY allocation request failed on channel 0

如果遇到 ssh 連線 PTY allocation request failed on channel 0 時 執行

$ umount /dev/pts

$ mount devpts /dev/pts -t devpts
tags: 系統工程