<commit_before>(*
 * Copyright (C) 2006-2009 Citrix Systems Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; version 2.1 only. with the special
 * exception on linking described in file LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *)
(* Synchronise the locally stored objects between the hosts in a pool *)

module D = Debug.Debugger(struct let name="sync" end)
open D

open Threadext

let sync_lock = Mutex.create ()

let sync_host ~__context host =
	Mutex.execute sync_lock (fun () ->
		try
			let localhost        = host = !Xapi_globs.localhost_ref
			and host_has_storage = not (List.mem_assoc Xapi_globs.host_no_local_storage (Db.Host.get_other_config ~__context ~self:host)) in

			if (not localhost) && host_has_storage then begin
				let address = Db.Host.get_address ~__context ~self:host in
				debug "Beginning sync with host at address: %s" address;

				let localpath  = Printf.sprintf "%s/" Xapi_globs.xapi_blob_location
				and remotepath = Printf.sprintf "%s:%s" address Xapi_globs.xapi_blob_location
				and session = Xapi_session.slave_login ~__context ~host:(Helpers.get_localhost ~__context) ~psecret:!Xapi_globs.pool_secret in
				Unix.putenv "XSH_SESSION" (Ref.string_of session);

				let env = Unix.environment () in
				let output,log = Forkhelpers.execute_command_get_output ~env "/usr/bin/rsync" ["--delete";"-avz";localpath;remotepath;"-e";"/opt/xensource/bin/xsh"] in
				debug "sync output: '%s' log: '%s'" output log;

				(* Store the last blob sync time in the Host.other_config *)
				(try Db.Host.remove_from_other_config ~__context ~self:host ~key:Xapi_globs.last_blob_sync_time with _ -> ());
				Db.Host.add_to_other_config ~__context ~self:host ~key:Xapi_globs.last_blob_sync_time ~value:(string_of_float (Unix.gettimeofday ()));
			end

			else begin
				debug "Ignoring host synchronise: localhost=%b host_has_storage=%b" localhost host_has_storage
			end;

		with Forkhelpers.Spawn_internal_error(log,output,status) ->
			(* Do we think the host is supposed to be online? *)
			let online =
				try
					let m = Db.Host.get_metrics ~__context ~self:host in
					Db.Host_metrics.get_live ~__context ~self:m
				with _ -> false in

			(* In rolling upgrade mode we would also expect a failure *)
			let rolling_upgrade = Helpers.rolling_upgrade_in_progress ~__context in
			if online && not rolling_upgrade
			then error "Unexpected failure synchronising blobs to host %s; log='%s'; output='%s'" (Ref.string_of host) log output;
	)
<commit_msg>CA-47663 The host blob sync logs 10s of thousands of log lines per iteration<commit_after>(*
 * Copyright (C) 2006-2009 Citrix Systems Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; version 2.1 only. with the special
 * exception on linking described in file LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *)
(* Synchronise the locally stored objects between the hosts in a pool *)

module D = Debug.Debugger(struct let name="sync" end)
open D

open Threadext

let sync_lock = Mutex.create ()

let sync_host ~__context host =
	Mutex.execute sync_lock (fun () ->
		try
			let localhost        = host = !Xapi_globs.localhost_ref
			and host_has_storage = not (List.mem_assoc Xapi_globs.host_no_local_storage (Db.Host.get_other_config ~__context ~self:host)) in

			if (not localhost) && host_has_storage then begin
				let address = Db.Host.get_address ~__context ~self:host in
				debug "Beginning sync with host at address: %s" address;

				let localpath  = Printf.sprintf "%s/" Xapi_globs.xapi_blob_location
				and remotepath = Printf.sprintf "%s:%s" address Xapi_globs.xapi_blob_location
				and session = Xapi_session.slave_login ~__context ~host:(Helpers.get_localhost ~__context) ~psecret:!Xapi_globs.pool_secret in
				Unix.putenv "XSH_SESSION" (Ref.string_of session);

				let output,log = Forkhelpers.execute_command_get_output
					~env:(Unix.environment ())
					"/usr/bin/rsync"
					["--delete";"--stats";"-az";localpath;remotepath;"-e";"/opt/xensource/bin/xsh"] in
				debug "sync output: \n%s" output;
				debug "log output: '%s'" log;

				(* Store the last blob sync time in the Host.other_config *)
				(try Db.Host.remove_from_other_config ~__context ~self:host ~key:Xapi_globs.last_blob_sync_time with _ -> ());
				Db.Host.add_to_other_config ~__context ~self:host ~key:Xapi_globs.last_blob_sync_time ~value:(string_of_float (Unix.gettimeofday ()));
			end

			else begin
				debug "Ignoring host synchronise: localhost=%b host_has_storage=%b" localhost host_has_storage
			end;

		with Forkhelpers.Spawn_internal_error(log,output,status) ->
			(* Do we think the host is supposed to be online? *)
			let online =
				try
					let m = Db.Host.get_metrics ~__context ~self:host in
					Db.Host_metrics.get_live ~__context ~self:m
				with _ -> false in

			(* In rolling upgrade mode we would also expect a failure *)
			let rolling_upgrade = Helpers.rolling_upgrade_in_progress ~__context in
			if online && not rolling_upgrade
			then error "Unexpected failure synchronising blobs to host %s; log='%s'; output='%s'" (Ref.string_of host) log output;
	)

{'fraction_non_alphanumeric': 0.09398756046993781, 'fraction_numerical': 0.0046648237733241185, 'mean_word_length': 4.187275985663082, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1744162', 'n_tokens_mistral': 2014, 'n_tokens_neox': 1790, 'n_words': 591}