PATH=/bin:/usr/bin:$PATH
-. /etc/ctdb/functions
+. $CTDB_BASE/functions
loadconfig ctdb
+loadconfig samba
+
+detect_init_style
+
+case $CTDB_INIT_STYLE in
+ suse)
+ CTDB_SERVICE_SMB="smb"
+ CTDB_SERVICE_NMB="nmb"
+ CTDB_SERVICE_WINBIND="winbind"
+ ;;
+ ubuntu)
+ CTDB_SERVICE_SMB="samba"
+ CTDB_SERVICE_NMB=""
+ CTDB_SERVICE_WINBIND="winbind"
+ ;;
+ redhat)
+ CTDB_SERVICE_SMB="smb"
+ CTDB_SERVICE_NMB=""
+ CTDB_SERVICE_WINBIND="winbind"
+ ;;
+ *)
+ # should not happen, but for now use redhat style as default:
+ CTDB_SERVICE_SMB="smb"
+ CTDB_SERVICE_NMB=""
+ CTDB_SERVICE_WINBIND="winbind"
+ ;;
+esac
cmd="$1"
shift
[ "$CTDB_MANAGES_SAMBA" = "yes" ] || exit 0
+# set default samba cleanup period - in minutes
+[ -z "$SAMBA_CLEANUP_PERIOD" ] && {
+ SAMBA_CLEANUP_PERIOD=10
+}
+
+# we keep a cached copy of smb.conf here
+smbconf_cache="$CTDB_BASE/state/samba/smb.conf.cache"
+
+
+#############################################
+# update the smb.conf cache in the foreground
+testparm_foreground_update() {
+ mkdir -p "$CTDB_BASE/state/samba" || exit 1
+ testparm -s 2> /dev/null | egrep -v 'registry.shares.=|include.=' > "$smbconf_cache"
+}
+
+#############################################
+# update the smb.conf cache in the background
+testparm_background_update() {
+ # if the cache doesn't exist, then update in the foreground
+ [ -f $smbconf_cache ] || {
+ testparm_foreground_update
+ }
+ # otherwise do a background update
+ (
+ tmpfile="${smbconf_cache}.$$"
+ testparm -s > $tmpfile 2> /dev/null &
+ # remember the pid of the teamparm process
+ pid="$!"
+ # give it 10 seconds to run
+ timeleft=10
+ while [ $timeleft -gt 0 ]; do
+ timeleft=$(($timeleft - 1))
+ # see if the process still exists
+ kill -0 $pid > /dev/null 2>&1 || {
+ # it doesn't exist, grab its exit status
+ wait $pid
+ [ $? = 0 ] || {
+ echo "50.samba: smb.conf background update exited with status $?"
+ rm -f "${tmpfile}"
+ exit 1
+ }
+ # put the new smb.conf contents in the cache (atomic rename)
+ # make sure we remove references to the registry while doing
+ # this to ensure that running testparm on the cache does
+ # not use the registry
+ egrep -v 'registry.shares.=|include.=' < "$tmpfile" > "${tmpfile}.2"
+ rm -f "$tmpfile"
+ mv -f "${tmpfile}.2" "$smbconf_cache" || {
+ echo "50.samba: failed to update background cache"
+ rm -f "${tmpfile}.2"
+ exit 1
+ }
+ exit 0
+ }
+ # keep waiting for testparm to finish
+ sleep 1
+ done
+ # it took more than 10 seconds - kill it off
+ rm -f "${tmpfile}"
+ kill -9 "$pid" > /dev/null 2>&1
+ echo "50.samba: timed out updating smbconf cache in background"
+ exit 1
+ ) &
+}
+
+##################################################
+# show the testparm output using a cached smb.conf
+# to avoid registry access
+testparm_cat() {
+ [ -f $smbconf_cache ] || {
+ testparm_foreground_update
+ }
+ testparm -s "$smbconf_cache" "$@" 2>/dev/null
+}
+
+# function to see if ctdb manages winbind
+check_ctdb_manages_winbind() {
+ [ -z "$CTDB_MANAGES_WINBIND" ] && {
+ secmode=`testparm_cat --parameter-name=security`
+ case $secmode in
+ ADS|DOMAIN)
+ CTDB_MANAGES_WINBIND="yes";
+ ;;
+ *)
+ CTDB_MANAGES_WINBIND="no";
+ ;;
+ esac
+ }
+}
+
+###########################
+# periodic cleanup function
+periodic_cleanup() {
+ # running smbstatus scrubs any dead entries from the connections
+ # and sessionid database
+ # echo "Running periodic cleanup of samba databases"
+ smbstatus -n > /dev/null 2>&1 &
+}
+
case $cmd in
startup)
- # wait for all shared directories to become available
- smb_dirs=`testparm -st 2> /dev/null | egrep '^\s*path = ' | cut -d= -f2`
- ctdb_wait_directories "Samba" $smb_dirs
+ # create the state directory for samba
+ /bin/mkdir -p $CTDB_BASE/state/samba
# make sure samba is not already started
- service smb stop > /dev/null 2>&1
- service winbind stop > /dev/null 2>&1
+ service "$CTDB_SERVICE_SMB" stop > /dev/null 2>&1
+ service "$CTDB_SERVICE_NMB" stop > /dev/null 2>&1
+ killall -0 -q smbd && {
+ sleep 1
+ # make absolutely sure samba is dead
+ killall -q -9 smbd
+ }
+
+ killall -0 -q nmbd && {
+ sleep 1
+ # make absolutely sure samba is dead
+ killall -q -9 nmbd
+ }
+
+ # restart the winbind service
+ check_ctdb_manages_winbind
+ [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
+ service "$CTDB_SERVICE_WINBIND" stop > /dev/null 2>&1
+ killall -0 -q winbindd && {
+ sleep 1
+ # make absolutely sure winbindd is dead
+ killall -q -9 winbindd
+ }
+ service "$CTDB_SERVICE_WINBIND" start
+ }
# start Samba service. Start it reniced, as under very heavy load
# the number of smbd processes will mean that it leaves few cycles for
# anything else
- nice service smb start
- service winbind start
-
- # wait for the Samba tcp ports to become available
- smb_ports=`testparm -stv 2> /dev/null | egrep '\s*smb ports =' | cut -d= -f2`
- ctdb_wait_tcp_ports "Samba" $smb_ports
+ nice_service "$CTDB_SERVICE_NMB" start
+ nice_service "$CTDB_SERVICE_SMB" start
;;
takeip)
shutdown)
# shutdown Samba when ctdb goes down
- service smb stop
- service winbind stop
+ service "$CTDB_SERVICE_SMB" stop
+ service "$CTDB_SERVICE_NMB" stop
+
+ # stop the winbind service
+ check_ctdb_manages_winbind
+ [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
+ service "$CTDB_SERVICE_WINBIND" stop
+ }
;;
+
+ monitor)
+ # Create a dummy file to track when we need to do periodic cleanup
+ # of samba databases
+ [ -f $CTDB_BASE/state/samba/periodic_cleanup ] || {
+ touch $CTDB_BASE/state/samba/periodic_cleanup
+ }
+ [ `/usr/bin/find $CTDB_BASE/state/samba/periodic_cleanup -mmin +$SAMBA_CLEANUP_PERIOD | wc -l` -eq 1 ] && {
+ # Cleanup the databases
+ periodic_cleanup
+ touch $CTDB_BASE/state/samba/periodic_cleanup
+ }
+
+ [ "$CTDB_SAMBA_SKIP_SHARE_CHECK" = "yes" ] || {
+ testparm_background_update
+
+ testparm_cat | egrep '^WARNING|^ERROR|^Unknown' && {
+ testparm_foreground_update
+ testparm_cat | egrep '^WARNING|^ERROR|^Unknown' && {
+ echo "ERROR: testparm shows smb.conf is not clean"
+ exit 1
+ }
+ }
+
+ smb_dirs=`testparm_cat | egrep '^[[:space:]]*path = ' | cut -d= -f2`
+ ctdb_check_directories_probe "Samba" $smb_dirs || {
+ testparm_foreground_update
+ smb_dirs=`testparm_cat | egrep '^[[:space:]]*path = ' | cut -d= -f2`
+ ctdb_check_directories "Samba" $smb_dirs
+ }
+ }
+
+ smb_ports="$CTDB_SAMBA_CHECK_PORTS"
+ [ -z "$smb_ports" ] && {
+ smb_ports=`testparm_cat --parameter-name="smb ports"`
+ }
+ ctdb_check_tcp_ports "Samba" $smb_ports
+
+ # check winbind is OK
+ check_ctdb_manages_winbind
+ [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
+ ctdb_check_command "winbind" "wbinfo -p"
+ }
+ ;;
+
esac
# ignore unknown commands