[Xorp-hackers] Re: process auto restart

Ray Qiu Ray Qiu <ray.qiu@gmail.com>
Tue, 17 Aug 2004 05:10:42 +0000


------=_Part_104_28907956.1092719442843
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Hi,

I made a patch for process auto-restart.  It kinda of works.  fea
restart is not
supported.  I want to post it here, so you guys can provide comments
and better ideas.

My idea is that if some critical processes can not support restart,
the whole XORP
stack should be restarted (e.g. killed and brought back by init) upon
their failures.

Thanks.

--Ray

Index: bgp/process_watch.cc
===================================================================
RCS file: /cvs/xorp/bgp/process_watch.cc,v
retrieving revision 1.13
diff -r1.13 process_watch.cc
80c80
< 	::exit(-1);
---
> 	//::exit(-1);
83,84c83,84
< 	start_kill_timer();
< 	_shutdown->dispatch();
---
> 	//start_kill_timer();
> 	//_shutdown->dispatch();
Index: rtrmgr/Makefile.am
===================================================================
RCS file: /cvs/xorp/rtrmgr/Makefile.am,v
retrieving revision 1.28
diff -r1.28 Makefile.am
180a181
> test_templates_SOURCES	+= master_conf_tree.cc
254a256
> test_module_manager_SOURCES	+= master_conf_tree.hh
268a271
> test_module_manager_SOURCES	+= master_conf_tree.cc
269a273
> test_module_manager_SOURCES	+= master_conf_tree.cc
Index: rtrmgr/Makefile.in
===================================================================
RCS file: /cvs/xorp/rtrmgr/Makefile.in,v
retrieving revision 1.39
diff -r1.39 Makefile.in
170c170
< 	module_command.$(OBJEXT) module_manager.$(OBJEXT) \
---
> 	module_command.$(OBJEXT) module_manager.$(OBJEXT) master_conf_tree.$(OBJEXT) \
200c200
< 	task.$(OBJEXT) template_commands.$(OBJEXT) \
---
> 	task.$(OBJEXT) template_commands.$(OBJEXT) master_conf_tree.$(OBJEXT) \
Index: rtrmgr/conf_tree_node.cc
===================================================================
RCS file: /cvs/xorp/rtrmgr/conf_tree_node.cc,v
retrieving revision 1.50
diff -r1.50 conf_tree_node.cc
17d16
< 
1104a1104,1117
> ConfigTreeNode::mark_subtree_as_uncommitted()
> {
>     _existence_committed = false;
>     _value_committed = false;
> 
>     list<ConfigTreeNode*>::iterator iter;
>     iter = _children.begin();
>     while (iter != _children.end()) {
> 	(*iter)->mark_subtree_as_uncommitted();
> 	++iter;
>     }
> }
> 
> void
Index: rtrmgr/conf_tree_node.hh
===================================================================
RCS file: /cvs/xorp/rtrmgr/conf_tree_node.hh,v
retrieving revision 1.24
diff -r1.24 conf_tree_node.hh
52a53
>     void mark_subtree_as_uncommitted();
Index: rtrmgr/main_rtrmgr.cc
===================================================================
RCS file: /cvs/xorp/rtrmgr/main_rtrmgr.cc,v
retrieving revision 1.50
diff -r1.50 main_rtrmgr.cc
16a17,19
> //#define DEBUG_LOGGING
> //#define DEBUG_PRINT_FUNCTION_NAME
> 
263d265
< 
273a276
> 	mmgr.set_conf_tree(_mct);
Index: rtrmgr/module_manager.cc
===================================================================
RCS file: /cvs/xorp/rtrmgr/module_manager.cc,v
retrieving revision 1.32
diff -r1.32 module_manager.cc
16a17,19
> //#define DEBUG_LOGGING
> //#define DEBUG_PRINT_FUNCTION_NAME
> 
35a39,40
> #include "master_conf_tree.hh"
> #include "conf_tree_node.hh"
86,88c91,122
< 	    }
< 	}
< 	module_pids.erase(pid_iter);
---
> 		// Restart the module because it exited abnormally. 
> 	        // It probably crashed.
> 		//
> 	        if (module->status() == Module::MODULE_FAILED) {
> 		    if ((!strcmp(module->name().c_str(), "fea")) || (!strcmp(module->name().c_str(), "interfaces"))) {
> 		        XLOG_ERROR("Fatal error: fea died, exit XORP.\n");
> 		        kill(getpid(), SIGTERM);
> 		        return;
> 		    }
> 	            XLOG_INFO("Restarting module %s ...\n", module->name().c_str());
> 	            XorpCallback1<void, bool>::RefPtr run_cb 
> 		        = callback(module, &Module::module_run_done);
> 	            if (module->run(true, run_cb) < 0) {
> 		        XLOG_ERROR("Failed to restart module %s.\n", module->name().c_str());
> 	            }    	
> 		    else {
> 		        XLOG_INFO("Module %s is successfully restarted.\n",
> 			    module->name().c_str());
> 	            }
> 		    MasterConfigTree* mct;
> 		    ConfigTreeNode* ctn;
> 		    mct = module->module_manager().get_conf_tree();
> 		    (const ConfigTreeNode*) ctn = mct->find_config_module(module->name());
> 		    if (ctn != NULL){
> 		        XLOG_INFO("Configure module %s.\n", module->name().c_str());
> 		        ctn->mark_subtree_as_uncommitted();
> 		        mct->execute();
> 		    }
> 		}
>             }
> 	    module_pids.erase(pid_iter);
> 	}	
106a141,166
> 	    if (module->status() == Module::MODULE_FAILED) {
> 	        // fea restart is not supported.
> 		if ((!strcmp(module->name().c_str(), "fea")) || (!strcmp(module->name().c_str(), "interfaces"))) {
> 		    XLOG_ERROR("Fatal error: fea died, exit XORP.\n");
> 		    kill(getpid(), SIGTERM);
> 		    return;
> 		}
> 	        XLOG_INFO("Restarting module %s ...\n", module->name().c_str());
> 	        XorpCallback1<void, bool>::RefPtr run_cb 
> 		    = callback(module, &Module::module_run_done);
> 	        if (module->run(true, run_cb) < 0) {
> 		    XLOG_ERROR("Failed to restart module %s.\n", module->name().c_str());
> 	        }    	
> 		else {
> 		    XLOG_INFO("Module %s is successfully restarted.\n", module->name().c_str());
> 	        }
> 		MasterConfigTree* mct;
> 		ConfigTreeNode* ctn;
> 		mct = module->module_manager().get_conf_tree();
> 		(const ConfigTreeNode*) ctn = mct->find_config_module(module->name());
> 		if (ctn != NULL){
> 		    XLOG_INFO("Configure module %s.\n", module->name().c_str());
> 		    ctn->mark_subtree_as_uncommitted();
> 		    mct->execute();
> 		}
> 	    }
357c417
< 
---
>     
535c595,596
<       _xorp_root_dir(xorp_root_dir)
---
>       _xorp_root_dir(xorp_root_dir),
>       _master_conf_tree(NULL)
Index: rtrmgr/module_manager.hh
===================================================================
RCS file: /cvs/xorp/rtrmgr/module_manager.hh,v
retrieving revision 1.22
diff -r1.22 module_manager.hh
27d26
< 
29a29,30
> class MasterConfigTree;
> 
35a37
> 
77a80,81
>     ModuleManager& module_manager() const { return _mmgr; }
>     string const name() { return _name; }
95a100
> 
138c143,145
< 
---
>     void set_conf_tree(MasterConfigTree* v) { _master_conf_tree = v; }
>     MasterConfigTree* get_conf_tree() const { return _master_conf_tree; }
>     
146a154
>     MasterConfigTree*	_master_conf_tree;

------=_Part_104_28907956.1092719442843
Content-Type: application/octet-stream; name="rtrmgr-patch"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="rtrmgr-patch"

SW5kZXg6IGJncC9wcm9jZXNzX3dhdGNoLmNjCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KUkNTIGZpbGU6IC9jdnMveG9y
cC9iZ3AvcHJvY2Vzc193YXRjaC5jYyx2CnJldHJpZXZpbmcgcmV2aXNpb24gMS4xMwpkaWZmIC1y
MS4xMyBwcm9jZXNzX3dhdGNoLmNjCjgwYzgwCjwgCTo6ZXhpdCgtMSk7Ci0tLQo+IAkvLzo6ZXhp
dCgtMSk7CjgzLDg0YzgzLDg0CjwgCXN0YXJ0X2tpbGxfdGltZXIoKTsKPCAJX3NodXRkb3duLT5k
aXNwYXRjaCgpOwotLS0KPiAJLy9zdGFydF9raWxsX3RpbWVyKCk7Cj4gCS8vX3NodXRkb3duLT5k
aXNwYXRjaCgpOwpJbmRleDogcnRybWdyL01ha2VmaWxlLmFtCj09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KUkNTIGZpbGU6
IC9jdnMveG9ycC9ydHJtZ3IvTWFrZWZpbGUuYW0sdgpyZXRyaWV2aW5nIHJldmlzaW9uIDEuMjgK
ZGlmZiAtcjEuMjggTWFrZWZpbGUuYW0KMTgwYTE4MQo+IHRlc3RfdGVtcGxhdGVzX1NPVVJDRVMJ
Kz0gbWFzdGVyX2NvbmZfdHJlZS5jYwoyNTRhMjU2Cj4gdGVzdF9tb2R1bGVfbWFuYWdlcl9TT1VS
Q0VTCSs9IG1hc3Rlcl9jb25mX3RyZWUuaGgKMjY4YTI3MQo+IHRlc3RfbW9kdWxlX21hbmFnZXJf
U09VUkNFUwkrPSBtYXN0ZXJfY29uZl90cmVlLmNjCjI2OWEyNzMKPiB0ZXN0X21vZHVsZV9tYW5h
Z2VyX1NPVVJDRVMJKz0gbWFzdGVyX2NvbmZfdHJlZS5jYwpJbmRleDogcnRybWdyL01ha2VmaWxl
LmluCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT0KUkNTIGZpbGU6IC9jdnMveG9ycC9ydHJtZ3IvTWFrZWZpbGUuaW4sdgpy
ZXRyaWV2aW5nIHJldmlzaW9uIDEuMzkKZGlmZiAtcjEuMzkgTWFrZWZpbGUuaW4KMTcwYzE3MAo8
IAltb2R1bGVfY29tbWFuZC4kKE9CSkVYVCkgbW9kdWxlX21hbmFnZXIuJChPQkpFWFQpIFwKLS0t
Cj4gCW1vZHVsZV9jb21tYW5kLiQoT0JKRVhUKSBtb2R1bGVfbWFuYWdlci4kKE9CSkVYVCkgbWFz
dGVyX2NvbmZfdHJlZS4kKE9CSkVYVCkgXAoyMDBjMjAwCjwgCXRhc2suJChPQkpFWFQpIHRlbXBs
YXRlX2NvbW1hbmRzLiQoT0JKRVhUKSBcCi0tLQo+IAl0YXNrLiQoT0JKRVhUKSB0ZW1wbGF0ZV9j
b21tYW5kcy4kKE9CSkVYVCkgbWFzdGVyX2NvbmZfdHJlZS4kKE9CSkVYVCkgXApJbmRleDogcnRy
bWdyL2NvbmZfdHJlZV9ub2RlLmNjCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KUkNTIGZpbGU6IC9jdnMveG9ycC9ydHJt
Z3IvY29uZl90cmVlX25vZGUuY2MsdgpyZXRyaWV2aW5nIHJldmlzaW9uIDEuNTAKZGlmZiAtcjEu
NTAgY29uZl90cmVlX25vZGUuY2MKMTdkMTYKPCAKMTEwNGExMTA0LDExMTcKPiBDb25maWdUcmVl
Tm9kZTo6bWFya19zdWJ0cmVlX2FzX3VuY29tbWl0dGVkKCkKPiB7Cj4gICAgIF9leGlzdGVuY2Vf
Y29tbWl0dGVkID0gZmFsc2U7Cj4gICAgIF92YWx1ZV9jb21taXR0ZWQgPSBmYWxzZTsKPiAKPiAg
ICAgbGlzdDxDb25maWdUcmVlTm9kZSo+OjppdGVyYXRvciBpdGVyOwo+ICAgICBpdGVyID0gX2No
aWxkcmVuLmJlZ2luKCk7Cj4gICAgIHdoaWxlIChpdGVyICE9IF9jaGlsZHJlbi5lbmQoKSkgewo+
IAkoKml0ZXIpLT5tYXJrX3N1YnRyZWVfYXNfdW5jb21taXR0ZWQoKTsKPiAJKytpdGVyOwo+ICAg
ICB9Cj4gfQo+IAo+IHZvaWQKSW5kZXg6IHJ0cm1nci9jb25mX3RyZWVfbm9kZS5oaAo9PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09ClJDUyBmaWxlOiAvY3ZzL3hvcnAvcnRybWdyL2NvbmZfdHJlZV9ub2RlLmhoLHYKcmV0cmll
dmluZyByZXZpc2lvbiAxLjI0CmRpZmYgLXIxLjI0IGNvbmZfdHJlZV9ub2RlLmhoCjUyYTUzCj4g
ICAgIHZvaWQgbWFya19zdWJ0cmVlX2FzX3VuY29tbWl0dGVkKCk7CkluZGV4OiBydHJtZ3IvbWFp
bl9ydHJtZ3IuY2MKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PQpSQ1MgZmlsZTogL2N2cy94b3JwL3J0cm1nci9tYWluX3J0
cm1nci5jYyx2CnJldHJpZXZpbmcgcmV2aXNpb24gMS41MApkaWZmIC1yMS41MCBtYWluX3J0cm1n
ci5jYwoxNmExNywxOQo+IC8vI2RlZmluZSBERUJVR19MT0dHSU5HCj4gLy8jZGVmaW5lIERFQlVH
X1BSSU5UX0ZVTkNUSU9OX05BTUUKPiAKMjYzZDI2NQo8IAoyNzNhMjc2Cj4gCW1tZ3Iuc2V0X2Nv
bmZfdHJlZShfbWN0KTsKSW5kZXg6IHJ0cm1nci9tb2R1bGVfbWFuYWdlci5jYwo9PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
ClJDUyBmaWxlOiAvY3ZzL3hvcnAvcnRybWdyL21vZHVsZV9tYW5hZ2VyLmNjLHYKcmV0cmlldmlu
ZyByZXZpc2lvbiAxLjMyCmRpZmYgLXIxLjMyIG1vZHVsZV9tYW5hZ2VyLmNjCjE2YTE3LDE5Cj4g
Ly8jZGVmaW5lIERFQlVHX0xPR0dJTkcKPiAvLyNkZWZpbmUgREVCVUdfUFJJTlRfRlVOQ1RJT05f
TkFNRQo+IAozNWEzOSw0MAo+ICNpbmNsdWRlICJtYXN0ZXJfY29uZl90cmVlLmhoIgo+ICNpbmNs
dWRlICJjb25mX3RyZWVfbm9kZS5oaCIKODYsODhjOTEsMTIyCjwgCSAgICB9CjwgCX0KPCAJbW9k
dWxlX3BpZHMuZXJhc2UocGlkX2l0ZXIpOwotLS0KPiAJCS8vIFJlc3RhcnQgdGhlIG1vZHVsZSBi
ZWNhdXNlIGl0IGV4aXRlZCBhYm5vcm1hbGx5LiAKPiAJICAgICAgICAvLyBJdCBwcm9iYWJseSBj
cmFzaGVkLgo+IAkJLy8KPiAJICAgICAgICBpZiAobW9kdWxlLT5zdGF0dXMoKSA9PSBNb2R1bGU6
Ok1PRFVMRV9GQUlMRUQpIHsKPiAJCSAgICBpZiAoKCFzdHJjbXAobW9kdWxlLT5uYW1lKCkuY19z
dHIoKSwgImZlYSIpKSB8fCAoIXN0cmNtcChtb2R1bGUtPm5hbWUoKS5jX3N0cigpLCAiaW50ZXJm
YWNlcyIpKSkgewo+IAkJICAgICAgICBYTE9HX0VSUk9SKCJGYXRhbCBlcnJvcjogZmVhIGRpZWQs
IGV4aXQgWE9SUC5cbiIpOwo+IAkJICAgICAgICBraWxsKGdldHBpZCgpLCBTSUdURVJNKTsKPiAJ
CSAgICAgICAgcmV0dXJuOwo+IAkJICAgIH0KPiAJICAgICAgICAgICAgWExPR19JTkZPKCJSZXN0
YXJ0aW5nIG1vZHVsZSAlcyAuLi5cbiIsIG1vZHVsZS0+bmFtZSgpLmNfc3RyKCkpOwo+IAkgICAg
ICAgICAgICBYb3JwQ2FsbGJhY2sxPHZvaWQsIGJvb2w+OjpSZWZQdHIgcnVuX2NiIAo+IAkJICAg
ICAgICA9IGNhbGxiYWNrKG1vZHVsZSwgJk1vZHVsZTo6bW9kdWxlX3J1bl9kb25lKTsKPiAJICAg
ICAgICAgICAgaWYgKG1vZHVsZS0+cnVuKHRydWUsIHJ1bl9jYikgPCAwKSB7Cj4gCQkgICAgICAg
IFhMT0dfRVJST1IoIkZhaWxlZCB0byByZXN0YXJ0IG1vZHVsZSAlcy5cbiIsIG1vZHVsZS0+bmFt
ZSgpLmNfc3RyKCkpOwo+IAkgICAgICAgICAgICB9ICAgIAkKPiAJCSAgICBlbHNlIHsKPiAJCSAg
ICAgICAgWExPR19JTkZPKCJNb2R1bGUgJXMgaXMgc3VjY2Vzc2Z1bGx5IHJlc3RhcnRlZC5cbiIs
Cj4gCQkJICAgIG1vZHVsZS0+bmFtZSgpLmNfc3RyKCkpOwo+IAkgICAgICAgICAgICB9Cj4gCQkg
ICAgTWFzdGVyQ29uZmlnVHJlZSogbWN0Owo+IAkJICAgIENvbmZpZ1RyZWVOb2RlKiBjdG47Cj4g
CQkgICAgbWN0ID0gbW9kdWxlLT5tb2R1bGVfbWFuYWdlcigpLmdldF9jb25mX3RyZWUoKTsKPiAJ
CSAgICAoY29uc3QgQ29uZmlnVHJlZU5vZGUqKSBjdG4gPSBtY3QtPmZpbmRfY29uZmlnX21vZHVs
ZShtb2R1bGUtPm5hbWUoKSk7Cj4gCQkgICAgaWYgKGN0biAhPSBOVUxMKXsKPiAJCSAgICAgICAg
WExPR19JTkZPKCJDb25maWd1cmUgbW9kdWxlICVzLlxuIiwgbW9kdWxlLT5uYW1lKCkuY19zdHIo
KSk7Cj4gCQkgICAgICAgIGN0bi0+bWFya19zdWJ0cmVlX2FzX3VuY29tbWl0dGVkKCk7Cj4gCQkg
ICAgICAgIG1jdC0+ZXhlY3V0ZSgpOwo+IAkJICAgIH0KPiAJCX0KPiAgICAgICAgICAgICB9Cj4g
CSAgICBtb2R1bGVfcGlkcy5lcmFzZShwaWRfaXRlcik7Cj4gCX0JCjEwNmExNDEsMTY2Cj4gCSAg
ICBpZiAobW9kdWxlLT5zdGF0dXMoKSA9PSBNb2R1bGU6Ok1PRFVMRV9GQUlMRUQpIHsKPiAJICAg
ICAgICAvLyBmZWEgcmVzdGFydCBpcyBub3Qgc3VwcG9ydGVkLgo+IAkJaWYgKCghc3RyY21wKG1v
ZHVsZS0+bmFtZSgpLmNfc3RyKCksICJmZWEiKSkgfHwgKCFzdHJjbXAobW9kdWxlLT5uYW1lKCku
Y19zdHIoKSwgImludGVyZmFjZXMiKSkpIHsKPiAJCSAgICBYTE9HX0VSUk9SKCJGYXRhbCBlcnJv
cjogZmVhIGRpZWQsIGV4aXQgWE9SUC5cbiIpOwo+IAkJICAgIGtpbGwoZ2V0cGlkKCksIFNJR1RF
Uk0pOwo+IAkJICAgIHJldHVybjsKPiAJCX0KPiAJICAgICAgICBYTE9HX0lORk8oIlJlc3RhcnRp
bmcgbW9kdWxlICVzIC4uLlxuIiwgbW9kdWxlLT5uYW1lKCkuY19zdHIoKSk7Cj4gCSAgICAgICAg
WG9ycENhbGxiYWNrMTx2b2lkLCBib29sPjo6UmVmUHRyIHJ1bl9jYiAKPiAJCSAgICA9IGNhbGxi
YWNrKG1vZHVsZSwgJk1vZHVsZTo6bW9kdWxlX3J1bl9kb25lKTsKPiAJICAgICAgICBpZiAobW9k
dWxlLT5ydW4odHJ1ZSwgcnVuX2NiKSA8IDApIHsKPiAJCSAgICBYTE9HX0VSUk9SKCJGYWlsZWQg
dG8gcmVzdGFydCBtb2R1bGUgJXMuXG4iLCBtb2R1bGUtPm5hbWUoKS5jX3N0cigpKTsKPiAJICAg
ICAgICB9ICAgIAkKPiAJCWVsc2Ugewo+IAkJICAgIFhMT0dfSU5GTygiTW9kdWxlICVzIGlzIHN1
Y2Nlc3NmdWxseSByZXN0YXJ0ZWQuXG4iLCBtb2R1bGUtPm5hbWUoKS5jX3N0cigpKTsKPiAJICAg
ICAgICB9Cj4gCQlNYXN0ZXJDb25maWdUcmVlKiBtY3Q7Cj4gCQlDb25maWdUcmVlTm9kZSogY3Ru
Owo+IAkJbWN0ID0gbW9kdWxlLT5tb2R1bGVfbWFuYWdlcigpLmdldF9jb25mX3RyZWUoKTsKPiAJ
CShjb25zdCBDb25maWdUcmVlTm9kZSopIGN0biA9IG1jdC0+ZmluZF9jb25maWdfbW9kdWxlKG1v
ZHVsZS0+bmFtZSgpKTsKPiAJCWlmIChjdG4gIT0gTlVMTCl7Cj4gCQkgICAgWExPR19JTkZPKCJD
b25maWd1cmUgbW9kdWxlICVzLlxuIiwgbW9kdWxlLT5uYW1lKCkuY19zdHIoKSk7Cj4gCQkgICAg
Y3RuLT5tYXJrX3N1YnRyZWVfYXNfdW5jb21taXR0ZWQoKTsKPiAJCSAgICBtY3QtPmV4ZWN1dGUo
KTsKPiAJCX0KPiAJICAgIH0KMzU3YzQxNwo8IAotLS0KPiAgICAgCjUzNWM1OTUsNTk2CjwgICAg
ICAgX3hvcnBfcm9vdF9kaXIoeG9ycF9yb290X2RpcikKLS0tCj4gICAgICAgX3hvcnBfcm9vdF9k
aXIoeG9ycF9yb290X2RpciksCj4gICAgICAgX21hc3Rlcl9jb25mX3RyZWUoTlVMTCkKSW5kZXg6
IHJ0cm1nci9tb2R1bGVfbWFuYWdlci5oaAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ClJDUyBmaWxlOiAvY3ZzL3hvcnAv
cnRybWdyL21vZHVsZV9tYW5hZ2VyLmhoLHYKcmV0cmlldmluZyByZXZpc2lvbiAxLjIyCmRpZmYg
LXIxLjIyIG1vZHVsZV9tYW5hZ2VyLmhoCjI3ZDI2CjwgCjI5YTI5LDMwCj4gY2xhc3MgTWFzdGVy
Q29uZmlnVHJlZTsKPiAKMzVhMzcKPiAKNzdhODAsODEKPiAgICAgTW9kdWxlTWFuYWdlciYgbW9k
dWxlX21hbmFnZXIoKSBjb25zdCB7IHJldHVybiBfbW1ncjsgfQo+ICAgICBzdHJpbmcgY29uc3Qg
bmFtZSgpIHsgcmV0dXJuIF9uYW1lOyB9Cjk1YTEwMAo+IAoxMzhjMTQzLDE0NQo8IAotLS0KPiAg
ICAgdm9pZCBzZXRfY29uZl90cmVlKE1hc3RlckNvbmZpZ1RyZWUqIHYpIHsgX21hc3Rlcl9jb25m
X3RyZWUgPSB2OyB9Cj4gICAgIE1hc3RlckNvbmZpZ1RyZWUqIGdldF9jb25mX3RyZWUoKSBjb25z
dCB7IHJldHVybiBfbWFzdGVyX2NvbmZfdHJlZTsgfQo+ICAgICAKMTQ2YTE1NAo+ICAgICBNYXN0
ZXJDb25maWdUcmVlKglfbWFzdGVyX2NvbmZfdHJlZTsK
------=_Part_104_28907956.1092719442843--