後処理スクリプトには、複写元ボリューム用(RepSrcPost.js)と複写先ボリューム用(RepDstPost.js)の2種類があり、それぞれのスクリプトは以下のディレクトリに格納されています。必要に応じて、カスタマイズしてください。
クラスタ運用でない場合
<環境設定ディレクトリ>\etc\repl\scriptsディレクトリクラスタ運用の場合
<共有ディスク>:\etc\opt\swstorage\etc\repl\scriptsディレクトリ複写元ボリューム用の後処理スクリプト(RepSrcPost.js)
1: // AdvancedCopy Manager for Windows
2: // All Rights Reserved, Copyright FUJITSU LIMITED, 2002-2006
3: //
4: // RepSrcPost.js: Post-Processing Script for Replication(Source)
5: //
6: // [Parameters]
7: // 1st argument: device name of source volume
8: //
9: // [Return Values]
10: // 0: The script ended normally.
11: // 2: The number of the arguments is incorrect.
12: // (1,3): unused, but must not be used because older versions use this value.
13: // 4: An error other than the above occurred.
14:
15: try {
16: // create global objects
17: var WshShell = WScript.CreateObject("WScript.Shell"); // create Shell object
18: var WshEnv = WshShell.Environment("PROCESS"); // create Environment object
19: var fsObj = WScript.CreateObject("Scripting.FileSystemObject"); // create FileSystemObject object
20:
21: // create SwstReplicationPostProc object
22: var proc = new SwstReplicationPostProc();
23:
24: // do nothing if postprocessing file exists
25: if (fsObj.FileExists(proc.postFileName) == false) {
26: SwstQuit(0);
27: }
28:
29: // get postprocessing type
30: var postProcType = proc.getPostProcData(proc.postFileName);
31: switch(postProcType) {
32: case "none":
33: proc.doNothing();
34: break;
35: }
36:
37: // clear temporary files
38: proc.deletePostFile(proc.postFileName);
39: SwstQuit(0);
40: } catch (e) {
41: SwstQuit(9);
42: }
43:
44: function SwstReplicationPostProc()
45: {
46: // member variables
47: this.svName = WScript.Arguments.length!=1?SwstQuit(1):WScript.Arguments.Item(0); // device name of source volume
48: this.postFileName = getDataPathName() + "\\" + getPutFileName(this.svName) + ".spre"; // name of postprocessing file
49:
50: // member functions
51: this.getPostProcData = getPostProcData; // self-explanatory
52: this.doNothing = doNothing; // self-explanatory
53: this.deletePostFile = deletePostFile; // self-explanatory
54: }
55:
56: function getPostProcData(postfile)
57: {
58: var iomode = 1; // means read-only mode
59: var create = false; // means not to create a file
60: var postFileStream = fsObj.OpenTextFile(postfile, iomode, create);
61: var postData = postFileStream.ReadLine();
62: postFileStream.Close();
63: return postData;
64: }
65:
66: function doNothing()
67: {
68: // do nothing
69: }
70:
71: function deletePostFile(postfile)
72: {
73: if (fsObj.FileExists(postfile) == true) {
74: fsObj.DeleteFile(postfile);
75: }
76: }
77:
78: function SwstQuit(exitStatus)
79: {
80: switch(exitStatus) {
81: case 0:
82: WScript.Quit(0);
83: case 1:
84: WScript.Echo("[Replication Postprocessing] The number of the arguments is incorrect.");
85: WScript.Quit(2);
86: default:
87: WScript.Echo("[Replication Postprocessing] The script exited abnormally.");
88: WScript.Quit(4);
89: }
90: }
91:
92: function getDataPathName()
93: {
94: return WshShell.RegRead(getSetupInfoKey() + "\\etcPathName") + "\\etc\\repl\\data\\DEFAULT";
95: }
96:
97: function getBinPathName()
98: {
99: return WshShell.RegRead(getSetupInfoKey() + "\\PathName") + "\\bin";
100: }
101:
102: function getSetupInfoKey()
103: {
104: var nodeName = WshEnv.Item("SWSTGNODE");
105: if( nodeName != "" ){
106: return "HKEY_LOCAL_MACHINE\\SOFTWARE\\Fujitsu\\AdvancedCopy Manager\\CurrentVersion\\" + nodeName;
107: }
108: return "HKEY_LOCAL_MACHINE\\SOFTWARE\\Fujitsu\\AdvancedCopy Manager\\CurrentVersion";
109: }
110:
111: function getPutFileName(deviceName){
112: var fileName;
113: if( isSafeDISKName(deviceName) ){
114: var re = /(\S+)\/(\S+):(\S+)/;
115: fileName = deviceName.replace(re, "$1_$2_$3");
116: }else{
117: fileName = deviceName;
118: }
119: return(fileName);
120: }
121:
122: function getGXDXPX(deviceName){
123: var gXdXpX;
124: if( isSafeDISKName(deviceName) ){
125: var re = /(\S+)\/(\S+):(\S+)/;
126: gXdXpX = deviceName.replace(re, "$3");
127: }else{
128: gXdXpX = deviceName;
129: }
130: return(gXdXpX);
131: }
132:
133: function isSafeDISKName(deviceName){
134: var key = ":g";
135: var s = deviceName.indexOf(key);
136: if ( s < 0 ) {
137: return (false);
138: } else {
139: return (true);
140: }
141: } |
複写先ボリューム用の後処理スクリプト(RepDstPost.js)
1: // AdvancedCopy Manager for Windows
2: // All Rights Reserved, Copyright FUJITSU LIMITED, 2002-2006
3: //
4: // RepDstPost.js: Post-Processing Script for Replication(Destination)
5: //
6: // [Parameters]
7: // 1st argument: device name of destination volume
8: //
9: // [Return Values]
10: // 0: The script ended normally.
11: // 2: The number of the arguments is incorrect.
12: // (1,3,5-7): unused, but must not be used because older versions use these values.
13: // 4: An error other than the above occurred.
14:
15: try {
16: // create global objects
17: var WshShell = WScript.CreateObject("WScript.Shell"); // create Shell object
18: var WshEnv = WshShell.Environment("PROCESS"); // create Environment object
19: var fsObj = WScript.CreateObject("Scripting.FileSystemObject"); // create FileSystemObject object
20:
21: // create SwstReplicationPostProc object
22: var proc = new SwstReplicationPostProc();
23:
24: // do nothing if postprocessing file exists
25: if (fsObj.FileExists(proc.postFileName) == false) {
26: SwstQuit(0);
27: }
28:
29: // get postprocessing type
30: var postProcType = proc.getPostProcData(proc.postFileName);
31: switch(postProcType) {
32: case "none":
33: proc.doNothing();
34: break;
35: }
36:
37: // clear temporary files
38: proc.deletePostFile(proc.postFileName);
39: SwstQuit(0);
40: } catch (e) {
41: SwstQuit(9);
42: }
43:
44: function SwstReplicationPostProc()
45: {
46: // member variables
47: this.dvName = WScript.Arguments.length!=1?SwstQuit(1):WScript.Arguments.Item(0); // device name of destination volume
48: this.postFileName = getDataPathName() + "\\" + getPutFileName(this.dvName) + ".dpre"; // name of postprocessing file
49:
50: // member functions
51: this.getPostProcData = getPostProcData; // self-explanatory
52: this.doNothing = doNothing; // self-explanatory
53: this.deletePostFile = deletePostFile; // self-explanatory
54: }
55:
56: function getPostProcData(postfile)
57: {
58: var iomode = 1; // means read-only mode
59: var create = false; // means not to create a file
60: var postFileStream = fsObj.OpenTextFile(postfile, iomode, create);
61: var postData = postFileStream.ReadLine();
62: postFileStream.Close();
63: return postData;
64: }
65:
66: function doNothing()
67: {
68: // do nothing
69: }
70:
71: function deletePostFile(postfile)
72: {
73: if (fsObj.FileExists(postfile) == true) {
74: fsObj.DeleteFile(postfile);
75: }
76: }
77:
78: function SwstQuit(exitStatus)
79: {
80: switch(exitStatus) {
81: case 0:
82: WScript.Quit(0);
83: case 1:
84: WScript.Echo("[Replication Postprocessing] The number of the arguments is incorrect.");
85: WScript.Quit(2);
86: default:
87: WScript.Echo("[Replication Postprocessing] The script exited abnormally.");
88: WScript.Quit(4);
89: }
90: }
91:
92: function getDataPathName()
93: {
94: return WshShell.RegRead(getSetupInfoKey() + "\\etcPathName") + "\\etc\\repl\\data\\DEFAULT";
95: }
96:
97: function getBinPathName()
98: {
99: return WshShell.RegRead(getSetupInfoKey() + "\\PathName") + "\\bin";
100: }
101:
102: function getSetupInfoKey()
103: {
104: var nodeName = WshEnv.Item("SWSTGNODE");
105: if( nodeName != "" ){
106: return "HKEY_LOCAL_MACHINE\\SOFTWARE\\Fujitsu\\AdvancedCopy Manager\\CurrentVersion\\" + nodeName;
107: }
108: return "HKEY_LOCAL_MACHINE\\SOFTWARE\\Fujitsu\\AdvancedCopy Manager\\CurrentVersion";
109: }
110:
111: function getPutFileName(deviceName){
112: var fileName;
113: if( isSafeDISKName(deviceName) ){
114: var re = /(\S+)\/(\S+):(\S+)/;
115: fileName = deviceName.replace(re, "$1_$2_$3");
116: }else{
117: fileName = deviceName;
118: }
119: return(fileName);
120: }
121:
122: function getGXDXPX(deviceName){
123: var gXdXpX;
124: if( isSafeDISKName(deviceName) ){
125: var re = /(\S+)\/(\S+):(\S+)/;
126: gXdXpX = deviceName.replace(re, "$3");
127: }else{
128: gXdXpX = deviceName;
129: }
130: return(gXdXpX);
131: }
132:
133: function isSafeDISKName(deviceName){
134: var key = ":g";
135: var s = deviceName.indexOf(key);
136: if ( s < 0 ) {
137: return (false);
138: } else {
139: return (true);
140: }
141: } |
ポイント
ボリュームのロック/ロック解除およびバッファーのフラッシュは、スクリプトではなく、コマンド内で実施されています。したがって、複写元前後処理スクリプトおよび複写先前後処理スクリプトは、複写元/複写先ボリュームのロック/ロック解除およびバッファーのフラッシュ処理の直前、直後にそれぞれ実行されます。複写元/複写先前後処理スクリプトでは、実質的に何も処理していません。
図C.3 スナップショット型レプリケーション(OPC)の場合

図C.4 同期型レプリケーション(EC)の場合(1):複写先ボリュームがクラスタシステムの共用ボリュームでない場合

図C.5 同期型レプリケーション(EC)の場合(2):複写先ボリュームがクラスタシステムの共用ボリュームの場合

注意
複写元/複写先ボリュームのレプリケーション前処理では、ほかのアプリケーションとの一時的なアクセス競合を回避するため、ロックに失敗した場合にロック処理をリトライします。既定のリトライ回数を超えた場合、コマンドは異常終了します。この場合、複写元/複写先ボリュームを使用しているプロセスが存在しているため、アプリケーションやサービスを停止するなどの対処を実施し、ほかのプロセスがボリュームを使用していない状態にしてください。リトライ回数は、「C.2.4 複写元ボリュームロック動作指定ファイル」、「C.2.5 複写先ボリュームロック動作指定ファイル」で変更できます。
なお、レプリケーション処理実行時にほかのプロセスが処理対象ボリュームを使用しないための対策が適切に行われている場合、通常、これらのファイルは作成不要です。
同期型レプリケーション(EC)かつコピー先ボリュームがクラスタシステムの共用ボリュームの場合、クラスタシステムの監視を回避するため、コピー先ボリュームのロック保持期間はswsrpstartsyncコマンドおよびswsrpmakeコマンドの動作中だけとなります(上図参照)。すなわち、swsrpstartsyncコマンド実行後からswsrpmakeコマンド実行前まで、コピー先ボリュームはロックされません。このため、「15.1.1.14 イベントビューアーに出力されるメッセージについて」に記載されているメッセージがイベントログに出力されることがありますが、問題はないので無視してください。