Compare commits

...

31 Commits
v5.02 ... v5.04

Author SHA1 Message Date
Kroese
ef5b650991 fix: Shutdown loop (#474) 2023-12-20 12:09:25 +01:00
Kroese
fd19c7b4f3 feat: Log creation info (#473) 2023-12-20 03:34:26 +01:00
Kroese
727297642c fix: Exit counter (#472) 2023-12-20 02:00:07 +01:00
Kroese
cd457801e7 fix: Set IP in bridge mode
* fix: Set IP in bridge mode
2023-12-20 01:52:55 +01:00
Kroese
392e7afdfe fix: Allocate after conversion
fix: Allocate after conversion
2023-12-19 08:54:43 +01:00
Kroese
b425e34907 fix: Allocate after conversion 2023-12-19 08:54:08 +01:00
Kroese
7c2e2fc7b1 feat: Enable IO threading
feat: Enable IO threading
2023-12-19 06:16:28 +01:00
Kroese
9bac0c94a8 feat: Detect COW on btrfs 2023-12-19 06:11:50 +01:00
Kroese
631568681e feat: Detect COW on BTRFS 2023-12-19 06:01:50 +01:00
Kroese
6599861dbb feat: Detect COW on BTRFS 2023-12-19 05:46:49 +01:00
Kroese
3bcd831531 fix: Display timeout 2023-12-19 04:30:01 +01:00
Kroese
fafd4a4fca feat: Enable IO threading 2023-12-19 03:59:19 +01:00
Kroese
5b69178f08 docs: Allocation 2023-12-19 03:33:41 +01:00
Kroese
479a30369d feat: Enable IO threading 2023-12-19 02:34:48 +01:00
Kroese
ba522a4acb feat: Increase clustersize for qcow2
* feat: Increase clustersize for qcow2
2023-12-18 17:34:40 +01:00
Kroese
3ab6d2c418 docs: Allocation 2023-12-18 16:48:01 +01:00
Kroese
b71b2245cb fix: Check diskspace
* fix: Check diskspace
2023-12-18 16:44:26 +01:00
Kroese
bbea0eb429 docs: Readme 2023-12-18 12:39:11 +01:00
Kroese
c28c5cfbaa docs: Allocation 2023-12-18 12:36:03 +01:00
Kroese
be3fd30cb2 feat: Honor allocation flag for qcow2
* feat: Honor allocation flag for qcow2
2023-12-18 12:18:28 +01:00
Kroese
e3942da906 feat: Set NOCOW flag for btrfs
feat: Set NOCOW flag for btrfs
2023-12-17 11:42:08 +01:00
Kroese
d66be1a228 fix: Do not set flags on resize 2023-12-17 11:25:42 +01:00
Kroese
72085d3711 fix: Set qcow2 flags 2023-12-17 11:17:26 +01:00
Kroese
e7cdbb1db5 feat: Optimize qcow2 flags 2023-12-17 10:51:30 +01:00
Kroese
7a592e0cea docs: DHCP mode 2023-12-17 10:08:55 +01:00
Kroese
107a4b87d5 fix: Quotes 2023-12-17 10:04:00 +01:00
Kroese
8b0ec3bef7 fix: Remove healthcheck exception 2023-12-17 09:57:50 +01:00
Kroese
aaded40a4f fix: Cleanup server files 2023-12-17 09:54:07 +01:00
Kroese
7f77bb88ab fix: Grammar 2023-12-17 09:50:07 +01:00
Kroese
95c3b2caad fix: Default folder 2023-12-17 09:39:19 +01:00
Kroese
150c450bf6 docs: Default folder 2023-12-17 09:37:36 +01:00
8 changed files with 237 additions and 144 deletions

View File

@@ -18,6 +18,6 @@ services:
ports:
- 5000:5000
volumes:
- /opt/dsm:/storage
- /var/dsm:/storage
restart: on-failure
stop_grace_period: 2m

View File

@@ -39,7 +39,7 @@ services:
ports:
- 5000:5000
volumes:
- /opt/dsm:/storage
- /var/dsm:/storage
restart: on-failure
stop_grace_period: 2m
```
@@ -65,14 +65,14 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
* ### How do I change the location of the virtual disk?
To change the virtual disk's location from the default Docker volume, include the following bind mount in your compose file:
To change the location of the virtual disk, include the following bind mount in your compose file:
```yaml
volumes:
- /home/user/data:/storage
- /var/dsm:/storage
```
Replace the example path `/home/user/data` with the desired storage folder.
Replace the example path `/var/dsm` with the desired storage folder.
* ### How do I add multiple disks?
@@ -89,18 +89,23 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
* ### How do I create a growable disk?
By default, the entire capacity of the disk is reserved in advance. To create a growable disk that only allocates space that is actually used, add the following environment variable:
By default, the entire capacity of the disk is reserved in advance.
To create a growable disk that only allocates space that is actually used, add the following environment variables:
```yaml
environment:
ALLOCATE: "N"
DISK_FMT: "qcow2"
```
This can also be used to convert any existing disks to the ```qcow2``` format.
Please note that this may reduce the write performance of the disk.
* ### How do I increase the amount of CPU or RAM?
By default, a single core and 1 GB of RAM are allocated to the container. To increase this, add the following environment variables:
By default, a single core and 1 GB of RAM are allocated to the container.
To increase this, add the following environment variables:
```yaml
environment:
@@ -170,7 +175,7 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
- 'c *:* rwm'
```
Please note that even if you don't need DHCP, it's still recommended to enable this feature as it prevents NAT issues and increases performance by using a `macvtap` interface.
Please note that even if you don't want DHCP, it's still recommended to enable this feature as it prevents NAT issues and increases performance by using a `macvtap` interface. In that case just set a static IP from the DSM control panel after you enabled this mode.
* ### How do I passthrough the GPU?

View File

@@ -31,7 +31,7 @@ if [[ "$ARCH" == "amd64" && "$KVM" != [Nn]* ]]; then
if [ -n "$KVM_OPTS" ]; then
if ! grep -qE '^flags.* (sse4_2)' /proc/cpuinfo; then
error "Your host CPU does not has the SSE4.2 instruction set that Virtual DSM requires to boot."
error "Your host CPU does not have the SSE4.2 instruction set that Virtual DSM requires to boot."
error "Disable KVM by setting KVM=N to emulate a compatible CPU, at the cost of performance."
[[ "$DEBUG" != [Yy1]* ]] && exit 89
fi

View File

@@ -8,6 +8,7 @@ set -Eeuo pipefail
: ${DISK_CACHE:='none'} # Caching mode, can be set to 'writeback' for better performance
: ${DISK_DISCARD:='on'} # Controls whether unmap (TRIM) commands are passed to the host.
: ${DISK_ROTATION:='1'} # Rotation rate, set to 1 for SSD storage and increase for HDD
: ${DISK_FLAGS:='nocow=on'} # Specifies the options for use with the qcow2 disk format
BOOT="$STORAGE/$BASE.boot.img"
SYSTEM="$STORAGE/$BASE.system.img"
@@ -16,10 +17,11 @@ SYSTEM="$STORAGE/$BASE.system.img"
[ ! -f "$SYSTEM" ] && error "Virtual DSM system-image does not exist ($SYSTEM)" && exit 82
DISK_OPTS="\
-device virtio-scsi-pci,id=hw-synoboot,bus=pcie.0,addr=0xa \
-object iothread,id=io1 -object iothread,id=io2 \
-device virtio-scsi-pci,id=hw-synoboot,iothread=io1,bus=pcie.0,addr=0xa \
-drive file=$BOOT,if=none,id=drive-synoboot,format=raw,cache=$DISK_CACHE,aio=$DISK_IO,discard=$DISK_DISCARD,detect-zeroes=on \
-device scsi-hd,bus=hw-synoboot.0,channel=0,scsi-id=0,lun=0,drive=drive-synoboot,id=synoboot0,rotation_rate=$DISK_ROTATION,bootindex=1 \
-device virtio-scsi-pci,id=hw-synosys,bus=pcie.0,addr=0xb \
-device virtio-scsi-pci,id=hw-synosys,iothread=io1,bus=pcie.0,addr=0xb \
-drive file=$SYSTEM,if=none,id=drive-synosys,format=raw,cache=$DISK_CACHE,aio=$DISK_IO,discard=$DISK_DISCARD,detect-zeroes=on \
-device scsi-hd,bus=hw-synosys.0,channel=0,scsi-id=0,lun=0,drive=drive-synosys,id=synosys0,rotation_rate=$DISK_ROTATION,bootindex=2"
@@ -75,45 +77,109 @@ getSize() {
esac
}
createDisk() {
local DISK_FILE=$1
local DISK_SPACE=$2
local DISK_DESC=$3
local DISK_FMT=$4
local DATA_SIZE DIR SPACE
DATA_SIZE=$(numfmt --from=iec "$DISK_SPACE")
if [[ "$ALLOCATE" != [Nn]* ]]; then
# Check free diskspace
DIR=$(dirname "$DISK_FILE")
SPACE=$(df --output=avail -B 1 "$DIR" | tail -n 1)
if (( DATA_SIZE > SPACE )); then
local SPACE_GB=$(( (SPACE + 1073741823)/1073741824 ))
error "Not enough free space to create a $DISK_DESC of $DISK_SPACE in $DIR, it has only $SPACE_GB GB available..."
error "Please specify a smaller ${DISK_DESC^^}_SIZE or disable preallocation by setting ALLOCATE=N." && exit 76
fi
fi
info "Creating a $DISK_TYPE $DISK_DESC image in $DISK_FMT format with a size of $DISK_SPACE..."
local FAIL="Could not create a $DISK_TYPE $DISK_FMT $DISK_DESC image of $DISK_SPACE ($DISK_FILE)"
case "${DISK_FMT,,}" in
raw)
if [[ "$ALLOCATE" == [Nn]* ]]; then
# Create an empty file
if ! truncate -s "$DATA_SIZE" "$DISK_FILE"; then
rm -f "$DISK_FILE"
error "$FAIL" && exit 77
fi
else
# Create an empty file
if ! fallocate -l "$DATA_SIZE" "$DISK_FILE"; then
if ! truncate -s "$DATA_SIZE" "$DISK_FILE"; then
rm -f "$DISK_FILE"
error "$FAIL" && exit 77
fi
fi
fi
;;
qcow2)
local DISK_OPTS="$DISK_ALLOC"
[ -n "$DISK_FLAGS" ] && DISK_OPTS="$DISK_OPTS,$DISK_FLAGS"
if ! qemu-img create -f "$DISK_FMT" -o "$DISK_OPTS" -- "$DISK_FILE" "$DATA_SIZE" ; then
rm -f "$DISK_FILE"
error "$FAIL" && exit 70
fi
;;
esac
return 0
}
resizeDisk() {
local DISK_FILE=$1
local CUR_SIZE=$2
local DATA_SIZE=$3
local DISK_SPACE=$4
local DISK_DESC=$5
local DISK_FMT=$6
local GB REQ FAIL SPACE SPACE_GB
local DISK_SPACE=$2
local DISK_DESC=$3
local DISK_FMT=$4
local CUR_SIZE DATA_SIZE DIR SPACE
GB=$(( (CUR_SIZE + 1073741823)/1073741824 ))
info "Resizing $DISK_DESC from ${GB}G to $DISK_SPACE .."
FAIL="Could not resize $DISK_FMT file of $DISK_DESC ($DISK_FILE) from ${GB}G to $DISK_SPACE .."
CUR_SIZE=$(getSize "$DISK_FILE")
DATA_SIZE=$(numfmt --from=iec "$DISK_SPACE")
local REQ=$((DATA_SIZE-CUR_SIZE))
(( REQ < 1 )) && error "Shrinking disks is not supported yet, please increase ${DISK_DESC^^}_SIZE." && exit 71
REQ=$((DATA_SIZE-CUR_SIZE))
(( REQ < 1 )) && error "Shrinking disks is not supported!" && exit 71
if [[ "$ALLOCATE" != [Nn]* ]]; then
# Check free diskspace
DIR=$(dirname "$DISK_FILE")
SPACE=$(df --output=avail -B 1 "$DIR" | tail -n 1)
if (( REQ > SPACE )); then
local SPACE_GB=$(( (SPACE + 1073741823)/1073741824 ))
error "Not enough free space to resize $DISK_DESC to $DISK_SPACE in $DIR, it has only $SPACE_GB GB available.."
error "Please specify a smaller ${DISK_DESC^^}_SIZE or disable preallocation by setting ALLOCATE=N." && exit 74
fi
fi
local GB=$(( (CUR_SIZE + 1073741823)/1073741824 ))
info "Resizing $DISK_DESC from ${GB}G to $DISK_SPACE..."
local FAIL="Could not resize the $DISK_TYPE $DISK_FMT $DISK_DESC image from ${GB}G to $DISK_SPACE ($DISK_FILE)"
case "${DISK_FMT,,}" in
raw)
if [[ "$ALLOCATE" == [Nn]* ]]; then
# Resize file by changing its length
if ! truncate -s "$DISK_SPACE" "$DISK_FILE"; then
if ! truncate -s "$DATA_SIZE" "$DISK_FILE"; then
error "$FAIL" && exit 75
fi
else
# Check free diskspace
SPACE=$(df --output=avail -B 1 "$DIR" | tail -n 1)
SPACE_GB=$(( (SPACE + 1073741823)/1073741824 ))
if (( REQ > SPACE )); then
error "Not enough free space to resize $DISK_DESC to $DISK_SPACE in $DIR, it has only $SPACE_GB GB available.."
error "Please specify a smaller ${DISK_DESC^^}_SIZE or disable preallocation by setting DISK_FMT to \"qcow2\"." && exit 74
fi
# Resize file by allocating more space
if ! fallocate -l "$DISK_SPACE" "$DISK_FILE"; then
if ! truncate -s "$DISK_SPACE" "$DISK_FILE"; then
if ! fallocate -l "$DATA_SIZE" "$DISK_FILE"; then
if ! truncate -s "$DATA_SIZE" "$DISK_FILE"; then
error "$FAIL" && exit 75
fi
fi
@@ -121,77 +187,76 @@ resizeDisk() {
fi
;;
qcow2)
if ! qemu-img resize -f "$DISK_FMT" "$DISK_FILE" "$DISK_SPACE" ; then
if ! qemu-img resize -f "$DISK_FMT" "--$DISK_ALLOC" "$DISK_FILE" "$DATA_SIZE" ; then
error "$FAIL" && exit 72
fi
;;
esac
return 0
}
convertDisk() {
local CONV_FLAGS="-p"
local SOURCE_FILE=$1
local SOURCE_FMT=$2
local DST_FILE=$3
local DST_FMT=$4
local DISK_BASE=$5
local DISK_DESC=$6
local CONV_FLAGS="-p"
local DISK_OPTS="$DISK_ALLOC"
local TMP_FILE="$DISK_BASE.tmp"
local DIR CUR_SIZE SPACE
case "$DST_FMT" in
qcow2)
CONV_FLAGS="$CONV_FLAGS -c"
;;
esac
[ -f "$DST_FILE" ] && error "Conversion failed, destination file $DST_FILE already exists?" && exit 79
[ ! -f "$SOURCE_FILE" ] && error "Conversion failed, source file $SOURCE_FILE does not exists?" && exit 79
# shellcheck disable=SC2086
qemu-img convert $CONV_FLAGS -f "$SOURCE_FMT" -O "$DST_FMT" -- "$SOURCE_FILE" "$DST_FILE"
}
createDisk() {
local DISK_FILE=$1
local DISK_SPACE=$2
local DISK_DESC=$3
local DISK_FMT=$4
local GB FAIL SPACE SPACE_GB
FAIL="Could not create a $DISK_SPACE $DISK_FMT file for $DISK_DESC ($DISK_FILE)"
case "${DISK_FMT,,}" in
raw)
if [[ "$ALLOCATE" == [Nn]* ]]; then
# Create an empty file
if ! truncate -s "$DISK_SPACE" "$DISK_FILE"; then
rm -f "$DISK_FILE"
error "$FAIL" && exit 77
fi
else
if [[ "$ALLOCATE" != [Nn]* ]]; then
# Check free diskspace
DIR=$(dirname "$TMP_FILE")
CUR_SIZE=$(getSize "$SOURCE_FILE")
SPACE=$(df --output=avail -B 1 "$DIR" | tail -n 1)
SPACE_GB=$(( (SPACE + 1073741823)/1073741824 ))
if (( DATA_SIZE > SPACE )); then
error "Not enough free space to create a $DISK_DESC of $DISK_SPACE in $DIR, it has only $SPACE_GB GB available.."
error "Please specify a smaller ${DISK_DESC^^}_SIZE or disable preallocation by setting DISK_FMT to \"qcow2\"." && exit 76
fi
# Create an empty file
if ! fallocate -l "$DISK_SPACE" "$DISK_FILE"; then
if ! truncate -s "$DISK_SPACE" "$DISK_FILE"; then
rm -f "$DISK_FILE"
error "$FAIL" && exit 77
if (( CUR_SIZE > SPACE )); then
local SPACE_GB=$(( (SPACE + 1073741823)/1073741824 ))
error "Not enough free space to convert $DISK_DESC to $DST_FMT in $DIR, it has only $SPACE_GB GB available..."
error "Please free up some disk space or disable preallocation by setting ALLOCATE=N." && exit 76
fi
fi
info "Converting $DISK_DESC to $DST_FMT, please wait until completed..."
if [[ "$DST_FMT" != "raw" ]]; then
if [[ "$ALLOCATE" == [Nn]* ]]; then
CONV_FLAGS="$CONV_FLAGS -c"
fi
;;
qcow2)
if ! qemu-img create -f "$DISK_FMT" -- "$DISK_FILE" "$DISK_SPACE" ; then
rm -f "$DISK_FILE"
error "$FAIL" && exit 70
[ -n "$DISK_FLAGS" ] && DISK_OPTS="$DISK_OPTS,$DISK_FLAGS"
fi
;;
esac
rm -f "$TMP_FILE"
# shellcheck disable=SC2086
if ! qemu-img convert -f "$SOURCE_FMT" $CONV_FLAGS -o "$DISK_OPTS" -O "$DST_FMT" -- "$SOURCE_FILE" "$TMP_FILE"; then
rm -f "$TMP_FILE"
error "Failed to convert $DISK_TYPE $DISK_DESC image to $DST_FMT format in $DIR, is there enough space available?" && exit 79
fi
if [[ "$DST_FMT" == "raw" ]]; then
if [[ "$ALLOCATE" != [Nn]* ]]; then
CUR_SIZE=$(stat -c%s "$TMP_FILE")
if ! fallocate -l "$CUR_SIZE" "$TMP_FILE"; then
info "Failed to allocate $CUR_SIZE bytes for $TMP_FILE"
fi
fi
fi
rm -f "$SOURCE_FILE"
mv "$TMP_FILE" "$DST_FILE"
info "Conversion of $DISK_DESC to $DST_FMT completed succesfully!"
return 0
}
addDisk () {
@@ -203,9 +268,9 @@ addDisk () {
local DISK_INDEX=$6
local DISK_ADDRESS=$7
local DISK_FMT=$8
local FS DIR CUR_SIZE DATA_SIZE DISK_FILE
local DISK_FILE="$DISK_BASE.$DISK_EXT"
local DIR FS FA DATA_SIZE PREV_FMT PREV_EXT CUR_SIZE
DISK_FILE="$DISK_BASE.$DISK_EXT"
DIR=$(dirname "$DISK_FILE")
[ ! -d "$DIR" ] && return 0
@@ -213,17 +278,32 @@ addDisk () {
if [[ "$FS" == "overlay"* ]]; then
info "Warning: the filesystem of $DIR is OverlayFS, this usually means it was binded to an invalid path!"
fi
if [[ "$FS" == "btrfs"* ]]; then
if [ -f "$DISK_FILE" ] ; then
FA=$(lsattr "$DISK_FILE")
[[ "$FA" == *"C"* ]] && FA=$(lsattr -d "$DIR")
else
FA=$(lsattr -d "$DIR")
fi
if [[ "$FA" != *"C"* ]]; then
info "Warning: the filesystem of $DIR is BTRFS, and COW (copy on write) is not disabled for that folder!"
info "This will negatively affect write performance, please empty the folder and disable COW (chattr +C <path>)."
fi
fi
[ -z "$DISK_SPACE" ] && DISK_SPACE="16G"
DISK_SPACE=$(echo "$DISK_SPACE" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g')
DATA_SIZE=$(numfmt --from=iec "$DISK_SPACE")
if (( DATA_SIZE < 6442450944 )); then
if (( DATA_SIZE < 1 )); then
error "Invalid value for ${DISK_DESC^^}_SIZE: $DISK_SPACE" && exit 73
else
error "Please increase ${DISK_DESC^^}_SIZE to at least 6 GB." && exit 73
fi
fi
if ! [ -f "$DISK_FILE" ] ; then
local PREV_EXT PREV_FMT PREV_FILE TMP_FILE
if [[ "${DISK_FMT,,}" != "raw" ]]; then
PREV_FMT="raw"
@@ -231,24 +311,9 @@ addDisk () {
PREV_FMT="qcow2"
fi
PREV_EXT="$(fmt2ext "$PREV_FMT")"
PREV_FILE="$DISK_BASE.$PREV_EXT"
if [ -f "$PREV_FILE" ] ; then
info "Detected that ${DISK_DESC^^}_FMT changed from \"$PREV_FMT\" to \"$DISK_FMT\"."
info "Starting conversion of $DISK_DESC to this new format, please wait until completed..."
TMP_FILE="$DISK_BASE.tmp"
rm -f "$TMP_FILE"
if ! convertDisk "$PREV_FILE" "$PREV_FMT" "$TMP_FILE" "$DISK_FMT" ; then
rm -f "$TMP_FILE"
error "Failed to convert $DISK_DESC to $DISK_FMT format." && exit 79
fi
mv "$TMP_FILE" "$DISK_FILE"
rm -f "$PREV_FILE"
info "Conversion of $DISK_DESC completed succesfully!"
if [ -f "$DISK_BASE.$PREV_EXT" ] ; then
convertDisk "$DISK_BASE.$PREV_EXT" "$PREV_FMT" "$DISK_FILE" "$DISK_FMT" "$DISK_BASE" "$DISK_DESC" || exit $?
fi
fi
@@ -256,8 +321,8 @@ addDisk () {
CUR_SIZE=$(getSize "$DISK_FILE")
if [ "$DATA_SIZE" -gt "$CUR_SIZE" ]; then
resizeDisk "$DISK_FILE" "$CUR_SIZE" "$DATA_SIZE" "$DISK_SPACE" "$DISK_DESC" "$DISK_FMT" || exit $?
if (( DATA_SIZE > CUR_SIZE )); then
resizeDisk "$DISK_FILE" "$DISK_SPACE" "$DISK_DESC" "$DISK_FMT" || exit $?
fi
else
@@ -267,7 +332,7 @@ addDisk () {
fi
DISK_OPTS="$DISK_OPTS \
-device virtio-scsi-pci,id=hw-$DISK_ID,bus=pcie.0,addr=$DISK_ADDRESS \
-device virtio-scsi-pci,id=hw-$DISK_ID,iothread=io2,bus=pcie.0,addr=$DISK_ADDRESS \
-drive file=$DISK_FILE,if=none,id=drive-$DISK_ID,format=$DISK_FMT,cache=$DISK_CACHE,aio=$DISK_IO,discard=$DISK_DISCARD,detect-zeroes=on \
-device scsi-hd,bus=hw-$DISK_ID.0,channel=0,scsi-id=0,lun=0,drive=drive-$DISK_ID,id=$DISK_ID,rotation_rate=$DISK_ROTATION,bootindex=$DISK_INDEX"
@@ -276,6 +341,14 @@ addDisk () {
DISK_EXT="$(fmt2ext "$DISK_FMT")" || exit $?
if [[ "$ALLOCATE" == [Nn]* ]]; then
DISK_TYPE="growable"
DISK_ALLOC="preallocation=off"
else
DISK_TYPE="preallocated"
DISK_ALLOC="preallocation=falloc"
fi
DISK1_FILE="$STORAGE/data"
if [[ ! -f "$DISK1_FILE.img" ]] && [[ -f "$STORAGE/data${DISK_SIZE}.img" ]]; then
# Fallback for legacy installs
@@ -336,7 +409,7 @@ addDevice () {
[ ! -b "$DISK_DEV" ] && error "Device $DISK_DEV cannot be found! Please add it to the 'devices' section of your compose file." && exit 55
DISK_OPTS="$DISK_OPTS \
-device virtio-scsi-pci,id=hw-$DISK_ID,bus=pcie.0,addr=$DISK_ADDRESS \
-device virtio-scsi-pci,id=hw-$DISK_ID,iothread=io2,bus=pcie.0,addr=$DISK_ADDRESS \
-drive file=$DISK_DEV,if=none,id=drive-$DISK_ID,format=raw,cache=$DISK_CACHE,aio=$DISK_IO,discard=$DISK_DISCARD,detect-zeroes=on \
-device scsi-hd,bus=hw-$DISK_ID.0,channel=0,scsi-id=0,lun=0,drive=drive-$DISK_ID,id=$DISK_ID,rotation_rate=$DISK_ROTATION,bootindex=$DISK_INDEX"

View File

@@ -55,6 +55,13 @@ FS=$(stat -f -c %T "$STORAGE")
if [[ "$FS" == "overlay"* ]]; then
info "Warning: the filesystem of $STORAGE is OverlayFS, this usually means it was binded to an invalid path!"
fi
if [[ "$FS" == "btrfs"* ]]; then
FA=$(lsattr -d "$STORAGE")
if [[ "$FA" != *"C"* ]]; then
info "Warning: the filesystem of $STORAGE is BTRFS, and COW (copy on write) is not disabled for that folder!"
info "This will negatively affect write performance, please empty the folder and disable COW (chattr +C <path>)."
fi
fi
if [[ "$FS" != "fat"* && "$FS" != "vfat"* && "$FS" != "exfat"* && \
"$FS" != "ntfs"* && "$FS" != "fuse"* && "$FS" != "msdos"* ]]; then

View File

@@ -4,9 +4,9 @@ set -Eeuo pipefail
# Configure QEMU for graceful shutdown
QEMU_PORT=7100
QEMU_TIMEOUT=50
QEMU_PID=/run/qemu.pid
QEMU_COUNT=/run/qemu.count
QEMU_TIMEOUT=55
QEMU_PID="/run/qemu.pid"
QEMU_COUNT="/run/qemu.count"
rm -f "$QEMU_PID"
rm -f "$QEMU_COUNT"
@@ -52,21 +52,23 @@ _graceful_shutdown() {
while [ "$(cat $QEMU_COUNT)" -lt "$QEMU_TIMEOUT" ]; do
# Increase the counter
echo $(($(cat $QEMU_COUNT)+1)) > "$QEMU_COUNT"
# Try to connect to qemu
if echo 'info version'| nc -q 1 -w 1 localhost "$QEMU_PORT" >/dev/null 2>&1 ; then
sleep 1
cnt="$(cat $QEMU_COUNT)/$QEMU_TIMEOUT"
[[ "$DEBUG" == [Yy1]* ]] && info "Shutting down, waiting... ($cnt)"
if ! echo 'info version'| nc -q 1 -w 1 localhost "$QEMU_PORT" >/dev/null 2>&1 ; then
break
fi
# Increase the counter
cnt=$(($(cat $QEMU_COUNT)+1))
echo $cnt > "$QEMU_COUNT"
[[ "$DEBUG" == [Yy1]* ]] && info "Shutting down, waiting... ($cnt/$QEMU_TIMEOUT)"
done
if [ "$(cat $QEMU_COUNT)" -ge "$QEMU_TIMEOUT" ]; then
echo && error "Shutdown timeout reached, forcefully quitting.."
fi
echo && echo " Quitting..."
echo 'quit' | nc -q 1 -w 1 localhost "$QEMU_PORT" >/dev/null 2>&1 || true

View File

@@ -1,12 +1,15 @@
#!/usr/bin/env bash
set -Eeuo pipefail
: ${DHCP:='N'}
info () { printf "%b%s%b" "\E[1;34m \E[1;36m" "$1" "\E[0m\n" >&2; }
error () { printf "%b%s%b" "\E[1;31m " "ERROR: $1" "\E[0m\n" >&2; }
file="/run/dsm.url"
shutdown="/run/qemu.count"
url="http://127.0.0.1:2210/read?command=10"
resp_err="Guest returned an invalid response:"
jq_err="Failed to parse response from guest: jq error"
@@ -19,11 +22,9 @@ do
sleep 3
[ -f "$shutdown" ] && exit 1
# Healthcheck may have intervened
[ -f "$file" ] && break
# Retrieve IP from guest VM
# Retrieve network info from guest VM
{ json=$(curl -m 20 -sk "$url"); rc=$?; } || :
[ -f "$shutdown" ] && exit 1
@@ -46,7 +47,11 @@ do
{ ip=$(echo "$json" | jq -r '.data.data.ip.data[] | select((.name=="eth0") and has("ip")).ip'); rc=$?; } || :
(( rc != 0 )) && error "$jq_err $rc ( $json )" && continue
[[ "$ip" == "null" ]] && error "$resp_err $json" && continue
[ -z "$ip" ] && continue
if [ -z "$ip" ]; then
[[ "$DHCP" == [Yy1]* ]] && continue
ip="20.20.20.21"
fi
echo "$ip:$port" > $file

View File

@@ -43,6 +43,7 @@ rm -f /run/qemu.count
# Cleanup dirs
rm -rf /tmp/dsm
rm -f /tmp/server.*
rm -rf "$STORAGE/tmp"
# Helper functions