Skip to content

Instantly share code, notes, and snippets.

@rledisez
Created June 28, 2017 07:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rledisez/f905dcca6be565da04ee12efdae8ad52 to your computer and use it in GitHub Desktop.
Save rledisez/f905dcca6be565da04ee12efdae8ad52 to your computer and use it in GitHub Desktop.
[object-reconstructor]
interval = 900
concurrency = 1
conn_timeout = 20
node_timeout = 180
http_timeout = 900
handoffs_first = false
sync_job_delay_after_part_move = 604800
commit 81a84ccf892f21938f504baaa4e4dbb3f4c5e0bf
Author: Romain LE DISEZ <romain.le-disez@corp.ovh.com>
Date: Mon Oct 17 15:08:03 2016 +0200
Force a reconstructor to run REVERT or SYNC only
By setting -r or -s the reconstructor now forces to treat only REVERT or SYNC
jobs. Also devices can now be specified in forever mode
diff --git a/bin/swift-object-reconstructor b/bin/swift-object-reconstructor
index ee4c5d64..70bfa85c 100755
--- a/bin/swift-object-reconstructor
+++ b/bin/swift-object-reconstructor
@@ -27,5 +27,11 @@ if __name__ == '__main__':
parser.add_option('-p', '--partitions',
help='Reconstruct only given partitions. '
'Comma-separated list')
+ parser.add_option('-r', '--revert-only',
+ default=False, action='store_true',
+ help='Run only REVERT jobs')
+ parser.add_option('-s', '--sync-only',
+ default=False, action='store_true',
+ help='Run only SYNC jobs')
conf_file, options = parse_options(parser=parser, once=True)
run_daemon(ObjectReconstructor, conf_file, **options)
diff --git a/swift/obj/reconstructor.py b/swift/obj/reconstructor.py
index 76d48890..6f8b3714 100644
--- a/swift/obj/reconstructor.py
+++ b/swift/obj/reconstructor.py
@@ -889,7 +889,8 @@ class ObjectReconstructor(Daemon):
return jobs
def collect_parts(self, override_devices=None,
- override_partitions=None):
+ override_partitions=None,
+ revert_only=False, sync_only=False):
"""
Helper for getting partitions in the top level reconstructor
"""
@@ -962,6 +963,13 @@ class ObjectReconstructor(Daemon):
if override_partitions and (partition not in
override_partitions):
continue
+ part_nodes = policy.object_ring.get_part_nodes(partition)
+ is_handoff = (local_dev['id'] not in
+ [n['id'] for n in part_nodes])
+ if revert_only ^ sync_only and \
+ not (sync_only and not is_handoff) and \
+ not (revert_only and is_handoff):
+ continue
part_info = {
'local_dev': local_dev,
'policy': policy,
@@ -1070,7 +1078,9 @@ class ObjectReconstructor(Daemon):
list_from_csv(kwargs.get('partitions'))]
self.reconstruct(
override_devices=override_devices,
- override_partitions=override_partitions)
+ override_partitions=override_partitions,
+ revert_only=kwargs.get('revert_only', False),
+ sync_only=kwargs.get('sync_only', False))
total = (time.time() - start) / 60
self.logger.info(
_("Object reconstruction complete (once). (%.02f minutes)"), total)
@@ -1086,7 +1096,9 @@ class ObjectReconstructor(Daemon):
start = time.time()
self.logger.info(_("Starting object reconstruction pass."))
# Run the reconstructor
- self.reconstruct()
+ self.reconstruct(override_devices=list_from_csv(kwargs.get('devices')),
+ revert_only=kwargs.get('revert_only', False),
+ sync_only=kwargs.get('sync_only', False))
total = (time.time() - start) / 60
self.logger.info(
_("Object reconstruction complete. (%.02f minutes)"), total)
#! /bin/sh
### BEGIN INIT INFO
# Provides: swift-object-reconstructor
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: OpenStack Object Storage (swift) - Object Reconstructor
# Description: OpenStack Object Storage (swift) - Object Reconstructor
### END INIT INFO
set -e
PATH=/sbin:/bin:/usr/sbin:/usr/bin
SERVICE_NAME="swift-object-reconstructor"
DAEMON="/opt/swift/bin/${SERVICE_NAME}"
DAEMON_ARGS="/etc/swift/object-server.conf"
PRINT_NAME="OpenStack Object Storage (swift) - Object Reconstructor"
SWIFT_USER=swift
SWIFT_GRP=swift
REVERT_ENABLED="true"
SYNC_ENABLED="true"
REVERT_DEVICES=""
SYNC_DEVICES=""
REVERT_GROUP_SIZE=1
SYNC_GROUP_SIZE=1
if ! [ -x "${DAEMON}" ] ; then
exit 0
fi
[ -r /etc/default/${SERVICE_NAME} ] && . /etc/default/${SERVICE_NAME}
if ! [ -r "${DAEMON_ARGS}" ] ; then
echo "No configuration file found in ${DAEMON_ARGS}: exiting"
exit 0
fi
. /lib/lsb/init-functions
#
# Return a list of devices in /srv/node, separated by space
# if present, arg1 define the number of devices to group together, separated
# by comma
# eg:
# get_devices
# disk-00-000 disk-00-001 disk-00-002 disk-00-003
#
# get_devices 2
# disk-00-000,disk-00-001 disk-00-002,disk-00-003
#
get_devices() {
if [ $# -gt 0 ]; then
GROUP_SIZE=$(( $1 - 1 ))
shift
else
GROUP_SIZE=0
fi
DEVICES=""
GROUP_COUNT=0
for DEVICE_PATH in /srv/node/*; do
[ ! -d "${DEVICE_PATH}" ] && continue
[[ "${DEVICE_PATH}" =~ ^/srv/node/(disk-[0-9][0-9]-[0-9][0-9][0-9])/?$ ]] || continue
if [ -z "${DEVICES}" ]; then
SEP=""
else
if [ $GROUP_COUNT -ge $GROUP_SIZE ]; then
SEP=" "
GROUP_COUNT="0"
else
SEP=","
GROUP_COUNT="$(( $GROUP_COUNT + 1))"
fi
fi
DEVICES="${DEVICES}${SEP}${BASH_REMATCH[1]}"
done
echo "${DEVICES}"
}
case "$1" in
start)
if [ "$REVERT_ENABLED" = "true" ] ; then
if [ -z "$REVERT_DEVICES" ]; then
REVERT_DEVICES="$(get_devices $REVERT_GROUP_SIZE)"
fi
for DEVICE in $REVERT_DEVICES; do
/usr/bin/pgrep -f "python $DAEMON .*-r .*-d +${DEVICE}( |$)" &> /dev/null && RET=$? || RET=$?
if [ $RET -ne 0 ]; then
log_daemon_msg "Starting ${PRINT_NAME}: ${DEVICE}" "${SERVICE_NAME}"
start-stop-daemon --start --chuid ${SWIFT_USER}:${SWIFT_GRP} -b --exec ${DAEMON} -- ${DAEMON_ARGS} -r -d "${DEVICE}"
log_end_msg $?
fi
done
fi
if [ "$SYNC_ENABLED" = "true" ] ; then
if [ -z "$SYNC_DEVICES" ]; then
SYNC_DEVICES="$(get_devices $SYNC_GROUP_SIZE)"
fi
for DEVICE in $SYNC_DEVICES; do
/usr/bin/pgrep -f "python $DAEMON .*-s .*-d +${DEVICE}( |$)" &> /dev/null && RET=$? || RET=$?
if [ $RET -ne 0 ]; then
log_daemon_msg "Starting ${PRINT_NAME}: ${DEVICE}" "${SERVICE_NAME}"
start-stop-daemon --start --chuid ${SWIFT_USER}:${SWIFT_GRP} -b --exec ${DAEMON} -- ${DAEMON_ARGS} -s -d "${DEVICE}"
log_end_msg $?
fi
done
fi
;;
stop)
log_daemon_msg "Stopping ${PRINT_NAME}" "${SERVICE_NAME}"
PATTERN="python $DAEMON( |$)"
/usr/bin/pkill -f "$PATTERN" || exit 0
# Wait 60 seconds, then kill -9
for i in {1..60}; do
/usr/bin/pgrep -f "$PATTERN" &> /dev/null || exit 0
/bin/sleep 1
done
/usr/bin/pkill --signal 9 -f "$PATTERN" || exit 0
log_end_msg $?
;;
restart|force-reload|reload)
$0 stop
sleep 1
$0 start
;;
status)
if [ "$REVERT_ENABLED" = "true" ] ; then
if [ -z "$REVERT_DEVICES" ]; then
REVERT_DEVICES="$(get_devices $REVERT_GROUP_SIZE)"
fi
for DEVICE in $REVERT_DEVICES; do
/usr/bin/pgrep -f "python $DAEMON .* -r .*-d +${DEVICE}( |$)" &> /dev/null || exit 1
done
fi
if [ "$SYNC_ENABLED" = "true" ] ; then
if [ -z "$SYNC_DEVICES" ]; then
SYNC_DEVICES="$(get_devices $SYNC_GROUP_SIZE)"
fi
for DEVICE in $SYNC_DEVICES; do
/usr/bin/pgrep -f "python $DAEMON .* -s .*-d +${DEVICE}( |$)" &> /dev/null || exit 1
done
fi
exit 0
;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
;;
esac
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment