1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-03 01:18:10 +03:00

ctdb-scripts: Improve update and listing code

Drop the complexity associated with using awk to escape dots in IPv4
addresses to protect them from sed, and generate a grep -F filter
instead.

For listing, the pipeline is now longer, but the steps are now
clearer:

1. List DB records
2. Extract keys
3. Keep only keys machine hosted public IPs
4. Parse out server IP and client IP
5. Sort

Performance here isn't critical, so having clearer code is preferable.

Use temporary files to avoid command-line length limits.

Also, drop the cd to the queue directory during update.

Signed-off-by: Martin Schwenke <mschwenke@ddn.com>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
This commit is contained in:
Martin Schwenke 2023-08-02 13:23:58 +10:00 committed by Amitay Isaacs
parent b8fe8a5fd2
commit e6a85d128f

View File

@ -172,6 +172,17 @@ ${CTDB_MY_PUBLIC_IPS_CACHE}
EOF EOF
} }
# Used via 'grep -F -f "$persistent_db_grep_filter"' to match database
# keys currently hosted public IPs
persistent_db_grep_filter="${statd_callout_state_dir}/.grep_filter"
persistent_db_make_grep_filter()
{
while read -r _ip; do
echo "statd-state@${_ip}@"
done <"$CTDB_MY_PUBLIC_IPS_CACHE" >"$persistent_db_grep_filter"
}
############################################################ ############################################################
case "$1" in case "$1" in
@ -180,25 +191,28 @@ startup)
;; ;;
update) update)
cd "$statd_callout_queue_dir" || files="${statd_callout_state_dir}/.file_list"
die "Failed to change directory to \"${statd_callout_queue_dir}\"" find "$statd_callout_queue_dir" -name "statd-state@*" >"$files"
files=$(echo statd-state@*) if [ ! -s "$files" ]; then
if [ "$files" = "statd-state@*" ]; then
# No files! # No files!
rm "$files"
exit 0 exit 0
fi fi
sed_expr=$(awk '{
ip = $1; gsub(/\./, "\\.", ip); persistent_db_make_grep_filter
printf "/statd-state@%s@/p\n", ip }' "$CTDB_MY_PUBLIC_IPS_CACHE")
# Intentional multi-word expansion for multiple files # Use cat instead of direct grep since POSIX grep does not
# shellcheck disable=SC2086 # have -h
items=$(sed -n "$sed_expr" $files) items="${statd_callout_state_dir}/.items"
if [ -n "$items" ]; then xargs cat <"$files" | grep -F -f "$persistent_db_grep_filter" >"$items"
if echo "$items" | $CTDB ptrans "$statd_callout_db"; then
# shellcheck disable=SC2086 if [ -s "$items" ]; then
rm $files if $CTDB ptrans "$statd_callout_db" <"$items"; then
xargs rm -f <"$files"
fi fi
fi fi
rm -f "$files" "$persistent_db_grep_filter" "$items"
;; ;;
notify) notify)
@ -222,21 +236,27 @@ notify)
sleep 2 sleep 2
"$CTDB_NFS_CALLOUT" "start" "nlockmgr" >/dev/null 2>&1 "$CTDB_NFS_CALLOUT" "start" "nlockmgr" >/dev/null 2>&1
# Construct a sed expression to take catdb output and produce pairs of: persistent_db_make_grep_filter
# server-IP client-IP
# but only for the server-IPs that are hosted on this node.
sed_expr=$(awk '{
ip = $1; gsub(/\./, "\\.", ip);
printf "s/^key.*=.*statd-state@\\(%s\\)@\\([^\"]*\\).*/\\1 \\2/p\n", ip }' \
"$CTDB_MY_PUBLIC_IPS_CACHE")
statd_state=$($CTDB catdb "$statd_callout_db" | # Produce "server-IP client-IP" per-line in .statd_state
sed -n "$sed_expr" | statd_state="${statd_callout_state_dir}/.statd_state"
sort) $CTDB catdb "$statd_callout_db" |
[ -n "$statd_state" ] || exit 0 sed -n -e 's|^key([0-9]*) = "\([^"]*\)".*|\1|p' |
grep -F -f "$persistent_db_grep_filter" |
sed -e 's|statd-state@\([^@]*\)@\(.*\)|\1 \2|' |
sort >"$statd_state"
echo "$statd_state" | send_notifies rm -f "$persistent_db_grep_filter"
echo "$statd_state" | delete_records
if [ ! -s "$statd_state" ]; then
rm -f "$statd_state"
exit 0
fi
send_notifies <"$statd_state"
delete_records <"$statd_state"
rm -f "$statd_state"
# Remove any stale touch files (i.e. for IPs not currently # Remove any stale touch files (i.e. for IPs not currently
# hosted on this node and created since the last "update"). # hosted on this node and created since the last "update").