閒聊+雙系統另種選擇 loopdevice - Linux

By Harry
at 2017-07-13T07:58
at 2017-07-13T07:58
Table of Contents
本次一樣修改initrd.d/linuxrc
新增可OverlayFS boot
同樣是新增修改這三部份
: part1: 參數讀取
放在參數讀取的那區
: part2: 解析UUID=, LABEL=; mount and losetup.
放在 Determine root device 前
: part3: mount --move
放在switch_root 前
在grub.cfg內的用法,舉例三種:
1. 最初的版本 只用單一loopfile 啟動os
linux vmlinuz loops_dev=LABEL=loops loops_mnt=/loops \
loop_file=live.ext4 root=LABEL=live
2. 使用overlay boot, 但lower,upper,work都在同一可寫的目錄下
linux vmlinuz rootfstype=overlay ovl_dev1=LABEL=loops ovl_mnt1=/loops \
ovl_loopfile1=live/live.ext4 ovl_mnt1_sub=/loops/live/lower \
ovl_mnt2_sub=/loops/live root=overlay
3. 使用overlay, lower來源為squashfs, upper與work使用tmpfs
linux vmlinuz rootfstype=overlay ovl_dev1=LABEL=cd ovl_mnt1=/loops \
ovl_loopfile1=live.squashfs ovl_mnt1_sub=/lower \
ovl_dev2=tmpfs ovl_mnt2=/rw ovl_mnt2_opt=size=3072m root=overlay
接著預計自製 live-cd...
: 以下為與原檔initrd.d/linuxrc[C比較 新增的內容
: ====================================
# zm 1: get parameters for boot from loop file or overlayfs
loops_dev=*)
LOOPS_DEV=${x#*=}
;;
loops_mnt=*)
LOOPS_MNT=${x#*=}
;;
loop_file=*)
LOOP_FILE=${x#*=}
;;
ovl_dev1=*)
OVL_DEV1=${x#*=}
;;
ovl_dev2=*)
OVL_DEV2=${x#*=}
;;
ovl_mnt1=*)
OVL_MNT1=${x#*=}
;;
ovl_mnt2=*)
OVL_MNT2=${x#*=}
;;
ovl_mnt2_opt=*)
OVL_MNT2_OPT=${x#*=}
;;
ovl_loopfile1=*)
OVL_LOOPFILE1=${x#*=}
;;
ovl_loopfile2=*)
OVL_LOOPFILE2=${x#*=}
;;
ovl_mnt1_sub=*)
OVL_MNT1_SUB=${x#*=}
;;
ovl_mnt2_sub=*)
OVL_MNT2_SUB=${x#*=}
;;
mount_move)
MOUNT_MOVE=1
;; # zm
------------
# zm 2: find the device which contains loop files, mount and losetup.
if [ -n "${LOOPS_DEV}" ]; then
if [ -z "${LOOPS_MNT}" ]; then
LOOPS_MNT='/loops'
fi
MNT_DEV=""
while [ "${MNT_DEV}" = '' ]
do
case "${LOOPS_DEV}" in
LABEL=*|UUID=*)
retval=1
if [ ${retval} -ne 0 ]; then
MNT_DEV=$(findfs "${LOOPS_DEV}" )
retval=$?
fi
if [ ${retval} -ne 0 ]; then
MNT_DEV=$(busybox findfs "${LOOPS_DEV}" )
# MNT_DEV=$(busybox findfs "${LOOPS_DEV}" 2>/dev/null)
retval=$?
fi
if [ ${retval} -ne 0 ]; then
MNT_DEV=$(blkid -o device -l -t "${LOOPS_DEV}")
retval=$?
fi
if [ ${retval} -eq 0 ] && [ -n "${MNT_DEV}" ]; then
good_msg "Detected loops_dev=${MNT_DEV}"
else
prompt_user "MNT_DEV" "block device"
continue
fi
;;
esac
done;
if [ -n "${LOOP_FILE}" ]; then
mkdir -p ${LOOPS_MNT}
mount ${MNT_DEV} ${LOOPS_MNT}
losetup /dev/loop0 "${LOOPS_MNT}/${LOOP_FILE}"
fi
fi
# zm 2-1: find the devices, loopfiles, dirs for overlay fs.
if [ "${ROOTFSTYPE}" = 'overlay' ]; then
OVL_MNT_DEV1=""
while [ "${OVL_MNT_DEV1}" = '' ]
do
case "${OVL_DEV1}" in
LABEL=*|UUID=*)
retval=1
if [ ${retval} -ne 0 ]; then
OVL_MNT_DEV1=$(findfs "${OVL_DEV1}" )
retval=$?
fi
if [ ${retval} -ne 0 ]; then
OVL_MNT_DEV1=$(busybox findfs "${OVL_DEV1}" )
# OVL_MNT_DEV1=$(busybox findfs "${OVL_DEV1}" 2>/dev/null)
retval=$?
fi
if [ ${retval} -ne 0 ]; then
OVL_MNT_DEV1=$(blkid -o device -l -t "${OVL_DEV1}")
retval=$?
fi
if [ ${retval} -eq 0 ] && [ -n "${OVL_MNT_DEV1}" ]; then
good_msg "Detected ovl_dev1=${OVL_MNT_DEV1}"
else
prompt_user "ovl_dev1" "${OVL_DEV1}" "failed"
continue
fi
;;
esac
done;
if [ -n "${OVL_MNT_DEV1}" ] && [ -n "${OVL_MNT1}" ]; then
mkdir -p ${OVL_MNT1}
mount ${OVL_MNT_DEV1} ${OVL_MNT1}
if [ "$?" = '0' ]; then
OVL_DEV1_MOUNTED=1
else
OVL_DEV1_MOUNTED=0
fi
fi
if [ "${OVL_DEV1_MOUNTED}" = '1' ]; then
if [ -n "${OVL_LOOPFILE1}" ]; then
if [ -z "${OVL_MNT1_SUB}" ]; then
OVL_MNT1_SUB="/lower"
fi
mkdir -p "${OVL_MNT1_SUB}"
losetup /dev/loop0 "${OVL_MNT1}/${OVL_LOOPFILE1}"
mount /dev/loop0 "${OVL_MNT1_SUB}"
# mount -t squashfs -o loop "${OVL_MNT1}/${OVL_LOOPFILE1}" "${OVL_MNT1_SUB}"
LOWER="lowerdir=${OVL_MNT1_SUB}"
else
if [ -n "${OVL_MNT1_SUB}" ]; then
LOWER="lowerdir=${OVL_MNT1_SUB}"
else
LOWER="lowerdir=${OVL_MNT1}"
fi
fi
got_good_root=1
fi
if [ -n "${OVL_DEV2}" ]; then
if [ "${OVL_DEV2}" = 'tmpfs' ]; then
if [ -z "${OVL_MNT2_OPT}" ]; then
OVL_MNT2_OPT='size=3072m'
fi
mkdir -p "${OVL_MNT2}"
mount -t tmpfs -o "${OVL_MNT2_OPT}" tmpfs "${OVL_MNT2}"
good_msg "Mounting -t ovl_dev2=${OVL_DEV2} -o ${OVL_MNT2_OPT} tmpfs ${OVL_MNT2}"
UPPER="upperdir=${OVL_MNT2}/upper"
mkdir -p "${OVL_MNT2}/upper"
WORK="workdir=${OVL_MNT2}/work"
mkdir -p "${OVL_MNT2}/work"
else
OVL_MNT_DEV2=""
while [ "${OVL_MNT_DEV2}" = '' ]
do
case "${OVL_DEV2}" in
LABEL=*|UUID=*)
retval=1
if [ ${retval} -ne 0 ]; then
OVL_MNT_DEV2=$(findfs "${OVL_DEV2}" )
retval=$?
fi
if [ ${retval} -ne 0 ]; then
OVL_MNT_DEV2=$(busybox findfs "${OVL_DEV2}" )
retval=$?
fi
if [ ${retval} -ne 0 ]; then
OVL_MNT_DEV2=$(blkid -o device -l -t "${OVL_DEV2}")
retval=$?
fi
if [ ${retval} -eq 0 ] && [ -n "${OVL_MNT_DEV2}" ]; then
good_msg "Detected ovl_dev2=${OVL_MNT_DEV2}"
else
prompt_user "Maybe ovl_dev2 ${OVL_DEV2} failed"
continue
fi
;;
esac
done;
if [ -n "${OVL_MNT_DEV2}" ] && [ -n "${OVL_MNT2}" ]; then
mkdir -p ${OVL_MNT2}
mount ${OVL_MNT_DEV2} ${OVL_MNT2}
if [ -z "${OVL_LOOPFILE2}" ]; then
UPPER="upperdir=${OVL_MNT2}/upper"
mkdir -p "${OVL_MNT2}/upper"
WORK="workdir=${OVL_MNT2}/work"
mkdir -p "${OVL_MNT2}/work"
fi
fi
if [ -n "${OVL_LOOPFILE2}" ]; then
if [ -z "${OVL_MNT2_SUB}" ]; then
OVL_MNT2_SUB="${OVL_MNT2}/rw"
fi
mkdir -p "${OVL_MNT2_SUB}"
losetup /dev/loop1 "${OVL_MNT2}/${OVL_LOOPFILE2}"
mount /dev/loop1 "${OVL_MNT2_SUB}"
mkdir -p "${OVL_MNT2_SUB}/upper"
mkdir -p "${OVL_MNT2_SUB}/work"
UPPER="upperdir=${OVL_MNT2_SUB}/upper"
WORK="workdir=${OVL_MNT2_SUB}/work"
else
if [ -n "${OVL_MNT2_SUB}" ]; then
mkdir -p "${OVL_MNT2_SUB}/upper"
mkdir -p "${OVL_MNT2_SUB}/work"
UPPER="upperdir=${OVL_MNT2_SUB}/upper"
WORK="workdir=${OVL_MNT2_SUB}/work"
fi
fi
fi # [ "${OVL_DEV2}" = 'tmpfs' ]
else # [ -n "${OVL_DEV2}" ]
if [ -n "${OVL_MNT2_SUB}" ]; then
mkdir -p "${OVL_MNT2_SUB}/upper"
mkdir -p "${OVL_MNT2_SUB}/work"
UPPER="upperdir=${OVL_MNT2_SUB}/upper"
WORK="workdir=${OVL_MNT2_SUB}/work"
else
if [ -z "${UPPER}" ]; then
UPPER="upperdir=${OVL_MNT1}/upper"
mkdir -p "${OVL_MNT1}/upper"
fi
if [ -z "${WORK}" ]; then
WORK="workdir=${OVL_MNT1}/work"
mkdir -p "${OVL_MNT1}/work"
fi
fi
fi # [ -n "${OVL_DEV2}" ]
good_msg "OverlayFS - lower:${LOWER}, upper:${UPPER}, work:${WORK} ..."
REAL_ROOTFLAGS="${LOWER},${UPPER},${WORK}"
fi # zm [ "${ROOTFSTYPE}" = 'overlay' ]
------------
# zm 3: move LOOPS_MNT or OVL_MNTs from initramfs to real root
if [ "${MOUNT_MOVE}" = '1' ]; then
if [ -n "${LOOPS_MNT}" ]; then
if [ ! -e "${CHROOT}${LOOPS_MNT}" ]; then
mkdir -p "${CHROOT}${LOOPS_MNT}"
fi
mount --move "${LOOPS_MNT}" "${CHROOT}${LOOPS_MNT}"
good_msg "Remounting loop_dev=${LOOPS_DEV} to ${CHROOT}${LOOPS_MNT}"
fi
if [ -n "${OVL_MNT1}" ]; then
if [ ! -e "${CHROOT}${OVL_MNT1}" ]; then
mkdir -p "${CHROOT}${OVL_MNT1}"
fi
mount --move "${OVL_MNT1}" "${CHROOT}${OVL_MNT1}"
good_msg "Remounting loop_dev=${OVL_DEV1} to ${CHROOT}${OVL_MNT1}"
fi
if [ -n "${OVL_MNT2}" ]; then
if [ ! -e "${CHROOT}${OVL_MNT2}" ]; then
mkdir -p "${CHROOT}${OVL_MNT2}"
fi
mount --move "${OVL_MNT2}" "${CHROOT}${OVL_MNT2}"
good_msg "Remounting loop_dev=${OVL_DEV2} to ${CHROOT}${OVL_MNT2}"
fi
fi # zm
-------
--
新增可OverlayFS boot
同樣是新增修改這三部份
: part1: 參數讀取
放在參數讀取的那區
: part2: 解析UUID=, LABEL=; mount and losetup.
放在 Determine root device 前
: part3: mount --move
放在switch_root 前
在grub.cfg內的用法,舉例三種:
1. 最初的版本 只用單一loopfile 啟動os
linux vmlinuz loops_dev=LABEL=loops loops_mnt=/loops \
loop_file=live.ext4 root=LABEL=live
2. 使用overlay boot, 但lower,upper,work都在同一可寫的目錄下
linux vmlinuz rootfstype=overlay ovl_dev1=LABEL=loops ovl_mnt1=/loops \
ovl_loopfile1=live/live.ext4 ovl_mnt1_sub=/loops/live/lower \
ovl_mnt2_sub=/loops/live root=overlay
3. 使用overlay, lower來源為squashfs, upper與work使用tmpfs
linux vmlinuz rootfstype=overlay ovl_dev1=LABEL=cd ovl_mnt1=/loops \
ovl_loopfile1=live.squashfs ovl_mnt1_sub=/lower \
ovl_dev2=tmpfs ovl_mnt2=/rw ovl_mnt2_opt=size=3072m root=overlay
接著預計自製 live-cd...
: 以下為與原檔initrd.d/linuxrc[C比較 新增的內容
: ====================================
# zm 1: get parameters for boot from loop file or overlayfs
loops_dev=*)
LOOPS_DEV=${x#*=}
;;
loops_mnt=*)
LOOPS_MNT=${x#*=}
;;
loop_file=*)
LOOP_FILE=${x#*=}
;;
ovl_dev1=*)
OVL_DEV1=${x#*=}
;;
ovl_dev2=*)
OVL_DEV2=${x#*=}
;;
ovl_mnt1=*)
OVL_MNT1=${x#*=}
;;
ovl_mnt2=*)
OVL_MNT2=${x#*=}
;;
ovl_mnt2_opt=*)
OVL_MNT2_OPT=${x#*=}
;;
ovl_loopfile1=*)
OVL_LOOPFILE1=${x#*=}
;;
ovl_loopfile2=*)
OVL_LOOPFILE2=${x#*=}
;;
ovl_mnt1_sub=*)
OVL_MNT1_SUB=${x#*=}
;;
ovl_mnt2_sub=*)
OVL_MNT2_SUB=${x#*=}
;;
mount_move)
MOUNT_MOVE=1
;; # zm
------------
# zm 2: find the device which contains loop files, mount and losetup.
if [ -n "${LOOPS_DEV}" ]; then
if [ -z "${LOOPS_MNT}" ]; then
LOOPS_MNT='/loops'
fi
MNT_DEV=""
while [ "${MNT_DEV}" = '' ]
do
case "${LOOPS_DEV}" in
LABEL=*|UUID=*)
retval=1
if [ ${retval} -ne 0 ]; then
MNT_DEV=$(findfs "${LOOPS_DEV}" )
retval=$?
fi
if [ ${retval} -ne 0 ]; then
MNT_DEV=$(busybox findfs "${LOOPS_DEV}" )
# MNT_DEV=$(busybox findfs "${LOOPS_DEV}" 2>/dev/null)
retval=$?
fi
if [ ${retval} -ne 0 ]; then
MNT_DEV=$(blkid -o device -l -t "${LOOPS_DEV}")
retval=$?
fi
if [ ${retval} -eq 0 ] && [ -n "${MNT_DEV}" ]; then
good_msg "Detected loops_dev=${MNT_DEV}"
else
prompt_user "MNT_DEV" "block device"
continue
fi
;;
esac
done;
if [ -n "${LOOP_FILE}" ]; then
mkdir -p ${LOOPS_MNT}
mount ${MNT_DEV} ${LOOPS_MNT}
losetup /dev/loop0 "${LOOPS_MNT}/${LOOP_FILE}"
fi
fi
# zm 2-1: find the devices, loopfiles, dirs for overlay fs.
if [ "${ROOTFSTYPE}" = 'overlay' ]; then
OVL_MNT_DEV1=""
while [ "${OVL_MNT_DEV1}" = '' ]
do
case "${OVL_DEV1}" in
LABEL=*|UUID=*)
retval=1
if [ ${retval} -ne 0 ]; then
OVL_MNT_DEV1=$(findfs "${OVL_DEV1}" )
retval=$?
fi
if [ ${retval} -ne 0 ]; then
OVL_MNT_DEV1=$(busybox findfs "${OVL_DEV1}" )
# OVL_MNT_DEV1=$(busybox findfs "${OVL_DEV1}" 2>/dev/null)
retval=$?
fi
if [ ${retval} -ne 0 ]; then
OVL_MNT_DEV1=$(blkid -o device -l -t "${OVL_DEV1}")
retval=$?
fi
if [ ${retval} -eq 0 ] && [ -n "${OVL_MNT_DEV1}" ]; then
good_msg "Detected ovl_dev1=${OVL_MNT_DEV1}"
else
prompt_user "ovl_dev1" "${OVL_DEV1}" "failed"
continue
fi
;;
esac
done;
if [ -n "${OVL_MNT_DEV1}" ] && [ -n "${OVL_MNT1}" ]; then
mkdir -p ${OVL_MNT1}
mount ${OVL_MNT_DEV1} ${OVL_MNT1}
if [ "$?" = '0' ]; then
OVL_DEV1_MOUNTED=1
else
OVL_DEV1_MOUNTED=0
fi
fi
if [ "${OVL_DEV1_MOUNTED}" = '1' ]; then
if [ -n "${OVL_LOOPFILE1}" ]; then
if [ -z "${OVL_MNT1_SUB}" ]; then
OVL_MNT1_SUB="/lower"
fi
mkdir -p "${OVL_MNT1_SUB}"
losetup /dev/loop0 "${OVL_MNT1}/${OVL_LOOPFILE1}"
mount /dev/loop0 "${OVL_MNT1_SUB}"
# mount -t squashfs -o loop "${OVL_MNT1}/${OVL_LOOPFILE1}" "${OVL_MNT1_SUB}"
LOWER="lowerdir=${OVL_MNT1_SUB}"
else
if [ -n "${OVL_MNT1_SUB}" ]; then
LOWER="lowerdir=${OVL_MNT1_SUB}"
else
LOWER="lowerdir=${OVL_MNT1}"
fi
fi
got_good_root=1
fi
if [ -n "${OVL_DEV2}" ]; then
if [ "${OVL_DEV2}" = 'tmpfs' ]; then
if [ -z "${OVL_MNT2_OPT}" ]; then
OVL_MNT2_OPT='size=3072m'
fi
mkdir -p "${OVL_MNT2}"
mount -t tmpfs -o "${OVL_MNT2_OPT}" tmpfs "${OVL_MNT2}"
good_msg "Mounting -t ovl_dev2=${OVL_DEV2} -o ${OVL_MNT2_OPT} tmpfs ${OVL_MNT2}"
UPPER="upperdir=${OVL_MNT2}/upper"
mkdir -p "${OVL_MNT2}/upper"
WORK="workdir=${OVL_MNT2}/work"
mkdir -p "${OVL_MNT2}/work"
else
OVL_MNT_DEV2=""
while [ "${OVL_MNT_DEV2}" = '' ]
do
case "${OVL_DEV2}" in
LABEL=*|UUID=*)
retval=1
if [ ${retval} -ne 0 ]; then
OVL_MNT_DEV2=$(findfs "${OVL_DEV2}" )
retval=$?
fi
if [ ${retval} -ne 0 ]; then
OVL_MNT_DEV2=$(busybox findfs "${OVL_DEV2}" )
retval=$?
fi
if [ ${retval} -ne 0 ]; then
OVL_MNT_DEV2=$(blkid -o device -l -t "${OVL_DEV2}")
retval=$?
fi
if [ ${retval} -eq 0 ] && [ -n "${OVL_MNT_DEV2}" ]; then
good_msg "Detected ovl_dev2=${OVL_MNT_DEV2}"
else
prompt_user "Maybe ovl_dev2 ${OVL_DEV2} failed"
continue
fi
;;
esac
done;
if [ -n "${OVL_MNT_DEV2}" ] && [ -n "${OVL_MNT2}" ]; then
mkdir -p ${OVL_MNT2}
mount ${OVL_MNT_DEV2} ${OVL_MNT2}
if [ -z "${OVL_LOOPFILE2}" ]; then
UPPER="upperdir=${OVL_MNT2}/upper"
mkdir -p "${OVL_MNT2}/upper"
WORK="workdir=${OVL_MNT2}/work"
mkdir -p "${OVL_MNT2}/work"
fi
fi
if [ -n "${OVL_LOOPFILE2}" ]; then
if [ -z "${OVL_MNT2_SUB}" ]; then
OVL_MNT2_SUB="${OVL_MNT2}/rw"
fi
mkdir -p "${OVL_MNT2_SUB}"
losetup /dev/loop1 "${OVL_MNT2}/${OVL_LOOPFILE2}"
mount /dev/loop1 "${OVL_MNT2_SUB}"
mkdir -p "${OVL_MNT2_SUB}/upper"
mkdir -p "${OVL_MNT2_SUB}/work"
UPPER="upperdir=${OVL_MNT2_SUB}/upper"
WORK="workdir=${OVL_MNT2_SUB}/work"
else
if [ -n "${OVL_MNT2_SUB}" ]; then
mkdir -p "${OVL_MNT2_SUB}/upper"
mkdir -p "${OVL_MNT2_SUB}/work"
UPPER="upperdir=${OVL_MNT2_SUB}/upper"
WORK="workdir=${OVL_MNT2_SUB}/work"
fi
fi
fi # [ "${OVL_DEV2}" = 'tmpfs' ]
else # [ -n "${OVL_DEV2}" ]
if [ -n "${OVL_MNT2_SUB}" ]; then
mkdir -p "${OVL_MNT2_SUB}/upper"
mkdir -p "${OVL_MNT2_SUB}/work"
UPPER="upperdir=${OVL_MNT2_SUB}/upper"
WORK="workdir=${OVL_MNT2_SUB}/work"
else
if [ -z "${UPPER}" ]; then
UPPER="upperdir=${OVL_MNT1}/upper"
mkdir -p "${OVL_MNT1}/upper"
fi
if [ -z "${WORK}" ]; then
WORK="workdir=${OVL_MNT1}/work"
mkdir -p "${OVL_MNT1}/work"
fi
fi
fi # [ -n "${OVL_DEV2}" ]
good_msg "OverlayFS - lower:${LOWER}, upper:${UPPER}, work:${WORK} ..."
REAL_ROOTFLAGS="${LOWER},${UPPER},${WORK}"
fi # zm [ "${ROOTFSTYPE}" = 'overlay' ]
------------
# zm 3: move LOOPS_MNT or OVL_MNTs from initramfs to real root
if [ "${MOUNT_MOVE}" = '1' ]; then
if [ -n "${LOOPS_MNT}" ]; then
if [ ! -e "${CHROOT}${LOOPS_MNT}" ]; then
mkdir -p "${CHROOT}${LOOPS_MNT}"
fi
mount --move "${LOOPS_MNT}" "${CHROOT}${LOOPS_MNT}"
good_msg "Remounting loop_dev=${LOOPS_DEV} to ${CHROOT}${LOOPS_MNT}"
fi
if [ -n "${OVL_MNT1}" ]; then
if [ ! -e "${CHROOT}${OVL_MNT1}" ]; then
mkdir -p "${CHROOT}${OVL_MNT1}"
fi
mount --move "${OVL_MNT1}" "${CHROOT}${OVL_MNT1}"
good_msg "Remounting loop_dev=${OVL_DEV1} to ${CHROOT}${OVL_MNT1}"
fi
if [ -n "${OVL_MNT2}" ]; then
if [ ! -e "${CHROOT}${OVL_MNT2}" ]; then
mkdir -p "${CHROOT}${OVL_MNT2}"
fi
mount --move "${OVL_MNT2}" "${CHROOT}${OVL_MNT2}"
good_msg "Remounting loop_dev=${OVL_DEV2} to ${CHROOT}${OVL_MNT2}"
fi
fi # zm
-------
--
Tags:
Linux
All Comments

By Joseph
at 2017-07-16T05:02
at 2017-07-16T05:02

By Hedy
at 2017-07-19T17:37
at 2017-07-19T17:37
Related Posts
無法輸入中文字

By Joseph
at 2017-07-12T20:50
at 2017-07-12T20:50
firefox變成zombie process

By Kristin
at 2017-07-12T18:11
at 2017-07-12T18:11
git add 失敗

By Ida
at 2017-07-12T15:31
at 2017-07-12T15:31
為什麼mint很多人用?

By William
at 2017-07-12T00:37
at 2017-07-12T00:37
請問外網連SAMBA到底要不要開PORT號呢?

By Necoo
at 2017-07-11T14:19
at 2017-07-11T14:19