From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpng1.m.smailru.net (smtpng1.m.smailru.net [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id C95694696C5 for ; Thu, 2 Apr 2020 03:29:52 +0300 (MSK) References: <20200401160914.GC26447@tarantool.org> From: Vladislav Shpilevoy Message-ID: <50ab4dbe-0e2e-9d65-6087-4d01feb94b8e@tarantool.org> Date: Thu, 2 Apr 2020 02:29:50 +0200 MIME-Version: 1.0 In-Reply-To: <20200401160914.GC26447@tarantool.org> Content-Type: multipart/mixed; boundary="------------4392EAB8059CB44410E970DC" Content-Language: en-US Subject: Re: [Tarantool-patches] [PATCH v2 06/10] box: introduce stacked diagnostic area List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Nikita Pettik Cc: tarantool-patches@dev.tarantool.org This is a multi-part message in MIME format. --------------4392EAB8059CB44410E970DC Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Hi! Thanks for the fixes! See 2 comments below. > static inline void > error_unref(struct error *e) > { > assert(e->refs > 0); > struct error *to_delete = e; > while (--to_delete->refs == 0) { > /* Unlink error from lists completely.*/ > struct error *cause = to_delete->cause; > if (to_delete->effect != NULL) > to_delete->effect->cause = to_delete->cause; 1. Looks like 'effect' should be always NULL here. Because if it is not NULL, then effect->cause == e, and it would keep a reference, making e->refs == 0 impossible. I applied the diff below and all the tests passed. ==================== diff --git a/src/lib/core/diag.h b/src/lib/core/diag.h index 3a817a659..276bf2362 100644 --- a/src/lib/core/diag.h +++ b/src/lib/core/diag.h @@ -117,12 +117,11 @@ error_unref(struct error *e) while (--to_delete->refs == 0) { /* Unlink error from lists completely.*/ struct error *cause = to_delete->cause; - if (to_delete->effect != NULL) - to_delete->effect->cause = to_delete->cause; - if (to_delete->cause != NULL) - to_delete->cause->effect = to_delete->effect; - to_delete->cause = NULL; - to_delete->effect = NULL; + assert(to_delete->effect == NULL); + if (to_delete->cause != NULL) { + to_delete->cause->effect = NULL; + to_delete->cause = NULL; + } to_delete->destroy(to_delete); if (cause == NULL) return; ==================== > if (to_delete->cause != NULL) > to_delete->cause->effect = to_delete->effect; > to_delete->cause = NULL; > to_delete->effect = NULL; > to_delete->destroy(to_delete); > if (cause == NULL) > return; > to_delete = cause; > } > }>>> diff --git a/src/lib/core/diag.c b/src/lib/core/diag.c >>> index c350abb4a..57da5da44 100644 >>> --- a/src/lib/core/diag.c >>> +++ b/src/lib/core/diag.c >>> @@ -34,6 +34,43 @@ >>> /* Must be set by the library user */ >>> struct error_factory *error_factory = NULL; >>> >>> +int >>> +error_set_prev(struct error *e, struct error *prev) >>> +{ >>> + /* >>> + * Make sure that adding error won't result in cycles. >>> + * Don't bother with sophisticated cycle-detection >>> + * algorithms, simple iteration is OK since as a rule >>> + * list contains a dozen errors at maximum. >>> + */ >>> + struct error *tmp = prev; >>> + while (tmp != NULL) { >>> + if (tmp == e) >>> + return -1; >>> + tmp = tmp->cause; >>> + } >> >> 3. Or we could remove 'prev' from its current stack gracefully, >> since the list is doubly linked. Then cycles become impossible. >> Is there a reason not to do that? I mean, we remove 'prev' >> from its old stack by changing its 'effect' already anyway. >> >> Can do the same for the other pointer, and no need to check >> for cycles anymore. >> I can only think of a problem when someone makes >> >> e1 = box.error.new() >> e2 = box.error.new() >> e2:set_prev(e1) >> >> and then >> >> e4 = box.error.new() >> e4:set_prev(e1) >> >> assuming that e1 will be copied. But it will steal e1 from >> its old stack. Even with your current solution. Maybe to make >> it more protected against dummies we should forbid moving error >> from one stack to another? So an error can't change its 'cause' >> and 'effect' once they become not NULL. In that way we eliminate >> any uncertainties and in future can decide whether we want to copy >> in set_prev() when necessary, or move from previous stack. Or we >> will keep this forbidden because probably no one does moving >> between stacks, nor the example I showed above. This also >> significantly simplifies tests and reduces probability of having >> a bug there. What are your thoughts? > > I'm okay with current approach. It is all about documentation - > the better feature is documented, the easier it turns out to > be in terms of usage. There's always way to misuse any feature > however well designed. If you insist on some changes - let me know. 2. I don't insist. Can only recommend. And I would strongly recommend to cut the ability to move errors between stacks. I see only pros in cutting that. Because it is never needed (I can't imagine a sane case), can be surprising for someone, and complicates the code. The server code. Makes it easier to leave a bug here. Another reason is that it is easier to add something later if someone will need it, than to forbid something after introduction. Besides, it seems we could even make the error list unidirectional then. Instead of 'effect' pointer we could keep a flag saying whether this error belongs to a stack. No more complex handling of when to do ref/unref/cycles and so on. Even bigger simplification. I decided to try that and got a patch. See it attached to the email as 'unidirect.txt', and below. I didn't push it on the branch so as not to change next commits. On the summary, I made the list unidirectional, removed the cycle detection and forbidden any chance of creating it by banning change of error object when it is not on top of the stack. So a stack should be built always in one order - from the cause of all causes to top. The only thing you can do is to cut a tail of a stack. All more complex actions which may be needed in very rare cases still can be implemented by users using the provided basic API. That made the patch 110 lines shorter. Also a small comment about cycle detection in your patch. Here I would strongly-strongly recommend to avoid it when it is clearly not necessary. You can't create a cycle, if e->effect and prev->effect are NULL. Which is the case in 99% of cases. Even if prev->cause is not NULL, you still can't create a cycle when both effects are NULL. See diff below and attached as 'opt-cycle.txt'. That skips 'prev' iteration even if it is a whole another stack, but 'prev' is its top. Optimized cycle detection: ==================== diff --git a/src/lib/core/diag.c b/src/lib/core/diag.c index ed8beb58d..64ff5e4d6 100644 --- a/src/lib/core/diag.c +++ b/src/lib/core/diag.c @@ -43,11 +43,28 @@ error_set_prev(struct error *e, struct error *prev) * algorithms, simple iteration is OK since as a rule * list contains a dozen errors at maximum. */ - struct error *tmp = prev; - while (tmp != NULL) { - if (tmp == e) + if (prev != NULL) { + if (e == prev) return -1; - tmp = tmp->cause; + if (prev->effect != NULL || e->effect != NULL) { + /* + * e and prev already compared, so start + * from prev->cause. + */ + struct error *tmp = prev->cause; + while (tmp != NULL) { + if (tmp == e) + return -1; + tmp = tmp->cause; + } + /* + * Unlink new 'effect' node from its old + * list of 'cause' errors. + */ + error_unlink_effect(prev); + } + error_ref(prev); + prev->effect = e; } /* * At once error can feature only one reason. @@ -59,15 +76,6 @@ error_set_prev(struct error *e, struct error *prev) } /* Set new 'prev' node. */ e->cause = prev; - /* - * Unlink new 'effect' node from its old list of 'cause' - * errors. nil can be also passed as an argument. - */ - if (prev != NULL) { - error_ref(prev); - error_unlink_effect(prev); - prev->effect = e; - } return 0; } ==================== Simplified error list patch: ==================== diff --git a/src/lib/core/diag.c b/src/lib/core/diag.c index ed8beb58d..69a19d91f 100644 --- a/src/lib/core/diag.c +++ b/src/lib/core/diag.c @@ -37,37 +37,32 @@ struct error_factory *error_factory = NULL; int error_set_prev(struct error *e, struct error *prev) { - /* - * Make sure that adding error won't result in cycles. - * Don't bother with sophisticated cycle-detection - * algorithms, simple iteration is OK since as a rule - * list contains a dozen errors at maximum. - */ - struct error *tmp = prev; - while (tmp != NULL) { - if (tmp == e) + if (e == prev) + return -1; + if (prev != NULL) { + /* + * It is not allowed to change middle of the error + * stack. Except when the tail is cut. Not + * replaced. Reason is to make the code simpler, + * and avoid any necessity to detect cycles. In + * that implementation cycles are not allowed, and + * this guarantee costs nothing. + */ + if (prev->has_effect || e->has_effect) return -1; - tmp = tmp->cause; + prev->has_effect = true; + error_ref(prev); } /* * At once error can feature only one reason. * So unlink previous 'cause' node. */ if (e->cause != NULL) { - e->cause->effect = NULL; + e->cause->has_effect = false; error_unref(e->cause); } /* Set new 'prev' node. */ e->cause = prev; - /* - * Unlink new 'effect' node from its old list of 'cause' - * errors. nil can be also passed as an argument. - */ - if (prev != NULL) { - error_ref(prev); - error_unlink_effect(prev); - prev->effect = e; - } return 0; } @@ -91,7 +86,7 @@ error_create(struct error *e, } e->errmsg[0] = '\0'; e->cause = NULL; - e->effect = NULL; + e->has_effect = false; } struct diag * diff --git a/src/lib/core/diag.h b/src/lib/core/diag.h index 3a817a659..52987befa 100644 --- a/src/lib/core/diag.h +++ b/src/lib/core/diag.h @@ -85,22 +85,20 @@ struct error { /* Error description. */ char errmsg[DIAG_ERRMSG_MAX]; /** - * Link to the cause and effect of given error. The cause - * creates the effect: + * Cause of the given error.. * e1 = box.error.new({code = 0, reason = 'e1'}) * e2 = box.error.new({code = 0, reason = 'e2'}) - * e1:set_prev(e2) -- Now e2 is the cause of e1 and e1 is - * the effect of e2. - * Only cause keeps reference to avoid cyclic dependence. - * RLIST implementation is not really suitable here - * since it is organized as circular list. In such - * a case it is impossible to start an iteration - * from any node and finish at the logical end of the - * list. Double-linked list is required to allow deletion - * from the middle of the list. + * e1:set_prev(e2) -- Now e2 is the cause of e1. */ struct error *cause; - struct error *effect; + /** + * Flag whether this error is not top of the error stack. + * I.e. it has an 'effect'. Effect is e1 in the example + * above. The flag is used to prevent changing middle of + * the stack (except when it is cut off - this easy to + * support, and can't create a cycle). + */ + bool has_effect; }; static inline void @@ -115,51 +113,24 @@ error_unref(struct error *e) assert(e->refs > 0); struct error *to_delete = e; while (--to_delete->refs == 0) { - /* Unlink error from lists completely.*/ struct error *cause = to_delete->cause; - if (to_delete->effect != NULL) - to_delete->effect->cause = to_delete->cause; - if (to_delete->cause != NULL) - to_delete->cause->effect = to_delete->effect; to_delete->cause = NULL; - to_delete->effect = NULL; to_delete->destroy(to_delete); if (cause == NULL) return; + cause->has_effect = false; to_delete = cause; } } /** - * Unlink error from its effect. For instance: - * e1 -> e2 -> e3 -> e4 (e1:set_prev(e2); e2:set_prev(e3) ...) - * unlink(e3): e1 -> e2 -> NULL; e3 -> e4 -> NULL - */ -static inline void -error_unlink_effect(struct error *e) -{ - if (e->effect != NULL) { - assert(e->refs > 1); - error_unref(e); - e->effect->cause = NULL; - } - e->effect = NULL; -} - -/** - * Set previous error: cut @a prev from its previous 'tail' of - * causes and link to the one @a e belongs to. Note that all - * previous errors starting from @a prev->cause are transferred - * with it as well (i.e. causes for given error are not erased). - * For instance: - * e1 -> e2 -> NULL; e3 -> e4 -> NULL; - * e2:set_effect(e3): e1 -> e2 -> e3 -> e4 -> NULL - * - * @a effect can be NULL. To be used as ffi method in - * lua/error.lua. + * Set previous error. It can be NULL to make @a not having any + * previous error. In case @a prev is not NULL, it should not be + * already belong to another stack, and @a e should be top of the + * stack. * - * @retval -1 in case adding @a effect results in list cycles; - * 0 otherwise. + * @retval -1 In case adding @a prev is not possible. + * @retval 0 Success. */ int error_set_prev(struct error *e, struct error *prev); @@ -241,7 +212,6 @@ diag_set_error(struct diag *diag, struct error *e) assert(e != NULL); error_ref(e); diag_clear(diag); - error_unlink_effect(e); diag->last = e; } @@ -255,11 +225,11 @@ static inline void diag_add_error(struct diag *diag, struct error *e) { assert(e != NULL); + assert(e->cause == NULL); error_ref(e); - error_unlink_effect(e); e->cause = diag->last; if (diag->last != NULL) - diag->last->effect = e; + diag->last->has_effect = true; diag->last = e; } diff --git a/src/lua/error.lua b/src/lua/error.lua index bdc9c714d..3d0b75689 100644 --- a/src/lua/error.lua +++ b/src/lua/error.lua @@ -25,7 +25,7 @@ struct error { /* Error description. */ char _errmsg[DIAG_ERRMSG_MAX]; struct error *_cause; - struct error *_effect; + bool has_effect; }; char * diff --git a/test/box/error.result b/test/box/error.result index 4f0f30491..300def647 100644 --- a/test/box/error.result +++ b/test/box/error.result @@ -502,6 +502,10 @@ box.error() | --- | ... +space:drop() + | --- + | ... + -- gh-1148: errors can be arranged into list (so called -- stacked diagnostics). -- @@ -540,14 +544,17 @@ assert(e2.prev == nil) | ... -- At this point stack is following: e1 -> e2 -- Let's test following cases: --- 1. e3 -> e2, e1 -> NULL (e3:set_prev(e2)) +-- 1. e3 -> e2, e1 -> NULL (e1:set_prev(nil), e3:set_prev(e2)) -- 2. e1 -> e3, e2 -> NULL (e1:set_prev(e3)) -- 3. e3 -> e1 -> e2 (e3:set_prev(e1)) --- 4. e1 -> e2 -> e3 (e2:set_prev(e3)) +-- 4. e1 -> e2 -> e3 (e1:set_prev(nil) e2:set_prev(e3) e1:set_prev(e2)) -- e3 = box.error.new({code = 111, reason = "another cause"}) | --- | ... +e1:set_prev(nil) + | --- + | ... e3:set_prev(e2) | --- | ... @@ -566,6 +573,9 @@ assert(e1.prev == nil) -- Reset stack to e1 -> e2 and test case 2. -- +e3:set_prev(nil) + | --- + | ... e1:set_prev(e2) | --- | ... @@ -628,19 +638,19 @@ assert(e3.prev == e1) -- Unlink errors and test case 4. -- -e1:set_prev(nil) +e3:set_prev(nil) | --- | ... e2:set_prev(nil) | --- | ... -e3:set_prev(nil) +e1:set_prev(nil) | --- | ... -e1:set_prev(e2) +e2:set_prev(e3) | --- | ... -e2:set_prev(e3) +e1:set_prev(e2) | --- | ... assert(e1.prev == e2) @@ -676,72 +686,6 @@ assert(e3.prev == nil) | - true | ... --- Test splitting list into two ones. --- After that we will get two lists: e1->e2->e5 and e3->e4 --- -e4 = box.error.new({code = 111, reason = "yet another cause"}) - | --- - | ... -e5 = box.error.new({code = 111, reason = "and another one"}) - | --- - | ... -e3:set_prev(e4) - | --- - | ... -e2:set_prev(e5) - | --- - | ... -assert(e1.prev == e2) - | --- - | - true - | ... -assert(e2.prev == e5) - | --- - | - true - | ... -assert(e3.prev == e4) - | --- - | - true - | ... -assert(e5.prev == nil) - | --- - | - true - | ... -assert(e4.prev == nil) - | --- - | - true - | ... - --- Another splitting option: e1->e2 and e5->e3->e4 --- But firstly restore to one single list e1->e2->e3->e4 --- -e2:set_prev(e3) - | --- - | ... -e5:set_prev(e3) - | --- - | ... -assert(e1.prev == e2) - | --- - | - true - | ... -assert(e2.prev == nil) - | --- - | - true - | ... -assert(e5.prev == e3) - | --- - | - true - | ... -assert(e3.prev == e4) - | --- - | - true - | ... -assert(e4.prev == nil) - | --- - | - true - | ... - -- In case error is destroyed, it unrefs reference counter -- of its previous error. In turn, box.error.clear() refs/unrefs -- only head and doesn't touch other errors. @@ -785,7 +729,3 @@ assert(e1.prev == e2) | --- | - true | ... - -space:drop() - | --- - | ... diff --git a/test/box/error.test.lua b/test/box/error.test.lua index 66a22db90..04e00168e 100644 --- a/test/box/error.test.lua +++ b/test/box/error.test.lua @@ -108,6 +108,8 @@ box.error.new(err) box.error.clear() box.error() +space:drop() + -- gh-1148: errors can be arranged into list (so called -- stacked diagnostics). -- @@ -122,12 +124,13 @@ e2:set_prev(e1) assert(e2.prev == nil) -- At this point stack is following: e1 -> e2 -- Let's test following cases: --- 1. e3 -> e2, e1 -> NULL (e3:set_prev(e2)) +-- 1. e3 -> e2, e1 -> NULL (e1:set_prev(nil), e3:set_prev(e2)) -- 2. e1 -> e3, e2 -> NULL (e1:set_prev(e3)) -- 3. e3 -> e1 -> e2 (e3:set_prev(e1)) --- 4. e1 -> e2 -> e3 (e2:set_prev(e3)) +-- 4. e1 -> e2 -> e3 (e1:set_prev(nil) e2:set_prev(e3) e1:set_prev(e2)) -- e3 = box.error.new({code = 111, reason = "another cause"}) +e1:set_prev(nil) e3:set_prev(e2) assert(e3.prev == e2) assert(e2.prev == nil) @@ -135,6 +138,7 @@ assert(e1.prev == nil) -- Reset stack to e1 -> e2 and test case 2. -- +e3:set_prev(nil) e1:set_prev(e2) assert(e2.prev == nil) assert(e3.prev == nil) @@ -156,11 +160,11 @@ assert(e3.prev == e1) -- Unlink errors and test case 4. -- -e1:set_prev(nil) -e2:set_prev(nil) e3:set_prev(nil) -e1:set_prev(e2) +e2:set_prev(nil) +e1:set_prev(nil) e2:set_prev(e3) +e1:set_prev(e2) assert(e1.prev == e2) assert(e2.prev == e3) assert(e3.prev == nil) @@ -173,30 +177,6 @@ assert(e3.prev == nil) e3:set_prev(e2) assert(e3.prev == nil) --- Test splitting list into two ones. --- After that we will get two lists: e1->e2->e5 and e3->e4 --- -e4 = box.error.new({code = 111, reason = "yet another cause"}) -e5 = box.error.new({code = 111, reason = "and another one"}) -e3:set_prev(e4) -e2:set_prev(e5) -assert(e1.prev == e2) -assert(e2.prev == e5) -assert(e3.prev == e4) -assert(e5.prev == nil) -assert(e4.prev == nil) - --- Another splitting option: e1->e2 and e5->e3->e4 --- But firstly restore to one single list e1->e2->e3->e4 --- -e2:set_prev(e3) -e5:set_prev(e3) -assert(e1.prev == e2) -assert(e2.prev == nil) -assert(e5.prev == e3) -assert(e3.prev == e4) -assert(e4.prev == nil) - -- In case error is destroyed, it unrefs reference counter -- of its previous error. In turn, box.error.clear() refs/unrefs -- only head and doesn't touch other errors. @@ -212,5 +192,3 @@ assert(e2.code == 111) box.error.set(e1) box.error.clear() assert(e1.prev == e2) - -space:drop() --------------4392EAB8059CB44410E970DC Content-Type: text/plain; charset=UTF-8; x-mac-type="0"; x-mac-creator="0"; name="opt-cycle.txt" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="opt-cycle.txt" ZGlmZiAtLWdpdCBhL3NyYy9saWIvY29yZS9kaWFnLmggYi9zcmMvbGliL2NvcmUvZGlhZy5o CmluZGV4IDNhODE3YTY1OS4uMjc2YmYyMzYyIDEwMDY0NAotLS0gYS9zcmMvbGliL2NvcmUv ZGlhZy5oCisrKyBiL3NyYy9saWIvY29yZS9kaWFnLmgKQEAgLTExNywxMiArMTE3LDExIEBA IGVycm9yX3VucmVmKHN0cnVjdCBlcnJvciAqZSkKIAl3aGlsZSAoLS10b19kZWxldGUtPnJl ZnMgPT0gMCkgewogCQkvKiBVbmxpbmsgZXJyb3IgZnJvbSBsaXN0cyBjb21wbGV0ZWx5Liov CiAJCXN0cnVjdCBlcnJvciAqY2F1c2UgPSB0b19kZWxldGUtPmNhdXNlOwotCQlpZiAodG9f ZGVsZXRlLT5lZmZlY3QgIT0gTlVMTCkKLQkJCXRvX2RlbGV0ZS0+ZWZmZWN0LT5jYXVzZSA9 IHRvX2RlbGV0ZS0+Y2F1c2U7Ci0JCWlmICh0b19kZWxldGUtPmNhdXNlICE9IE5VTEwpCi0J CQl0b19kZWxldGUtPmNhdXNlLT5lZmZlY3QgPSB0b19kZWxldGUtPmVmZmVjdDsKLQkJdG9f ZGVsZXRlLT5jYXVzZSA9IE5VTEw7Ci0JCXRvX2RlbGV0ZS0+ZWZmZWN0ID0gTlVMTDsKKwkJ YXNzZXJ0KHRvX2RlbGV0ZS0+ZWZmZWN0ID09IE5VTEwpOworCQlpZiAodG9fZGVsZXRlLT5j YXVzZSAhPSBOVUxMKSB7CisJCQl0b19kZWxldGUtPmNhdXNlLT5lZmZlY3QgPSBOVUxMOwor CQkJdG9fZGVsZXRlLT5jYXVzZSA9IE5VTEw7CisJCX0KIAkJdG9fZGVsZXRlLT5kZXN0cm95 KHRvX2RlbGV0ZSk7CiAJCWlmIChjYXVzZSA9PSBOVUxMKQogCQkJcmV0dXJuOwo= --------------4392EAB8059CB44410E970DC Content-Type: text/plain; charset=UTF-8; x-mac-type="0"; x-mac-creator="0"; name="unidirect.txt" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="unidirect.txt" Y29tbWl0IGVhYWRhMDI1ZTQ3OGFlYjY2ZDBiOGY4ZjMxYzkxMDQ1YjBmMDA4OWYKQXV0aG9y OiBWbGFkaXNsYXYgU2hwaWxldm95IDx2LnNocGlsZXZveUB0YXJhbnRvb2wub3JnPgpEYXRl OiAgIFRodSBBcHIgMiAwMDo1Mjo1NCAyMDIwICswMjAwCgogICAgRGlhZyBzdGFjayBzaW1w bGlmaWNhdGlvbgoKZGlmZiAtLWdpdCBhL3NyYy9saWIvY29yZS9kaWFnLmMgYi9zcmMvbGli L2NvcmUvZGlhZy5jCmluZGV4IGVkOGJlYjU4ZC4uNjlhMTlkOTFmIDEwMDY0NAotLS0gYS9z cmMvbGliL2NvcmUvZGlhZy5jCisrKyBiL3NyYy9saWIvY29yZS9kaWFnLmMKQEAgLTM3LDM3 ICszNywzMiBAQCBzdHJ1Y3QgZXJyb3JfZmFjdG9yeSAqZXJyb3JfZmFjdG9yeSA9IE5VTEw7 CiBpbnQKIGVycm9yX3NldF9wcmV2KHN0cnVjdCBlcnJvciAqZSwgc3RydWN0IGVycm9yICpw cmV2KQogewotCS8qCi0JICogTWFrZSBzdXJlIHRoYXQgYWRkaW5nIGVycm9yIHdvbid0IHJl c3VsdCBpbiBjeWNsZXMuCi0JICogRG9uJ3QgYm90aGVyIHdpdGggc29waGlzdGljYXRlZCBj eWNsZS1kZXRlY3Rpb24KLQkgKiBhbGdvcml0aG1zLCBzaW1wbGUgaXRlcmF0aW9uIGlzIE9L IHNpbmNlIGFzIGEgcnVsZQotCSAqIGxpc3QgY29udGFpbnMgYSBkb3plbiBlcnJvcnMgYXQg bWF4aW11bS4KLQkgKi8KLQlzdHJ1Y3QgZXJyb3IgKnRtcCA9IHByZXY7Ci0Jd2hpbGUgKHRt cCAhPSBOVUxMKSB7Ci0JCWlmICh0bXAgPT0gZSkKKwlpZiAoZSA9PSBwcmV2KQorCQlyZXR1 cm4gLTE7CisJaWYgKHByZXYgIT0gTlVMTCkgeworCQkvKgorCQkgKiBJdCBpcyBub3QgYWxs b3dlZCB0byBjaGFuZ2UgbWlkZGxlIG9mIHRoZSBlcnJvcgorCQkgKiBzdGFjay4gRXhjZXB0 IHdoZW4gdGhlIHRhaWwgaXMgY3V0LiBOb3QKKwkJICogcmVwbGFjZWQuIFJlYXNvbiBpcyB0 byBtYWtlIHRoZSBjb2RlIHNpbXBsZXIsCisJCSAqIGFuZCBhdm9pZCBhbnkgbmVjZXNzaXR5 IHRvIGRldGVjdCBjeWNsZXMuIEluCisJCSAqIHRoYXQgaW1wbGVtZW50YXRpb24gY3ljbGVz IGFyZSBub3QgYWxsb3dlZCwgYW5kCisJCSAqIHRoaXMgZ3VhcmFudGVlIGNvc3RzIG5vdGhp bmcuCisJCSAqLworCQlpZiAocHJldi0+aGFzX2VmZmVjdCB8fCBlLT5oYXNfZWZmZWN0KQog CQkJcmV0dXJuIC0xOwotCQl0bXAgPSB0bXAtPmNhdXNlOworCQlwcmV2LT5oYXNfZWZmZWN0 ID0gdHJ1ZTsKKwkJZXJyb3JfcmVmKHByZXYpOwogCX0KIAkvKgogCSAqIEF0IG9uY2UgZXJy b3IgY2FuIGZlYXR1cmUgb25seSBvbmUgcmVhc29uLgogCSAqIFNvIHVubGluayBwcmV2aW91 cyAnY2F1c2UnIG5vZGUuCiAJICovCiAJaWYgKGUtPmNhdXNlICE9IE5VTEwpIHsKLQkJZS0+ Y2F1c2UtPmVmZmVjdCA9IE5VTEw7CisJCWUtPmNhdXNlLT5oYXNfZWZmZWN0ID0gZmFsc2U7 CiAJCWVycm9yX3VucmVmKGUtPmNhdXNlKTsKIAl9CiAJLyogU2V0IG5ldyAncHJldicgbm9k ZS4gKi8KIAllLT5jYXVzZSA9IHByZXY7Ci0JLyoKLQkgKiBVbmxpbmsgbmV3ICdlZmZlY3Qn IG5vZGUgZnJvbSBpdHMgb2xkIGxpc3Qgb2YgJ2NhdXNlJwotCSAqIGVycm9ycy4gbmlsIGNh biBiZSBhbHNvIHBhc3NlZCBhcyBhbiBhcmd1bWVudC4KLQkgKi8KLQlpZiAocHJldiAhPSBO VUxMKSB7Ci0JCWVycm9yX3JlZihwcmV2KTsKLQkJZXJyb3JfdW5saW5rX2VmZmVjdChwcmV2 KTsKLQkJcHJldi0+ZWZmZWN0ID0gZTsKLQl9CiAJcmV0dXJuIDA7CiB9CiAKQEAgLTkxLDcg Kzg2LDcgQEAgZXJyb3JfY3JlYXRlKHN0cnVjdCBlcnJvciAqZSwKIAl9CiAJZS0+ZXJybXNn WzBdID0gJ1wwJzsKIAllLT5jYXVzZSA9IE5VTEw7Ci0JZS0+ZWZmZWN0ID0gTlVMTDsKKwll LT5oYXNfZWZmZWN0ID0gZmFsc2U7CiB9CiAKIHN0cnVjdCBkaWFnICoKZGlmZiAtLWdpdCBh L3NyYy9saWIvY29yZS9kaWFnLmggYi9zcmMvbGliL2NvcmUvZGlhZy5oCmluZGV4IDNhODE3 YTY1OS4uNTI5ODdiZWZhIDEwMDY0NAotLS0gYS9zcmMvbGliL2NvcmUvZGlhZy5oCisrKyBi L3NyYy9saWIvY29yZS9kaWFnLmgKQEAgLTg1LDIyICs4NSwyMCBAQCBzdHJ1Y3QgZXJyb3Ig ewogCS8qIEVycm9yIGRlc2NyaXB0aW9uLiAqLwogCWNoYXIgZXJybXNnW0RJQUdfRVJSTVNH X01BWF07CiAJLyoqCi0JICogTGluayB0byB0aGUgY2F1c2UgYW5kIGVmZmVjdCBvZiBnaXZl biBlcnJvci4gVGhlIGNhdXNlCi0JICogY3JlYXRlcyB0aGUgZWZmZWN0OgorCSAqIENhdXNl IG9mIHRoZSBnaXZlbiBlcnJvci4uCiAJICogZTEgPSBib3guZXJyb3IubmV3KHtjb2RlID0g MCwgcmVhc29uID0gJ2UxJ30pCiAJICogZTIgPSBib3guZXJyb3IubmV3KHtjb2RlID0gMCwg cmVhc29uID0gJ2UyJ30pCi0JICogZTE6c2V0X3ByZXYoZTIpIC0tIE5vdyBlMiBpcyB0aGUg Y2F1c2Ugb2YgZTEgYW5kIGUxIGlzCi0JICogdGhlIGVmZmVjdCBvZiBlMi4KLQkgKiBPbmx5 IGNhdXNlIGtlZXBzIHJlZmVyZW5jZSB0byBhdm9pZCBjeWNsaWMgZGVwZW5kZW5jZS4KLQkg KiBSTElTVCBpbXBsZW1lbnRhdGlvbiBpcyBub3QgcmVhbGx5IHN1aXRhYmxlIGhlcmUKLQkg KiBzaW5jZSBpdCBpcyBvcmdhbml6ZWQgYXMgY2lyY3VsYXIgbGlzdC4gSW4gc3VjaAotCSAq IGEgY2FzZSBpdCBpcyBpbXBvc3NpYmxlIHRvIHN0YXJ0IGFuIGl0ZXJhdGlvbgotCSAqIGZy b20gYW55IG5vZGUgYW5kIGZpbmlzaCBhdCB0aGUgbG9naWNhbCBlbmQgb2YgdGhlCi0JICog bGlzdC4gRG91YmxlLWxpbmtlZCBsaXN0IGlzIHJlcXVpcmVkIHRvIGFsbG93IGRlbGV0aW9u Ci0JICogZnJvbSB0aGUgbWlkZGxlIG9mIHRoZSBsaXN0LgorCSAqIGUxOnNldF9wcmV2KGUy KSAtLSBOb3cgZTIgaXMgdGhlIGNhdXNlIG9mIGUxLgogCSAqLwogCXN0cnVjdCBlcnJvciAq Y2F1c2U7Ci0Jc3RydWN0IGVycm9yICplZmZlY3Q7CisJLyoqCisJICogRmxhZyB3aGV0aGVy IHRoaXMgZXJyb3IgaXMgbm90IHRvcCBvZiB0aGUgZXJyb3Igc3RhY2suCisJICogSS5lLiBp dCBoYXMgYW4gJ2VmZmVjdCcuIEVmZmVjdCBpcyBlMSBpbiB0aGUgZXhhbXBsZQorCSAqIGFi b3ZlLiBUaGUgZmxhZyBpcyB1c2VkIHRvIHByZXZlbnQgY2hhbmdpbmcgbWlkZGxlIG9mCisJ ICogdGhlIHN0YWNrIChleGNlcHQgd2hlbiBpdCBpcyBjdXQgb2ZmIC0gdGhpcyBlYXN5IHRv CisJICogc3VwcG9ydCwgYW5kIGNhbid0IGNyZWF0ZSBhIGN5Y2xlKS4KKwkgKi8KKwlib29s IGhhc19lZmZlY3Q7CiB9OwogCiBzdGF0aWMgaW5saW5lIHZvaWQKQEAgLTExNSw1MSArMTEz LDI0IEBAIGVycm9yX3VucmVmKHN0cnVjdCBlcnJvciAqZSkKIAlhc3NlcnQoZS0+cmVmcyA+ IDApOwogCXN0cnVjdCBlcnJvciAqdG9fZGVsZXRlID0gZTsKIAl3aGlsZSAoLS10b19kZWxl dGUtPnJlZnMgPT0gMCkgewotCQkvKiBVbmxpbmsgZXJyb3IgZnJvbSBsaXN0cyBjb21wbGV0 ZWx5LiovCiAJCXN0cnVjdCBlcnJvciAqY2F1c2UgPSB0b19kZWxldGUtPmNhdXNlOwotCQlp ZiAodG9fZGVsZXRlLT5lZmZlY3QgIT0gTlVMTCkKLQkJCXRvX2RlbGV0ZS0+ZWZmZWN0LT5j YXVzZSA9IHRvX2RlbGV0ZS0+Y2F1c2U7Ci0JCWlmICh0b19kZWxldGUtPmNhdXNlICE9IE5V TEwpCi0JCQl0b19kZWxldGUtPmNhdXNlLT5lZmZlY3QgPSB0b19kZWxldGUtPmVmZmVjdDsK IAkJdG9fZGVsZXRlLT5jYXVzZSA9IE5VTEw7Ci0JCXRvX2RlbGV0ZS0+ZWZmZWN0ID0gTlVM TDsKIAkJdG9fZGVsZXRlLT5kZXN0cm95KHRvX2RlbGV0ZSk7CiAJCWlmIChjYXVzZSA9PSBO VUxMKQogCQkJcmV0dXJuOworCQljYXVzZS0+aGFzX2VmZmVjdCA9IGZhbHNlOwogCQl0b19k ZWxldGUgPSBjYXVzZTsKIAl9CiB9CiAKIC8qKgotICogVW5saW5rIGVycm9yIGZyb20gaXRz IGVmZmVjdC4gRm9yIGluc3RhbmNlOgotICogZTEgLT4gZTIgLT4gZTMgLT4gZTQgKGUxOnNl dF9wcmV2KGUyKTsgZTI6c2V0X3ByZXYoZTMpIC4uLikKLSAqIHVubGluayhlMyk6IGUxIC0+ IGUyIC0+IE5VTEw7IGUzIC0+IGU0IC0+IE5VTEwKLSAqLwotc3RhdGljIGlubGluZSB2b2lk Ci1lcnJvcl91bmxpbmtfZWZmZWN0KHN0cnVjdCBlcnJvciAqZSkKLXsKLQlpZiAoZS0+ZWZm ZWN0ICE9IE5VTEwpIHsKLQkJYXNzZXJ0KGUtPnJlZnMgPiAxKTsKLQkJZXJyb3JfdW5yZWYo ZSk7Ci0JCWUtPmVmZmVjdC0+Y2F1c2UgPSBOVUxMOwotCX0KLQllLT5lZmZlY3QgPSBOVUxM OwotfQotCi0vKioKLSAqIFNldCBwcmV2aW91cyBlcnJvcjogY3V0IEBhIHByZXYgZnJvbSBp dHMgcHJldmlvdXMgJ3RhaWwnIG9mCi0gKiBjYXVzZXMgYW5kIGxpbmsgdG8gdGhlIG9uZSBA YSBlIGJlbG9uZ3MgdG8uIE5vdGUgdGhhdCBhbGwKLSAqIHByZXZpb3VzIGVycm9ycyBzdGFy dGluZyBmcm9tIEBhIHByZXYtPmNhdXNlIGFyZSB0cmFuc2ZlcnJlZAotICogd2l0aCBpdCBh cyB3ZWxsIChpLmUuIGNhdXNlcyBmb3IgZ2l2ZW4gZXJyb3IgYXJlIG5vdCBlcmFzZWQpLgot ICogRm9yIGluc3RhbmNlOgotICogZTEgLT4gZTIgLT4gTlVMTDsgZTMgLT4gZTQgLT4gTlVM TDsKLSAqIGUyOnNldF9lZmZlY3QoZTMpOiBlMSAtPiBlMiAtPiBlMyAtPiBlNCAtPiBOVUxM Ci0gKgotICogQGEgZWZmZWN0IGNhbiBiZSBOVUxMLiBUbyBiZSB1c2VkIGFzIGZmaSBtZXRo b2QgaW4KLSAqIGx1YS9lcnJvci5sdWEuCisgKiBTZXQgcHJldmlvdXMgZXJyb3IuIEl0IGNh biBiZSBOVUxMIHRvIG1ha2UgQGEgbm90IGhhdmluZyBhbnkKKyAqIHByZXZpb3VzIGVycm9y LiBJbiBjYXNlIEBhIHByZXYgaXMgbm90IE5VTEwsIGl0IHNob3VsZCBub3QgYmUKKyAqIGFs cmVhZHkgYmVsb25nIHRvIGFub3RoZXIgc3RhY2ssIGFuZCBAYSBlIHNob3VsZCBiZSB0b3Ag b2YgdGhlCisgKiBzdGFjay4KICAqCi0gKiBAcmV0dmFsIC0xIGluIGNhc2UgYWRkaW5nIEBh IGVmZmVjdCByZXN1bHRzIGluIGxpc3QgY3ljbGVzOwotICogICAgICAgICAgMCBvdGhlcndp c2UuCisgKiBAcmV0dmFsIC0xIEluIGNhc2UgYWRkaW5nIEBhIHByZXYgaXMgbm90IHBvc3Np YmxlLgorICogQHJldHZhbCAwIFN1Y2Nlc3MuCiAgKi8KIGludAogZXJyb3Jfc2V0X3ByZXYo c3RydWN0IGVycm9yICplLCBzdHJ1Y3QgZXJyb3IgKnByZXYpOwpAQCAtMjQxLDcgKzIxMiw2 IEBAIGRpYWdfc2V0X2Vycm9yKHN0cnVjdCBkaWFnICpkaWFnLCBzdHJ1Y3QgZXJyb3IgKmUp CiAJYXNzZXJ0KGUgIT0gTlVMTCk7CiAJZXJyb3JfcmVmKGUpOwogCWRpYWdfY2xlYXIoZGlh Zyk7Ci0JZXJyb3JfdW5saW5rX2VmZmVjdChlKTsKIAlkaWFnLT5sYXN0ID0gZTsKIH0KIApA QCAtMjU1LDExICsyMjUsMTEgQEAgc3RhdGljIGlubGluZSB2b2lkCiBkaWFnX2FkZF9lcnJv cihzdHJ1Y3QgZGlhZyAqZGlhZywgc3RydWN0IGVycm9yICplKQogewogCWFzc2VydChlICE9 IE5VTEwpOworCWFzc2VydChlLT5jYXVzZSA9PSBOVUxMKTsKIAllcnJvcl9yZWYoZSk7Ci0J ZXJyb3JfdW5saW5rX2VmZmVjdChlKTsKIAllLT5jYXVzZSA9IGRpYWctPmxhc3Q7CiAJaWYg KGRpYWctPmxhc3QgIT0gTlVMTCkKLQkJZGlhZy0+bGFzdC0+ZWZmZWN0ID0gZTsKKwkJZGlh Zy0+bGFzdC0+aGFzX2VmZmVjdCA9IHRydWU7CiAJZGlhZy0+bGFzdCA9IGU7CiB9CiAKZGlm ZiAtLWdpdCBhL3NyYy9sdWEvZXJyb3IubHVhIGIvc3JjL2x1YS9lcnJvci5sdWEKaW5kZXgg YmRjOWM3MTRkLi4zZDBiNzU2ODkgMTAwNjQ0Ci0tLSBhL3NyYy9sdWEvZXJyb3IubHVhCisr KyBiL3NyYy9sdWEvZXJyb3IubHVhCkBAIC0yNSw3ICsyNSw3IEBAIHN0cnVjdCBlcnJvciB7 CiAgICAgLyogRXJyb3IgZGVzY3JpcHRpb24uICovCiAgICAgY2hhciBfZXJybXNnW0RJQUdf RVJSTVNHX01BWF07CiAgICAgc3RydWN0IGVycm9yICpfY2F1c2U7Ci0gICAgc3RydWN0IGVy cm9yICpfZWZmZWN0OworICAgIGJvb2wgaGFzX2VmZmVjdDsKIH07CiAKIGNoYXIgKgpkaWZm IC0tZ2l0IGEvdGVzdC9ib3gvZXJyb3IucmVzdWx0IGIvdGVzdC9ib3gvZXJyb3IucmVzdWx0 CmluZGV4IDRmMGYzMDQ5MS4uMzAwZGVmNjQ3IDEwMDY0NAotLS0gYS90ZXN0L2JveC9lcnJv ci5yZXN1bHQKKysrIGIvdGVzdC9ib3gvZXJyb3IucmVzdWx0CkBAIC01MDIsNiArNTAyLDEw IEBAIGJveC5lcnJvcigpCiAgfCAtLS0KICB8IC4uLgogCitzcGFjZTpkcm9wKCkKKyB8IC0t LQorIHwgLi4uCisKIC0tIGdoLTExNDg6IGVycm9ycyBjYW4gYmUgYXJyYW5nZWQgaW50byBs aXN0IChzbyBjYWxsZWQKIC0tIHN0YWNrZWQgZGlhZ25vc3RpY3MpLgogLS0KQEAgLTU0MCwx NCArNTQ0LDE3IEBAIGFzc2VydChlMi5wcmV2ID09IG5pbCkKICB8IC4uLgogLS0gQXQgdGhp cyBwb2ludCBzdGFjayBpcyBmb2xsb3dpbmc6IGUxIC0+IGUyCiAtLSBMZXQncyB0ZXN0IGZv bGxvd2luZyBjYXNlczoKLS0tIDEuIGUzIC0+IGUyLCBlMSAtPiBOVUxMIChlMzpzZXRfcHJl dihlMikpCistLSAxLiBlMyAtPiBlMiwgZTEgLT4gTlVMTCAoZTE6c2V0X3ByZXYobmlsKSwg ZTM6c2V0X3ByZXYoZTIpKQogLS0gMi4gZTEgLT4gZTMsIGUyIC0+IE5VTEwgKGUxOnNldF9w cmV2KGUzKSkKIC0tIDMuIGUzIC0+IGUxIC0+IGUyIChlMzpzZXRfcHJldihlMSkpCi0tLSA0 LiBlMSAtPiBlMiAtPiBlMyAoZTI6c2V0X3ByZXYoZTMpKQorLS0gNC4gZTEgLT4gZTIgLT4g ZTMgKGUxOnNldF9wcmV2KG5pbCkgZTI6c2V0X3ByZXYoZTMpIGUxOnNldF9wcmV2KGUyKSkK IC0tCiBlMyA9IGJveC5lcnJvci5uZXcoe2NvZGUgPSAxMTEsIHJlYXNvbiA9ICJhbm90aGVy IGNhdXNlIn0pCiAgfCAtLS0KICB8IC4uLgorZTE6c2V0X3ByZXYobmlsKQorIHwgLS0tCisg fCAuLi4KIGUzOnNldF9wcmV2KGUyKQogIHwgLS0tCiAgfCAuLi4KQEAgLTU2Niw2ICs1NzMs OSBAQCBhc3NlcnQoZTEucHJldiA9PSBuaWwpCiAKIC0tIFJlc2V0IHN0YWNrIHRvIGUxIC0+ IGUyIGFuZCB0ZXN0IGNhc2UgMi4KIC0tCitlMzpzZXRfcHJldihuaWwpCisgfCAtLS0KKyB8 IC4uLgogZTE6c2V0X3ByZXYoZTIpCiAgfCAtLS0KICB8IC4uLgpAQCAtNjI4LDE5ICs2Mzgs MTkgQEAgYXNzZXJ0KGUzLnByZXYgPT0gZTEpCiAKIC0tIFVubGluayBlcnJvcnMgYW5kIHRl c3QgY2FzZSA0LgogLS0KLWUxOnNldF9wcmV2KG5pbCkKK2UzOnNldF9wcmV2KG5pbCkKICB8 IC0tLQogIHwgLi4uCiBlMjpzZXRfcHJldihuaWwpCiAgfCAtLS0KICB8IC4uLgotZTM6c2V0 X3ByZXYobmlsKQorZTE6c2V0X3ByZXYobmlsKQogIHwgLS0tCiAgfCAuLi4KLWUxOnNldF9w cmV2KGUyKQorZTI6c2V0X3ByZXYoZTMpCiAgfCAtLS0KICB8IC4uLgotZTI6c2V0X3ByZXYo ZTMpCitlMTpzZXRfcHJldihlMikKICB8IC0tLQogIHwgLi4uCiBhc3NlcnQoZTEucHJldiA9 PSBlMikKQEAgLTY3Niw3MiArNjg2LDYgQEAgYXNzZXJ0KGUzLnByZXYgPT0gbmlsKQogIHwg LSB0cnVlCiAgfCAuLi4KIAotLS0gVGVzdCBzcGxpdHRpbmcgbGlzdCBpbnRvIHR3byBvbmVz LgotLS0gQWZ0ZXIgdGhhdCB3ZSB3aWxsIGdldCB0d28gbGlzdHM6IGUxLT5lMi0+ZTUgYW5k IGUzLT5lNAotLS0KLWU0ID0gYm94LmVycm9yLm5ldyh7Y29kZSA9IDExMSwgcmVhc29uID0g InlldCBhbm90aGVyIGNhdXNlIn0pCi0gfCAtLS0KLSB8IC4uLgotZTUgPSBib3guZXJyb3Iu bmV3KHtjb2RlID0gMTExLCByZWFzb24gPSAiYW5kIGFub3RoZXIgb25lIn0pCi0gfCAtLS0K LSB8IC4uLgotZTM6c2V0X3ByZXYoZTQpCi0gfCAtLS0KLSB8IC4uLgotZTI6c2V0X3ByZXYo ZTUpCi0gfCAtLS0KLSB8IC4uLgotYXNzZXJ0KGUxLnByZXYgPT0gZTIpCi0gfCAtLS0KLSB8 IC0gdHJ1ZQotIHwgLi4uCi1hc3NlcnQoZTIucHJldiA9PSBlNSkKLSB8IC0tLQotIHwgLSB0 cnVlCi0gfCAuLi4KLWFzc2VydChlMy5wcmV2ID09IGU0KQotIHwgLS0tCi0gfCAtIHRydWUK LSB8IC4uLgotYXNzZXJ0KGU1LnByZXYgPT0gbmlsKQotIHwgLS0tCi0gfCAtIHRydWUKLSB8 IC4uLgotYXNzZXJ0KGU0LnByZXYgPT0gbmlsKQotIHwgLS0tCi0gfCAtIHRydWUKLSB8IC4u LgotCi0tLSBBbm90aGVyIHNwbGl0dGluZyBvcHRpb246IGUxLT5lMiBhbmQgZTUtPmUzLT5l NAotLS0gQnV0IGZpcnN0bHkgcmVzdG9yZSB0byBvbmUgc2luZ2xlIGxpc3QgZTEtPmUyLT5l My0+ZTQKLS0tCi1lMjpzZXRfcHJldihlMykKLSB8IC0tLQotIHwgLi4uCi1lNTpzZXRfcHJl dihlMykKLSB8IC0tLQotIHwgLi4uCi1hc3NlcnQoZTEucHJldiA9PSBlMikKLSB8IC0tLQot IHwgLSB0cnVlCi0gfCAuLi4KLWFzc2VydChlMi5wcmV2ID09IG5pbCkKLSB8IC0tLQotIHwg LSB0cnVlCi0gfCAuLi4KLWFzc2VydChlNS5wcmV2ID09IGUzKQotIHwgLS0tCi0gfCAtIHRy dWUKLSB8IC4uLgotYXNzZXJ0KGUzLnByZXYgPT0gZTQpCi0gfCAtLS0KLSB8IC0gdHJ1ZQot IHwgLi4uCi1hc3NlcnQoZTQucHJldiA9PSBuaWwpCi0gfCAtLS0KLSB8IC0gdHJ1ZQotIHwg Li4uCi0KIC0tIEluIGNhc2UgZXJyb3IgaXMgZGVzdHJveWVkLCBpdCB1bnJlZnMgcmVmZXJl bmNlIGNvdW50ZXIKIC0tIG9mIGl0cyBwcmV2aW91cyBlcnJvci4gSW4gdHVybiwgYm94LmVy cm9yLmNsZWFyKCkgcmVmcy91bnJlZnMKIC0tIG9ubHkgaGVhZCBhbmQgZG9lc24ndCB0b3Vj aCBvdGhlciBlcnJvcnMuCkBAIC03ODUsNyArNzI5LDMgQEAgYXNzZXJ0KGUxLnByZXYgPT0g ZTIpCiAgfCAtLS0KICB8IC0gdHJ1ZQogIHwgLi4uCi0KLXNwYWNlOmRyb3AoKQotIHwgLS0t Ci0gfCAuLi4KZGlmZiAtLWdpdCBhL3Rlc3QvYm94L2Vycm9yLnRlc3QubHVhIGIvdGVzdC9i b3gvZXJyb3IudGVzdC5sdWEKaW5kZXggNjZhMjJkYjkwLi4wNGUwMDE2OGUgMTAwNjQ0Ci0t LSBhL3Rlc3QvYm94L2Vycm9yLnRlc3QubHVhCisrKyBiL3Rlc3QvYm94L2Vycm9yLnRlc3Qu bHVhCkBAIC0xMDgsNiArMTA4LDggQEAgYm94LmVycm9yLm5ldyhlcnIpCiBib3guZXJyb3Iu Y2xlYXIoKQogYm94LmVycm9yKCkKIAorc3BhY2U6ZHJvcCgpCisKIC0tIGdoLTExNDg6IGVy cm9ycyBjYW4gYmUgYXJyYW5nZWQgaW50byBsaXN0IChzbyBjYWxsZWQKIC0tIHN0YWNrZWQg ZGlhZ25vc3RpY3MpLgogLS0KQEAgLTEyMiwxMiArMTI0LDEzIEBAIGUyOnNldF9wcmV2KGUx KQogYXNzZXJ0KGUyLnByZXYgPT0gbmlsKQogLS0gQXQgdGhpcyBwb2ludCBzdGFjayBpcyBm b2xsb3dpbmc6IGUxIC0+IGUyCiAtLSBMZXQncyB0ZXN0IGZvbGxvd2luZyBjYXNlczoKLS0t IDEuIGUzIC0+IGUyLCBlMSAtPiBOVUxMIChlMzpzZXRfcHJldihlMikpCistLSAxLiBlMyAt PiBlMiwgZTEgLT4gTlVMTCAoZTE6c2V0X3ByZXYobmlsKSwgZTM6c2V0X3ByZXYoZTIpKQog LS0gMi4gZTEgLT4gZTMsIGUyIC0+IE5VTEwgKGUxOnNldF9wcmV2KGUzKSkKIC0tIDMuIGUz IC0+IGUxIC0+IGUyIChlMzpzZXRfcHJldihlMSkpCi0tLSA0LiBlMSAtPiBlMiAtPiBlMyAo ZTI6c2V0X3ByZXYoZTMpKQorLS0gNC4gZTEgLT4gZTIgLT4gZTMgKGUxOnNldF9wcmV2KG5p bCkgZTI6c2V0X3ByZXYoZTMpIGUxOnNldF9wcmV2KGUyKSkKIC0tCiBlMyA9IGJveC5lcnJv ci5uZXcoe2NvZGUgPSAxMTEsIHJlYXNvbiA9ICJhbm90aGVyIGNhdXNlIn0pCitlMTpzZXRf cHJldihuaWwpCiBlMzpzZXRfcHJldihlMikKIGFzc2VydChlMy5wcmV2ID09IGUyKQogYXNz ZXJ0KGUyLnByZXYgPT0gbmlsKQpAQCAtMTM1LDYgKzEzOCw3IEBAIGFzc2VydChlMS5wcmV2 ID09IG5pbCkKIAogLS0gUmVzZXQgc3RhY2sgdG8gZTEgLT4gZTIgYW5kIHRlc3QgY2FzZSAy LgogLS0KK2UzOnNldF9wcmV2KG5pbCkKIGUxOnNldF9wcmV2KGUyKQogYXNzZXJ0KGUyLnBy ZXYgPT0gbmlsKQogYXNzZXJ0KGUzLnByZXYgPT0gbmlsKQpAQCAtMTU2LDExICsxNjAsMTEg QEAgYXNzZXJ0KGUzLnByZXYgPT0gZTEpCiAKIC0tIFVubGluayBlcnJvcnMgYW5kIHRlc3Qg Y2FzZSA0LgogLS0KLWUxOnNldF9wcmV2KG5pbCkKLWUyOnNldF9wcmV2KG5pbCkKIGUzOnNl dF9wcmV2KG5pbCkKLWUxOnNldF9wcmV2KGUyKQorZTI6c2V0X3ByZXYobmlsKQorZTE6c2V0 X3ByZXYobmlsKQogZTI6c2V0X3ByZXYoZTMpCitlMTpzZXRfcHJldihlMikKIGFzc2VydChl MS5wcmV2ID09IGUyKQogYXNzZXJ0KGUyLnByZXYgPT0gZTMpCiBhc3NlcnQoZTMucHJldiA9 PSBuaWwpCkBAIC0xNzMsMzAgKzE3Nyw2IEBAIGFzc2VydChlMy5wcmV2ID09IG5pbCkKIGUz OnNldF9wcmV2KGUyKQogYXNzZXJ0KGUzLnByZXYgPT0gbmlsKQogCi0tLSBUZXN0IHNwbGl0 dGluZyBsaXN0IGludG8gdHdvIG9uZXMuCi0tLSBBZnRlciB0aGF0IHdlIHdpbGwgZ2V0IHR3 byBsaXN0czogZTEtPmUyLT5lNSBhbmQgZTMtPmU0Ci0tLQotZTQgPSBib3guZXJyb3IubmV3 KHtjb2RlID0gMTExLCByZWFzb24gPSAieWV0IGFub3RoZXIgY2F1c2UifSkKLWU1ID0gYm94 LmVycm9yLm5ldyh7Y29kZSA9IDExMSwgcmVhc29uID0gImFuZCBhbm90aGVyIG9uZSJ9KQot ZTM6c2V0X3ByZXYoZTQpCi1lMjpzZXRfcHJldihlNSkKLWFzc2VydChlMS5wcmV2ID09IGUy KQotYXNzZXJ0KGUyLnByZXYgPT0gZTUpCi1hc3NlcnQoZTMucHJldiA9PSBlNCkKLWFzc2Vy dChlNS5wcmV2ID09IG5pbCkKLWFzc2VydChlNC5wcmV2ID09IG5pbCkKLQotLS0gQW5vdGhl ciBzcGxpdHRpbmcgb3B0aW9uOiBlMS0+ZTIgYW5kIGU1LT5lMy0+ZTQKLS0tIEJ1dCBmaXJz dGx5IHJlc3RvcmUgdG8gb25lIHNpbmdsZSBsaXN0IGUxLT5lMi0+ZTMtPmU0Ci0tLQotZTI6 c2V0X3ByZXYoZTMpCi1lNTpzZXRfcHJldihlMykKLWFzc2VydChlMS5wcmV2ID09IGUyKQot YXNzZXJ0KGUyLnByZXYgPT0gbmlsKQotYXNzZXJ0KGU1LnByZXYgPT0gZTMpCi1hc3NlcnQo ZTMucHJldiA9PSBlNCkKLWFzc2VydChlNC5wcmV2ID09IG5pbCkKLQogLS0gSW4gY2FzZSBl cnJvciBpcyBkZXN0cm95ZWQsIGl0IHVucmVmcyByZWZlcmVuY2UgY291bnRlcgogLS0gb2Yg aXRzIHByZXZpb3VzIGVycm9yLiBJbiB0dXJuLCBib3guZXJyb3IuY2xlYXIoKSByZWZzL3Vu cmVmcwogLS0gb25seSBoZWFkIGFuZCBkb2Vzbid0IHRvdWNoIG90aGVyIGVycm9ycy4KQEAg LTIxMiw1ICsxOTIsMyBAQCBhc3NlcnQoZTIuY29kZSA9PSAxMTEpCiBib3guZXJyb3Iuc2V0 KGUxKQogYm94LmVycm9yLmNsZWFyKCkKIGFzc2VydChlMS5wcmV2ID09IGUyKQotCi1zcGFj ZTpkcm9wKCkK --------------4392EAB8059CB44410E970DC--