Serialize rule writes and add tests
This commit is contained in:
@@ -172,7 +172,7 @@ cmd_list() {
|
||||
fi
|
||||
}
|
||||
|
||||
cmd_add_batch() {
|
||||
_cmd_add_batch_locked() {
|
||||
local proto=${1-}
|
||||
local lport=${2-}
|
||||
local tip=${3-}
|
||||
@@ -191,14 +191,14 @@ cmd_add_batch() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! storage_add "${line}"; then
|
||||
if ! storage_add_unlocked "${line}"; then
|
||||
ipt_remove_rule "${uuid}" "${proto}" "${lport}" "${tip}" "${tport}" "${ipver}" >/dev/null 2>&1 || true
|
||||
log_err '写入规则数据库失败。'
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! persist_save; then
|
||||
storage_delete "${uuid}" >/dev/null 2>&1 || true
|
||||
storage_delete_unlocked "${uuid}" >/dev/null 2>&1 || true
|
||||
ipt_remove_rule "${uuid}" "${proto}" "${lport}" "${tip}" "${tport}" "${ipver}" >/dev/null 2>&1 || true
|
||||
log_err '保存持久化规则失败,已回滚。'
|
||||
return 1
|
||||
@@ -208,6 +208,10 @@ cmd_add_batch() {
|
||||
printf '%s\n' "${uuid}"
|
||||
}
|
||||
|
||||
cmd_add_batch() {
|
||||
storage_with_lock _cmd_add_batch_locked "$@"
|
||||
}
|
||||
|
||||
cmd_add() {
|
||||
local proto_choice ipver_choice proto ipver lport tip tport desc
|
||||
|
||||
@@ -264,7 +268,7 @@ cmd_add() {
|
||||
cmd_add_batch "${proto}" "${lport}" "${tip}" "${tport}" "${ipver}" "${desc}" >/dev/null
|
||||
}
|
||||
|
||||
cmd_delete_uuid() {
|
||||
_cmd_delete_uuid_locked() {
|
||||
local uuid=${1-}
|
||||
local line proto lport tip tport ipver
|
||||
line=$(storage_get "${uuid}") || {
|
||||
@@ -283,13 +287,14 @@ cmd_delete_uuid() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! storage_delete "${uuid}"; then
|
||||
log_err '删除规则数据库记录失败。'
|
||||
if ! storage_delete_unlocked "${uuid}"; then
|
||||
ipt_apply_rule "${uuid}" "${proto}" "${lport}" "${tip}" "${tport}" "${ipver}" >/dev/null 2>&1 || true
|
||||
log_err '删除规则数据库记录失败,已尝试回滚。'
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! persist_save; then
|
||||
storage_add "${line}" >/dev/null 2>&1 || true
|
||||
storage_add_unlocked "${line}" >/dev/null 2>&1 || true
|
||||
ipt_apply_rule "${uuid}" "${proto}" "${lport}" "${tip}" "${tport}" "${ipver}" >/dev/null 2>&1 || true
|
||||
log_err '持久化保存失败,已尝试回滚。'
|
||||
return 1
|
||||
@@ -298,6 +303,10 @@ cmd_delete_uuid() {
|
||||
log_ok "规则 ${uuid} 已删除。"
|
||||
}
|
||||
|
||||
cmd_delete_uuid() {
|
||||
storage_with_lock _cmd_delete_uuid_locked "$@"
|
||||
}
|
||||
|
||||
cmd_delete() {
|
||||
local index answer line uuid
|
||||
rules_load_lines
|
||||
@@ -348,7 +357,7 @@ cmd_show_env_status() {
|
||||
pause_return
|
||||
}
|
||||
|
||||
cmd_save_rules() {
|
||||
_cmd_save_rules_locked() {
|
||||
if persist_save; then
|
||||
log_ok '规则已保存到磁盘。'
|
||||
else
|
||||
@@ -356,3 +365,7 @@ cmd_save_rules() {
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
cmd_save_rules() {
|
||||
storage_with_lock _cmd_save_rules_locked
|
||||
}
|
||||
|
||||
@@ -34,20 +34,30 @@ storage_init() {
|
||||
chmod 600 "${lock}"
|
||||
}
|
||||
|
||||
storage_add() {
|
||||
local line=${1-}
|
||||
local db lock
|
||||
[[ -n ${line} ]] || return 1
|
||||
storage_with_lock() {
|
||||
local lock
|
||||
storage_init
|
||||
db=$(storage_db_path)
|
||||
lock=$(storage_lock_path)
|
||||
|
||||
(
|
||||
flock -x 9
|
||||
printf '%s\n' "${line}" >>"${db}"
|
||||
"$@"
|
||||
) 9>>"${lock}"
|
||||
}
|
||||
|
||||
storage_add_unlocked() {
|
||||
local line=${1-}
|
||||
local db
|
||||
[[ -n ${line} ]] || return 1
|
||||
storage_init
|
||||
db=$(storage_db_path)
|
||||
printf '%s\n' "${line}" >>"${db}"
|
||||
}
|
||||
|
||||
storage_add() {
|
||||
storage_with_lock storage_add_unlocked "$@"
|
||||
}
|
||||
|
||||
storage_list() {
|
||||
local db
|
||||
db=$(storage_db_path)
|
||||
@@ -83,34 +93,34 @@ storage_get() {
|
||||
return 1
|
||||
}
|
||||
|
||||
storage_delete() {
|
||||
storage_delete_unlocked() {
|
||||
local uuid=${1-}
|
||||
local db lock tmp found=0 line current
|
||||
local db tmp found=0 line current
|
||||
[[ -n ${uuid} ]] || return 1
|
||||
storage_init
|
||||
db=$(storage_db_path)
|
||||
lock=$(storage_lock_path)
|
||||
tmp="${db}.tmp.$$"
|
||||
|
||||
(
|
||||
flock -x 9
|
||||
: >"${tmp}"
|
||||
while IFS= read -r line || [[ -n ${line} ]]; do
|
||||
current=$(storage_parse "${line}" uuid || true)
|
||||
if [[ ${current} == "${uuid}" ]]; then
|
||||
found=1
|
||||
continue
|
||||
fi
|
||||
printf '%s\n' "${line}" >>"${tmp}"
|
||||
done <"${db}"
|
||||
|
||||
if (( found == 0 )); then
|
||||
rm -f "${tmp}"
|
||||
exit 1
|
||||
: >"${tmp}"
|
||||
while IFS= read -r line || [[ -n ${line} ]]; do
|
||||
current=$(storage_parse "${line}" uuid || true)
|
||||
if [[ ${current} == "${uuid}" ]]; then
|
||||
found=1
|
||||
continue
|
||||
fi
|
||||
printf '%s\n' "${line}" >>"${tmp}"
|
||||
done <"${db}"
|
||||
|
||||
mv "${tmp}" "${db}"
|
||||
) 9>>"${lock}"
|
||||
if (( found == 0 )); then
|
||||
rm -f "${tmp}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
mv "${tmp}" "${db}"
|
||||
}
|
||||
|
||||
storage_delete() {
|
||||
storage_with_lock storage_delete_unlocked "$@"
|
||||
}
|
||||
|
||||
storage_count() {
|
||||
|
||||
Reference in New Issue
Block a user