Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w6vM3-004mn4-0I for pgsql-hackers@arkaria.postgresql.org; Sun, 29 Mar 2026 18:59:23 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w6vM0-00H5IN-1f for pgsql-hackers@arkaria.postgresql.org; Sun, 29 Mar 2026 18:59:20 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1w6vLz-00H5IE-34 for pgsql-hackers@lists.postgresql.org; Sun, 29 Mar 2026 18:59:20 +0000 Received: from mail-qt1-x82d.google.com ([2607:f8b0:4864:20::82d]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w6vLx-00000001gWQ-1P8O for pgsql-hackers@lists.postgresql.org; Sun, 29 Mar 2026 18:59:19 +0000 Received: by mail-qt1-x82d.google.com with SMTP id d75a77b69052e-50335b926c2so32342421cf.2 for ; Sun, 29 Mar 2026 11:59:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1774810756; cv=none; d=google.com; s=arc-20240605; b=hc5zxJJUpdjYSk6gCh0BwZ4eYg/7dqo974m/bkvJWl2GVFgezZ6SOrLgbtVWwQL/ny xT4ZTZeYnGMXwjStOd4sezpbCcMNSXMNgqXAS6zoSP7/Qmz+umfKHA0BFNq3sJKfAfes y2t4iXFTdtliQII+FKduksa9iRQsOcnUCHlHSw2Z5PXpI67f9N6bK5UD19b0OtlBUT0b C7XBk+krjNkT8V8wuy0SUubiarNwf7MWRV/px9an9f2M2Kuqvs8zx12E01QqkOjQAVbU OvtxGEfKrcXbv7GIRuG1gx+oaCg7odT+dOos+XcNwD5T9HKc3jWOv5AX5Ik4fMPAvgly Yvdw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=fpwzk3e4FcpMXHYALHoWuNIv+xiRJmFVrTe0FzmKEGc=; fh=uqMBBb8rRpy/KNvPodspwU7qaDKnb/3bXPPD3GhdGZE=; b=E0x2SahyRDgGD5wQAwo+wgN5piepDl/hvpMCZOxy+vLnq0iOEM2MYItKyqXOgWxqJA Ua6qhmc1vc+zz5kkfM/lhIsj3L/F5zYqGVxKXyQVYi0Z/4uvx4pAf4pZSJnO+tfQ0Co5 YioIEfvsEy5DAxjPFs1DW+6Gs+ickuAgXmEHKs1SIiZMLk2/PPBulBwX0EshhRB//5mw lY5KY6OCWCn6cpVNpDmPH+Yra9fGfCqPY2mLICT4a4BnzbT5pJaOFlLfPKbyx8mNQomR xv2yJjiK0zzusu5fsJj1ae6jcCzCASfhrvnXKev+yQNTRRBmAN5Jhd/RqX5Xw4z83HT1 KOzw==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fittl.com; s=google; t=1774810756; x=1775415556; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=fpwzk3e4FcpMXHYALHoWuNIv+xiRJmFVrTe0FzmKEGc=; b=bMbbm6ak/waWZDYldGIqmI4o9SN+5fQ9zlyug+nRvBryJzdAzCjUOqSG46q2Bk8D7Q 6e17lsyYhNNWj/2crWhaR2hfwjZJEv2qvA/9StXSCOxicVER+YbZDay0zucc9P71vC5x lDlFWhR094Zu7Z4B7VNQ2d5SQVIciFpg/pQlk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774810756; x=1775415556; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=fpwzk3e4FcpMXHYALHoWuNIv+xiRJmFVrTe0FzmKEGc=; b=YnHeEU35BKuxi1f40Y+ISLRTuguvbKmCarDv/f9faYL/TfEJAhpEmALp5GKOWvsUVi 11cW1s/LGiAOpZ37udrFWOLFGSKDHGUNfdL4XGxhui6RkKtI4GV2cXMFdbui6yqxRYq6 2TBvUTF9vlT5eIJOCCAox807yNtoYKSez3pmAd6kCmfaudNAa98KEXsOBTXqTlS2gAYX AdMc2lwZrfy+qx/TKyCfI0RMqgAH0mEj1xikOXZRvpVrjs/N+iF4mxS6mqoYNRJRHa39 esEq5BswLqXSo6gROBeSMGMhePQimmTX+F9oN+cRmeQbcbqToVd5jj9QZ+A4uedbWGud 3CEg== X-Forwarded-Encrypted: i=1; AJvYcCWzfOX41zBSxn+t8GHPFrbh4z7E+E6NYK24D6guA17cdCoQRAfDPDRrX6x9lNOiV9aTWhH9948Gh/l9AVV5@lists.postgresql.org X-Gm-Message-State: AOJu0Yy7eOvqVCTzOF9KZYY4vdvTkW//9yEgpbOT78muHEhTuBlr8Q6T EHTYhdL+P5phc9eXIHX6YHX6JBF6ImPCDLuXbX4o3TILFkU30Sq9jZImRZ12CbXa0RxgY3HOAZ5 /daAGtSOs4FRz9KLv3bgFe9RxMi8Z7gh9XnlgnkRo X-Gm-Gg: ATEYQzzoVejETvJURD92dhbyzPXhHPGeMqT/eeVc9sgvPpttYF/Pl4kr6Y0hp5UHtHG 0yON/9FhUjg7MGOuuwbe54simCwda+BbeMX29bQBZhpvPehMpoJs/ifVPB8Pf0BVEz8Yw3kE18A uI/EIiXv28Lq80JdxHyoqCOMWLq7NFqD+cpZITirXfELuZQN+J6z7PqCG+OCKojo8/TYYWRZGkj 4dmuutRtDovhSpEmjhn3hdRRgmnFU++Yx1w+GVJex4hdPW1ZwJFvcCfFMizjdF3b0HwvAbzKx/q +I1iimVqqzepv0Pjxs2ua2Tin7Ld7tbKhK4az6cNsF+ZE4+YYQ8= X-Received: by 2002:a05:622a:1e96:b0:50b:3e24:f9b8 with SMTP id d75a77b69052e-50ba37ef616mr139212461cf.14.1774810756387; Sun, 29 Mar 2026 11:59:16 -0700 (PDT) MIME-Version: 1.0 References: <1136161.1769654478@sss.pgh.pa.us> <1299934.1773938807@sss.pgh.pa.us> In-Reply-To: From: Lukas Fittl Date: Sun, 29 Mar 2026 11:58:39 -0700 X-Gm-Features: AQROBzDF29b1ZvG2taxVTHeTD_J8iX1Sq85zoYKnDE5tE-vhs3Smf4W2lyXIQ18 Message-ID: Subject: Re: pg_plan_advice To: Robert Haas Cc: Jakub Wartak , Tom Lane , PostgreSQL Hackers Content-Type: multipart/mixed; boundary="000000000000adfef8064e2e5406" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000adfef8064e2e5406 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Robert, On Fri, Mar 27, 2026 at 8:44=E2=80=AFAM Robert Haas = wrote: > > On Fri, Mar 27, 2026 at 4:31=E2=80=AFAM Lukas Fittl wro= te: > > For the other one 0004 (pg_stash_advice) I feel its worth trying to > > get it in, if we can figure out the remaining issues. I'll try to do > > another pass on that tomorrow after some sleep. > > Let me just talk a little about the way that I see the space of > possible designs here. Let's set aside what we do or do not have time > to code for a moment and just think about what makes some kind of > sense in theory. I believe we can divide this up along a few different > axes: > > 1. Where is advice stored for on-the-fly retrieval? Possible answers > include: in shared memory, in local memory, in a table, on disk. But > realistically, I doubt that "in a table" is a realistic option. Even > if we hard-coded a direct index lookup i.e. without going through the > query planner, I think this would be a fairly expensive thing to do > for every query, and if this is going to be usable on production > systems, it has to be fast. I am absolutely certain that "on disk" is > not a realistic option. Local memory is an option. It has the > advantage of making server-lifespan memory leaks impossible, and the > further advantage of avoiding contention between different backends, > since each backend would have its own copy of the data. The big > disadvantage is memory consumption. If we think the advice store is > going to be small, then that might be fine, but somebody is > potentially going to have thousands of advice strings stored, > duplicating that across hundreds (or, gulp, thousands) of backends is > pretty bad. I've been pondering this particular question for the last few days (because pg_hint_plan uses a table, so in a sense the question is, why not do that), and I've come to the conclusion that I think your choice of shared memory seems reasonable, especially in combination with the stash GUC being a way to control which stash gets used. I don't think local memory makes as much sense, because realistically one would want their advice applied to all backends, and whilst we could invent some synchronization mechanism, that seems more brittle than managing shared memory. The other problem of using a table (if we were to go that route), besides performance overhead, is that advice would have to be tied to individual databases where the extension was created - and for multi-tenant use cases where you have a one-customer-per-database setup, it'd basically be unusable. I think the combination of shared memory and the GUC mechanism would work really well for that since you could pick the advice stash to use for a given database using ALTER DATABASE, without repeating the advice definitions. It is worth noting in such a use case, one could still have a problem with queryids being different between databases, but as of 787514b30bb ("Use relation name instead of OID in query jumbling for RangeTblEntry") that should no longer be the case, if the schemas/queries match. > > 2. What provision do we have for durability? Possible answers include: > in a table, on disk, nothing. I went with nothing, partly on the > theory that it gives users more flexibility. We don't really care > where they store their query IDs and advice strings, as long as they > have a way to feed them into the mechanism. But of course I was also > trying to save myself implementation complexity. There are some tricky > things about a table: as implemented, the advice stores are > cluster-wide objects, but tables are database objects. If we're > supposed to automatically load advice strings from a table that might > be in another database into an in-memory store, well, we can't. That > could be fixed by scoping stores to a specific database, which would > be inconvenient only for users who have the same schema in multiple > databases and would want to share stashes across DBs, which is > probably not common. A disk file is also an option. It requires > inventing some kind of custom format that we can generate and parse, > which has some complexity, but reading from a table has some > complexity too; I'm not sure which is messier. I think a simple disk file is the way to go, similar to how autoprewarm works with its "autoprewarm.blocks" file. Its a bit awkward that that just sits in the main data directory, but since pg_prewarm already does it today, I think its okay to have another contrib module do the same. As noted I'm mainly worried about restarts that the user didn't control, causing advice that was set to be lost. I've attached a patch of how that could look like on top of your v23, that copies the modified stash information to a "pg_stash_advice.entries" file, and loads it after restarts. > 3. How do we limit memory usage? One possible approach involves > limiting the size of the hash table by entries or by memory > consumption, but I don't think that's too valuable if that's all we > do, because presumably all that's going to do is annoy people who hit > the limit. It could make sense if we switched to a design where the > superuser creates the stash, assigns it a memory limit, and then > there's a way to give permission to use that stash to some particular > user who is bound by the memory limit. In that kind of design, the > person setting aside the memory has different and superior privileges > to the person using it, so the cap serves a real purpose. A > complicating factor here is that dshash doesn't seem to be well set up > to enforce memory limits. You can do it if each dshash uses a separate > DSA, but that's clunky, too. A completely different direction is to > treat the in-memory component of the system as a cache, backed by a > table or file from which cold entries are retrieved as needed. The > problem with this - and I think it's a pretty big problem - is that > performance will probably fall off a cliff as soon as you overflow the > cache. I mean, it might not, if most of the requests can be satisfied > from cache and a small percentage get fetched from cold storage, but > if it's a case where a uniformly-accessed working set is 10% larger > than the cache, the cache hit ratio will go down the tubes and so will > performance. Because the number of entries here is controlled by the user (i.e. its not a function of the workload, but a function of how much advice you as a user have set), I'm much less worried about memory usage, as long as we document it clearly how to measure the amount of memory used. We could also consider having a parameter that sets a maximum size/number of entries, and require you to remove entries if that is exceeded. I agree on your concerns that a hybrid design (i.e. one that falls back to on-disk) has a performance cliff that will be unexpected. I don't think we need to solve for this use case of having that many advice strings for now, as I think the main utility of pg_stash_advice is to fix a handful of badly behaving queries through manual intervention, not to automatically fix thousands of them. > 4. How do we match advice strings to queries? The query ID is the > obvious answer, but you could also think of having an option to match > on query text, for cases when query IDs collide. You could do > something like store a tag in the query string or in a GUC and look > that up, instead of the query ID, but then I'm not sure why you don't > just store the advice string instead of the tag, and then you don't > need a hash table lookup anymore. You could do some kind of pattern > matching on the query string rather than using the query ID, but that > feels like it would be hard to get right, and also probably more > expensive. There are probably other options here but I don't know what > they are. I doubt that it makes sense from a performance standpoint to > delegate out to a function written in a high-level language, and if > you want to delegate to C code then you can just forget about > pg_stash_advice and just use the add_advisor hook directly. I really > feel like I'm probably missing some possible techniques, here. I > wonder if other people will come up with some clever ideas. I think for what makes sense in tree at this point, simple queryid matching is the way to go. I'm sure there are better ways to do matching of queries (i.e. make it dependent on parameters in some way, be smart about significant table size changes, etc), but we can let the community iterate on that out of tree, since they can just build an extension like pg_stash_advice that use the functions provided by pg_plan_advice. > 5. What should the security model be? Right now it's as simple as can > be: the superuser gets to decide who can use the mechanism. But also, > not to be overlooked, an individual session can always opt out of > automatic advice application by clearing the stash_name GUC. It > shouldn't be possible to force wrong answers on another session even > if you can impose arbitrary plan_advice, but there is a good chance > that you could find a way to make their session catastrophically slow, > so it's good that users can opt themselves out of the mechanism. > Nonetheless, if we really want to have mutually untrusting users be > able to use this facility, then stashes should have owners, and you > should only be able to access a stash whose owner has authorized you > to do so. This is all a bit awkward because there's no way for an > extension to integrate with the built-in permissions mechanisms for > handling e.g. dropped users, and in-memory objects are a poor fit > anyway. Also, all of this is bound to have a performance cost: if > every access to a stash involves permissions checking, that's going to > add a possibly-significant amount of overhead to a code path that > might be very hot. And, in many environments, that permissions check > would be a complete waste of cycles. Things could maybe be simplified > by deciding that stash access can't be delegated: a stash has one and > only one owner, and it can affect only that user and not any other. > That is unlike what we do for built-in objects, but it simplifies the > permissions check to strcmp(), which is super-cheap compared to > catalog lookups. All in all, I don't really know which way to jump > here: what I've got right now looks almost stupidly primitive, and I > suspect it is, but adding complexity along what seem to be the obvious > lines isn't an obvious win, either. I think the current trade-off is probably okay in terms of requiring a superuser or its equivalent to grant access to create stash entries, and allow unprivileged users to opt out of applied advice. In practice for a good amount of our user base these days the question will be "Does my cloud provider give me access to create stash entries", so its maybe worth thinking about if we could also allow pg_maintain to manage entries by default? > 6. How do we tell users when there's a problem? Right now, the only > available answer is to set pg_plan_advice.feedback_warnings, which I > don't think is unreasonable. If you're using advice as intended, i.e. > only for particular queries that really need it, then it really > shouldn't be generating any output unless something's gone wrong, but > I also don't think everyone is going to want this information going to > the main log file. Somehow percolating the advice feedback back to the > advisor that provided it -- pg_stash_advice or whatever -- feels like > a thing that is probably worth doing. pg_stash_advice could then > summarize the feedback and provide reports: hey, look, of the 100 > queries for which you stashed advice, 97 of them always showed /* > matched */ for every item of advice, but the last 3 had varying > numbers of other results. Being able to query that via SQL seems like > it would be quite useful. I tend to think that it's almost a given > that we're going to eventually want something like this, but the > details aren't entirely clear to me. It could for example be developed > as a separate extension that can work for any advisor, rather than > being coupled to pg_stash_advice specifically -- but I'm also not > saying that's better, and I think it might be worse. Figuring out > exactly what we want to do here is a lot less critical than the items > mentioned above because, no matter what we do about any of those > things, this can always be added afterwards if and when desired. But, > I'm mentioning it for completeness. I think figuring out a feedback mechanism would be a good thing, but we could definitely add that in a later release without a major design change of pg_stash_advice, I think. And as you note, pg_plan_advice.feedback_warnings exists as a mechanism today to validate whether advice was applied as expected. > If there are other design axes we should be talking about, I'm keen to > hear them. This is just what came to mind off-hand. Of course, I'm > also interested in everyone's views on what the right decisions are > from among the available options (or other options they may have in > mind). I can't think of other angles at this point, at least not in the context of what it makes sense to do in-tree for this release. Thanks, Lukas --=20 Lukas Fittl --000000000000adfef8064e2e5406 Content-Type: application/octet-stream; name="nocfbot-0001-Make-pg_stash_advice-dump-advice-to-disk-wh.patch" Content-Disposition: attachment; filename="nocfbot-0001-Make-pg_stash_advice-dump-advice-to-disk-wh.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mnc4dizm0 RnJvbSA2YzAyZmM5MzE4ZWYxOWMxNWIwMGFkNTM3NmI3NzE3YmZhOTI3MjVmIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBMdWthcyBGaXR0bCA8bHVrYXNAZml0dGwuY29tPgpEYXRlOiBT dW4sIDI5IE1hciAyMDI2IDExOjQ3OjI3IC0wNzAwClN1YmplY3Q6IFtQQVRDSCB2bm9jZmJvdF0g TWFrZSBwZ19zdGFzaF9hZHZpY2UgZHVtcCBhZHZpY2UgdG8gZGlzayB3aGVuCiBjaGFuZ2VkLCBs b2FkIGFmdGVyIHJlc3RhcnQKCi0tLQogY29udHJpYi9wZ19zdGFzaF9hZHZpY2UvcGdfc3Rhc2hf YWR2aWNlLmMgfCAzNTYgKysrKysrKysrKysrKysrKysrKysrKwogZG9jL3NyYy9zZ21sL3Bnc3Rh c2hhZHZpY2Uuc2dtbCAgICAgICAgICAgfCAgMTAgKy0KIDIgZmlsZXMgY2hhbmdlZCwgMzYyIGlu c2VydGlvbnMoKyksIDQgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvY29udHJpYi9wZ19zdGFz aF9hZHZpY2UvcGdfc3Rhc2hfYWR2aWNlLmMgYi9jb250cmliL3BnX3N0YXNoX2FkdmljZS9wZ19z dGFzaF9hZHZpY2UuYwppbmRleCAyMjEyMjIzNjY5NC4uN2RjNTI0ODU2MTcgMTAwNjQ0Ci0tLSBh L2NvbnRyaWIvcGdfc3Rhc2hfYWR2aWNlL3BnX3N0YXNoX2FkdmljZS5jCisrKyBiL2NvbnRyaWIv cGdfc3Rhc2hfYWR2aWNlL3BnX3N0YXNoX2FkdmljZS5jCkBAIC0xOCw2ICsxOCw4IEBACiAgKi8K ICNpbmNsdWRlICJwb3N0Z3Jlcy5oIgogCisjaW5jbHVkZSA8dW5pc3RkLmg+CisKICNpbmNsdWRl ICJjb21tb24vaGFzaGZuLmgiCiAjaW5jbHVkZSAiY29tbW9uL3N0cmluZy5oIgogI2luY2x1ZGUg ImZtZ3IuaCIKQEAgLTI2LDEyICsyOCwxNSBAQAogI2luY2x1ZGUgIm5vZGVzL3F1ZXJ5anVtYmxl LmgiCiAjaW5jbHVkZSAicGdfcGxhbl9hZHZpY2UuaCIKICNpbmNsdWRlICJzdG9yYWdlL2RzbV9y ZWdpc3RyeS5oIgorI2luY2x1ZGUgInN0b3JhZ2UvZmQuaCIKICNpbmNsdWRlICJzdG9yYWdlL2x3 bG9jay5oIgogI2luY2x1ZGUgInV0aWxzL2J1aWx0aW5zLmgiCiAjaW5jbHVkZSAidXRpbHMvZ3Vj LmgiCiAjaW5jbHVkZSAidXRpbHMvbWVtdXRpbHMuaCIKICNpbmNsdWRlICJ1dGlscy90dXBsZXN0 b3JlLmgiCiAKKyNkZWZpbmUgUEdTQV9EVU1QX0ZJTEUJCSJwZ19zdGFzaF9hZHZpY2UuZW50cmll cyIKKwogUEdfTU9EVUxFX01BR0lDOwogCiBQR19GVU5DVElPTl9JTkZPX1YxKHBnX2NyZWF0ZV9h ZHZpY2Vfc3Rhc2gpOwpAQCAtNTAsNiArNTUsNyBAQCB0eXBlZGVmIHN0cnVjdCBwZ3NhX3NoYXJl ZF9zdGF0ZQogCWRzYV9oYW5kbGUJYXJlYTsKIAlkc2hhc2hfdGFibGVfaGFuZGxlIHN0YXNoX2hh c2g7CiAJZHNoYXNoX3RhYmxlX2hhbmRsZSBlbnRyeV9oYXNoOworCWJvb2wJCWZpbGVfbG9hZGVk OwogfSBwZ3NhX3NoYXJlZF9zdGF0ZTsKIAogdHlwZWRlZiBzdHJ1Y3QgcGdzYV9zdGFzaApAQCAt MTU0LDYgKzE2MCwxMCBAQCBzdGF0aWMgdm9pZCBwZ3NhX2luaXRfc2hhcmVkX3N0YXRlKHZvaWQg KnB0ciwgdm9pZCAqYXJnKTsKIHN0YXRpYyB1aW50NjQgcGdzYV9sb29rdXBfc3Rhc2hfaWQoY2hh ciAqc3Rhc2hfbmFtZSk7CiBzdGF0aWMgdm9pZCBwZ3NhX3NldF9hZHZpY2Vfc3RyaW5nKGNoYXIg KnN0YXNoX25hbWUsIGludDY0IHF1ZXJ5SWQsCiAJCQkJCQkJCSAgIGNoYXIgKmFkdmljZV9zdHJp bmcpOworc3RhdGljIHZvaWQgcGdzYV9kdW1wX3RvX2ZpbGUodm9pZCk7CitzdGF0aWMgdm9pZCBw Z3NhX2xvYWRfZnJvbV9maWxlKHZvaWQpOworc3RhdGljIGNoYXIgKnBnc2FfZXNjYXBlX3N0cmlu ZyhjaGFyICpzdHIpOworc3RhdGljIGNoYXIgKnBnc2FfdW5lc2NhcGVfc3RyaW5nKGNoYXIgKnN0 cik7CiAKIC8qCiAgKiBJbml0aWFsaXplIHRoaXMgbW9kdWxlLgpAQCAtMjAxLDYgKzIxMSw3IEBA IHBnX2NyZWF0ZV9hZHZpY2Vfc3Rhc2goUEdfRlVOQ1RJT05fQVJHUykKIAlMV0xvY2tBY3F1aXJl KCZwZ3NhX3N0YXRlLT5sb2NrLCBMV19FWENMVVNJVkUpOwogCXBnc2FfY3JlYXRlX3N0YXNoKHN0 YXNoX25hbWUpOwogCUxXTG9ja1JlbGVhc2UoJnBnc2Ffc3RhdGUtPmxvY2spOworCXBnc2FfZHVt cF90b19maWxlKCk7CiAJUEdfUkVUVVJOX1ZPSUQoKTsKIH0KIApAQCAtMjE4LDYgKzIyOSw3IEBA IHBnX2Ryb3BfYWR2aWNlX3N0YXNoKFBHX0ZVTkNUSU9OX0FSR1MpCiAJTFdMb2NrQWNxdWlyZSgm cGdzYV9zdGF0ZS0+bG9jaywgTFdfRVhDTFVTSVZFKTsKIAlwZ3NhX2Ryb3Bfc3Rhc2goc3Rhc2hf bmFtZSk7CiAJTFdMb2NrUmVsZWFzZSgmcGdzYV9zdGF0ZS0+bG9jayk7CisJcGdzYV9kdW1wX3Rv X2ZpbGUoKTsKIAlQR19SRVRVUk5fVk9JRCgpOwogfQogCkBAIC00NDEsNiArNDUzLDcgQEAgcGdf c2V0X3N0YXNoZWRfYWR2aWNlKFBHX0ZVTkNUSU9OX0FSR1MpCiAJCXBnc2Ffc2V0X2FkdmljZV9z dHJpbmcoc3Rhc2hfbmFtZSwgcXVlcnlJZCwgYWR2aWNlX3N0cmluZyk7CiAJfQogCisJcGdzYV9k dW1wX3RvX2ZpbGUoKTsKIAlQR19SRVRVUk5fVk9JRCgpOwogfQogCkBAIC02MTQsNiArNjI3LDIx IEBAIHBnc2FfYXR0YWNoKHZvaWQpCiAKIAkvKiBSZXN0b3JlIHByZXZpb3VzIG1lbW9yeSBjb250 ZXh0LiAqLwogCU1lbW9yeUNvbnRleHRTd2l0Y2hUbyhvbGRjb250ZXh0KTsKKworCS8qCisJICog SWYgdGhlIHNoYXJlZCBzdGF0ZSB3YXMganVzdCBjcmVhdGVkIChpLmUuIGFmdGVyIGEgc2VydmVy IHJlc3RhcnQgb3IKKwkgKiBjcmFzaCksIHRyeSB0byByZXN0b3JlIHN0YXNoIGRhdGEgZnJvbSB0 aGUgZHVtcCBmaWxlLiBVc2UgdGhlCisJICogZmlsZV9sb2FkZWQgZmxhZyB1bmRlciB0aGUgbG9j ayB0byBlbnN1cmUgb25seSBvbmUgYmFja2VuZCBkb2VzIHRoaXMuCisJICovCisJTFdMb2NrQWNx dWlyZSgmcGdzYV9zdGF0ZS0+bG9jaywgTFdfRVhDTFVTSVZFKTsKKwlpZiAoIXBnc2Ffc3RhdGUt PmZpbGVfbG9hZGVkKQorCXsKKwkJcGdzYV9zdGF0ZS0+ZmlsZV9sb2FkZWQgPSB0cnVlOworCQlM V0xvY2tSZWxlYXNlKCZwZ3NhX3N0YXRlLT5sb2NrKTsKKwkJcGdzYV9sb2FkX2Zyb21fZmlsZSgp OworCX0KKwllbHNlCisJCUxXTG9ja1JlbGVhc2UoJnBnc2Ffc3RhdGUtPmxvY2spOwogfQogCiAv KgpAQCAtNzk2LDYgKzgyNCw3IEBAIHBnc2FfaW5pdF9zaGFyZWRfc3RhdGUodm9pZCAqcHRyLCB2 b2lkICphcmcpCiAJc3RhdGUtPmFyZWEgPSBEU0FfSEFORExFX0lOVkFMSUQ7CiAJc3RhdGUtPnN0 YXNoX2hhc2ggPSBEU0hBU0hfSEFORExFX0lOVkFMSUQ7CiAJc3RhdGUtPmVudHJ5X2hhc2ggPSBE U0hBU0hfSEFORExFX0lOVkFMSUQ7CisJc3RhdGUtPmZpbGVfbG9hZGVkID0gZmFsc2U7CiB9CiAK IC8qCkBAIC04OTgsMyArOTI3LDMzMCBAQCBwZ3NhX3NldF9hZHZpY2Vfc3RyaW5nKGNoYXIgKnN0 YXNoX25hbWUsIGludDY0IHF1ZXJ5SWQsIGNoYXIgKmFkdmljZV9zdHJpbmcpCiAJCWRzYV9mcmVl KHBnc2FfZHNhX2FyZWEsIG9sZF9kcCk7CiAJTFdMb2NrUmVsZWFzZSgmcGdzYV9zdGF0ZS0+bG9j ayk7CiB9CisKKy8qCisgKiBEdW1wIGFsbCBhZHZpY2Ugc3Rhc2ggZGF0YSB0byBhIGZpbGUuCisg KgorICogVGhlIGZpbGUgZm9ybWF0IGlzIGEgc2ltcGxlIHRleHQgZm9ybWF0OgorICogICBMaW5l IDE6IDw8bnVtX3N0YXNoZXM+PgorICogICBOZXh0IG51bV9zdGFzaGVzIGxpbmVzOiBvbmUgc3Rh c2ggbmFtZSBwZXIgbGluZQorICogICBSZW1haW5pbmcgbGluZXM6IHN0YXNoX25hbWVcdHF1ZXJ5 X2lkXHRhZHZpY2Vfc3RyaW5nCisgKgorICogU3Rhc2ggbmFtZXMgYW5kIGFkdmljZSBzdHJpbmdz IGFyZSBiYWNrc2xhc2gtZXNjYXBlZCB3aGVyZSBuZWVkZWQuCisgKi8KK3N0YXRpYyB2b2lkCitw Z3NhX2R1bXBfdG9fZmlsZSh2b2lkKQoreworCUZJTEUJICAgKmZpbGU7CisJY2hhcgkJdHJhbnNp ZW50X2R1bXBfZmlsZV9wYXRoW01BWFBHUEFUSF07CisJZHNoYXNoX3NlcV9zdGF0dXMgaXRlcjsK KwlwZ3NhX3N0YXNoICpzdGFzaDsKKwlwZ3NhX2VudHJ5ICplbnRyeTsKKwlwZ3NhX3N0YXNoX25h bWVfdGFibGVfaGFzaCAqbmhhc2g7CisJaW50CQkJbnVtX3N0YXNoZXMgPSAwOworCWludAkJCXJl dDsKKworCUFzc2VydChwZ3NhX2VudHJ5X2RzaGFzaCAhPSBOVUxMKTsKKworCS8qIE9wZW4gYSB0 ZW1wb3JhcnkgZmlsZSBmb3Igd3JpdGluZy4gKi8KKwlzbnByaW50Zih0cmFuc2llbnRfZHVtcF9m aWxlX3BhdGgsIE1BWFBHUEFUSCwgIiVzLnRtcCIsIFBHU0FfRFVNUF9GSUxFKTsKKwlmaWxlID0g QWxsb2NhdGVGaWxlKHRyYW5zaWVudF9kdW1wX2ZpbGVfcGF0aCwgInciKTsKKwlpZiAoIWZpbGUp CisJCWVyZXBvcnQoRVJST1IsCisJCQkJKGVycmNvZGVfZm9yX2ZpbGVfYWNjZXNzKCksCisJCQkJ IGVycm1zZygiY291bGQgbm90IG9wZW4gZmlsZSBcIiVzXCI6ICVtIiwKKwkJCQkJCXRyYW5zaWVu dF9kdW1wX2ZpbGVfcGF0aCkpKTsKKworCS8qCisJICogQnVpbGQgYW4gSUQtPm5hbWUgbG9va3Vw IHRhYmxlLiBXZSBhbHNvIHVzZSB0aGlzIHRvIGNvdW50IHN0YXNoZXMgKGZvcgorCSAqIHRoZSBo ZWFkZXIpIGFuZCB0byB3cml0ZSBzdGFzaCBuYW1lcyBhZnRlciB0aGUgaGVhZGVyLgorCSAqLwor CW5oYXNoID0gcGdzYV9zdGFzaF9uYW1lX3RhYmxlX2NyZWF0ZShDdXJyZW50TWVtb3J5Q29udGV4 dCwgNjQsIE5VTEwpOworCWRzaGFzaF9zZXFfaW5pdCgmaXRlciwgcGdzYV9zdGFzaF9kc2hhc2gs IHRydWUpOworCXdoaWxlICgoc3Rhc2ggPSBkc2hhc2hfc2VxX25leHQoJml0ZXIpKSAhPSBOVUxM KQorCXsKKwkJcGdzYV9zdGFzaF9uYW1lICpuOworCQlib29sCQlmb3VuZDsKKworCQluID0gcGdz YV9zdGFzaF9uYW1lX3RhYmxlX2luc2VydChuaGFzaCwgc3Rhc2gtPnBnc2Ffc3Rhc2hfaWQsICZm b3VuZCk7CisJCUFzc2VydCghZm91bmQpOworCQluLT5uYW1lID0gcHN0cmR1cChzdGFzaC0+bmFt ZSk7CisJCW51bV9zdGFzaGVzKys7CisJfQorCWRzaGFzaF9zZXFfdGVybSgmaXRlcik7CisKKwkv KiBXcml0ZSB0aGUgaGVhZGVyIGFuZCBzdGFzaCBuYW1lcy4gKi8KKwlyZXQgPSBmcHJpbnRmKGZp bGUsICI8PCVkPj5cbiIsIG51bV9zdGFzaGVzKTsKKwlpZiAocmV0ID49IDApCisJeworCQlwZ3Nh X3N0YXNoX25hbWVfdGFibGVfaXRlcmF0b3IgaTsKKworCQlwZ3NhX3N0YXNoX25hbWVfdGFibGVf c3RhcnRfaXRlcmF0ZShuaGFzaCwgJmkpOworCQl3aGlsZSAocmV0ID49IDApCisJCXsKKwkJCXBn c2Ffc3Rhc2hfbmFtZSAqbiA9IHBnc2Ffc3Rhc2hfbmFtZV90YWJsZV9pdGVyYXRlKG5oYXNoLCAm aSk7CisKKwkJCWlmIChuID09IE5VTEwpCisJCQkJYnJlYWs7CisJCQlyZXQgPSBmcHJpbnRmKGZp bGUsICIlc1xuIiwgcGdzYV9lc2NhcGVfc3RyaW5nKG4tPm5hbWUpKTsKKwkJfQorCX0KKworCS8q IFdyaXRlIGVudHJpZXM6IGVzY2FwZWRfc3Rhc2hfbmFtZVx0cXVlcnlfaWRcdGVzY2FwZWRfYWR2 aWNlLiAqLworCWlmIChyZXQgPj0gMCkKKwl7CisJCWRzaGFzaF9zZXFfaW5pdCgmaXRlciwgcGdz YV9lbnRyeV9kc2hhc2gsIHRydWUpOworCQl3aGlsZSAoKGVudHJ5ID0gZHNoYXNoX3NlcV9uZXh0 KCZpdGVyKSkgIT0gTlVMTCkKKwkJeworCQkJcGdzYV9zdGFzaF9uYW1lICpuOworCQkJY2hhcgkg ICAqYWR2aWNlX3N0cmluZzsKKworCQkJaWYgKGVudHJ5LT5hZHZpY2Vfc3RyaW5nID09IEludmFs aWREc2FQb2ludGVyKQorCQkJCWNvbnRpbnVlOworCisJCQluID0gcGdzYV9zdGFzaF9uYW1lX3Rh YmxlX2xvb2t1cChuaGFzaCwgZW50cnktPmtleS5wZ3NhX3N0YXNoX2lkKTsKKwkJCWlmIChuID09 IE5VTEwpCisJCQkJY29udGludWU7CQkvKiBvcnBoYW4gZW50cnksIHNraXAgKi8KKworCQkJYWR2 aWNlX3N0cmluZyA9IGRzYV9nZXRfYWRkcmVzcyhwZ3NhX2RzYV9hcmVhLAorCQkJCQkJCQkJCQll bnRyeS0+YWR2aWNlX3N0cmluZyk7CisJCQlyZXQgPSBmcHJpbnRmKGZpbGUsICIlc1x0JSIgUFJJ ZDY0ICJcdCVzXG4iLAorCQkJCQkJICBwZ3NhX2VzY2FwZV9zdHJpbmcobi0+bmFtZSksCisJCQkJ CQkgIGVudHJ5LT5rZXkucXVlcnlJZCwKKwkJCQkJCSAgcGdzYV9lc2NhcGVfc3RyaW5nKGFkdmlj ZV9zdHJpbmcpKTsKKwkJCWlmIChyZXQgPCAwKQorCQkJCWJyZWFrOworCQl9CisJCWRzaGFzaF9z ZXFfdGVybSgmaXRlcik7CisJfQorCisJLyogSGFuZGxlIGFueSB3cml0ZSBlcnJvci4gKi8KKwlp ZiAocmV0IDwgMCkKKwl7CisJCWludAkJCXNhdmVfZXJybm8gPSBlcnJubzsKKworCQlGcmVlRmls ZShmaWxlKTsKKwkJdW5saW5rKHRyYW5zaWVudF9kdW1wX2ZpbGVfcGF0aCk7CisJCWVycm5vID0g c2F2ZV9lcnJubzsKKwkJZXJlcG9ydChFUlJPUiwKKwkJCQkoZXJyY29kZV9mb3JfZmlsZV9hY2Nl c3MoKSwKKwkJCQkgZXJybXNnKCJjb3VsZCBub3Qgd3JpdGUgdG8gZmlsZSBcIiVzXCI6ICVtIiwK KwkJCQkJCXRyYW5zaWVudF9kdW1wX2ZpbGVfcGF0aCkpKTsKKwl9CisKKwkvKiBDbG9zZSB0aGUg ZmlsZSBhbmQgcmVuYW1lIGl0IGludG8gcGxhY2UgYXRvbWljYWxseS4gKi8KKwlyZXQgPSBGcmVl RmlsZShmaWxlKTsKKwlpZiAocmV0ICE9IDApCisJeworCQlpbnQJCQlzYXZlX2Vycm5vID0gZXJy bm87CisKKwkJdW5saW5rKHRyYW5zaWVudF9kdW1wX2ZpbGVfcGF0aCk7CisJCWVycm5vID0gc2F2 ZV9lcnJubzsKKwkJZXJlcG9ydChFUlJPUiwKKwkJCQkoZXJyY29kZV9mb3JfZmlsZV9hY2Nlc3Mo KSwKKwkJCQkgZXJybXNnKCJjb3VsZCBub3QgY2xvc2UgZmlsZSBcIiVzXCI6ICVtIiwKKwkJCQkJ CXRyYW5zaWVudF9kdW1wX2ZpbGVfcGF0aCkpKTsKKwl9CisKKwkodm9pZCkgZHVyYWJsZV9yZW5h bWUodHJhbnNpZW50X2R1bXBfZmlsZV9wYXRoLCBQR1NBX0RVTVBfRklMRSwgRVJST1IpOworfQor CisvKgorICogTG9hZCBhZHZpY2Ugc3Rhc2ggZGF0YSBmcm9tIHRoZSBkdW1wIGZpbGUuCisgKgor ICogVGhpcyBpcyBjYWxsZWQgb25jZSB3aGVuIHRoZSBzaGFyZWQgbWVtb3J5IHN0YXRlIGlzIGZp cnN0IGluaXRpYWxpemVkCisgKiAoaS5lLiBhZnRlciBhIHNlcnZlciByZXN0YXJ0IG9yIGNyYXNo IHJlY292ZXJ5KSwgdG8gcmVzdG9yZSB0aGUgcHJldmlvdXNseQorICogc2F2ZWQgc3Rhc2ggY29u dGVudHMuCisgKgorICogRXJyb3JzIGR1cmluZyBsb2FkaW5nIGFyZSByZXBvcnRlZCBhcyB3YXJu aW5ncyBzbyB0aGF0IGEgY29ycnVwdCBkdW1wIGZpbGUKKyAqIGRvZXMgbm90IHByZXZlbnQgdGhl IHNlcnZlciBmcm9tIHN0YXJ0aW5nLgorICovCitzdGF0aWMgdm9pZAorcGdzYV9sb2FkX2Zyb21f ZmlsZSh2b2lkKQoreworCUZJTEUJICAgKmZpbGU7CisJaW50CQkJbnVtX3N0YXNoZXM7CisJaW50 CQkJbnVtX2VudHJpZXMgPSAwOworCWludAkJCWk7CisJU3RyaW5nSW5mb0RhdGEgYnVmOworCisJ ZmlsZSA9IEFsbG9jYXRlRmlsZShQR1NBX0RVTVBfRklMRSwgInIiKTsKKwlpZiAoIWZpbGUpCisJ eworCQlpZiAoZXJybm8gPT0gRU5PRU5UKQorCQkJcmV0dXJuOwkJCQkvKiBubyBkdW1wIGZpbGUs IG5vdGhpbmcgdG8gbG9hZCAqLworCQllcmVwb3J0KFdBUk5JTkcsCisJCQkJKGVycmNvZGVfZm9y X2ZpbGVfYWNjZXNzKCksCisJCQkJIGVycm1zZygiY291bGQgbm90IG9wZW4gZmlsZSBcIiVzXCI6 ICVtIiwgUEdTQV9EVU1QX0ZJTEUpKSk7CisJCXJldHVybjsKKwl9CisKKwkvKiBSZWFkIHRoZSBo ZWFkZXIuICovCisJaWYgKGZzY2FuZihmaWxlLCAiPDwlZD4+XG4iLCAmbnVtX3N0YXNoZXMpICE9 IDEpCisJeworCQlGcmVlRmlsZShmaWxlKTsKKwkJZXJlcG9ydChXQVJOSU5HLAorCQkJCWVycm1z ZygicGdfc3Rhc2hfYWR2aWNlIGR1bXAgZmlsZSBoYXMgY29ycnVwdGVkIGhlYWRlciIpKTsKKwkJ cmV0dXJuOworCX0KKworCWluaXRTdHJpbmdJbmZvKCZidWYpOworCisJLyogUmVhZCBhbmQgY3Jl YXRlIHN0YXNoIG5hbWVzLiAqLworCWZvciAoaSA9IDA7IGkgPCBudW1fc3Rhc2hlczsgaSsrKQor CXsKKwkJaWYgKCFwZ19nZXRfbGluZV9idWYoZmlsZSwgJmJ1ZikpCisJCXsKKwkJCUZyZWVGaWxl KGZpbGUpOworCQkJcGZyZWUoYnVmLmRhdGEpOworCQkJZXJlcG9ydChXQVJOSU5HLAorCQkJCQll cnJtc2coInBnX3N0YXNoX2FkdmljZSBkdW1wIGZpbGUgaXMgdHJ1bmNhdGVkIGF0IHN0YXNoICVk IiwKKwkJCQkJCSAgIGkgKyAxKSk7CisJCQlyZXR1cm47CisJCX0KKworCQkvKiBTdHJpcCB0aGUg dHJhaWxpbmcgbmV3bGluZS4gKi8KKwkJaWYgKGJ1Zi5sZW4gPiAwICYmIGJ1Zi5kYXRhW2J1Zi5s ZW4gLSAxXSA9PSAnXG4nKQorCQkJYnVmLmRhdGFbLS1idWYubGVuXSA9ICdcMCc7CisJCXsKKwkJ CWNoYXIJICAgKm5hbWUgPSBwZ3NhX3VuZXNjYXBlX3N0cmluZyhidWYuZGF0YSk7CisKKwkJCS8q IFNraXAgZHVwbGljYXRlcyByYXRoZXIgdGhhbiBFUlJPUmluZyBsaWtlIHBnc2FfY3JlYXRlX3N0 YXNoLiAqLworCQkJaWYgKHBnc2FfbG9va3VwX3N0YXNoX2lkKG5hbWUpID09IDApCisJCQl7CisJ CQkJTFdMb2NrQWNxdWlyZSgmcGdzYV9zdGF0ZS0+bG9jaywgTFdfRVhDTFVTSVZFKTsKKwkJCQlw Z3NhX2NyZWF0ZV9zdGFzaChuYW1lKTsKKwkJCQlMV0xvY2tSZWxlYXNlKCZwZ3NhX3N0YXRlLT5s b2NrKTsKKwkJCX0KKwkJfQorCX0KKworCS8qIFJlYWQgYW5kIHJlc3RvcmUgZW50cmllcyB1bnRp bCBFT0YuICovCisJd2hpbGUgKHBnX2dldF9saW5lX2J1ZihmaWxlLCAmYnVmKSkKKwl7CisJCWNo YXIJICAgKnN0YXNoX25hbWU7CisJCWNoYXIJICAgKnF1ZXJ5aWRfc3RyOworCQljaGFyCSAgICph ZHZpY2Vfc3RyaW5nOworCQlpbnQ2NAkJcXVlcnlJZDsKKwkJRXJyb3JTYXZlQ29udGV4dCBlc2Nv bnRleHQgPSB7VF9FcnJvclNhdmVDb250ZXh0fTsKKworCQkvKiBTdHJpcCB0aGUgdHJhaWxpbmcg bmV3bGluZS4gKi8KKwkJaWYgKGJ1Zi5sZW4gPiAwICYmIGJ1Zi5kYXRhW2J1Zi5sZW4gLSAxXSA9 PSAnXG4nKQorCQkJYnVmLmRhdGFbLS1idWYubGVuXSA9ICdcMCc7CisKKwkJLyogUGFyc2U6IHN0 YXNoX25hbWVcdHF1ZXJ5X2lkXHRhZHZpY2Vfc3RyaW5nICovCisJCXN0YXNoX25hbWUgPSBidWYu ZGF0YTsKKwkJcXVlcnlpZF9zdHIgPSBzdHJjaHIoc3Rhc2hfbmFtZSwgJ1x0Jyk7CisJCWlmIChx dWVyeWlkX3N0ciA9PSBOVUxMKQorCQkJZ290byBtYWxmb3JtZWQ7CisJCSpxdWVyeWlkX3N0cisr ID0gJ1wwJzsKKworCQlhZHZpY2Vfc3RyaW5nID0gc3RyY2hyKHF1ZXJ5aWRfc3RyLCAnXHQnKTsK KwkJaWYgKGFkdmljZV9zdHJpbmcgPT0gTlVMTCkKKwkJCWdvdG8gbWFsZm9ybWVkOworCQkqYWR2 aWNlX3N0cmluZysrID0gJ1wwJzsKKworCQlxdWVyeUlkID0gcGdfc3RydG9pbnQ2NF9zYWZlKHF1 ZXJ5aWRfc3RyLCAoTm9kZSAqKSAmZXNjb250ZXh0KTsKKwkJaWYgKFNPRlRfRVJST1JfT0NDVVJS RUQoJmVzY29udGV4dCkpCisJCQlnb3RvIG1hbGZvcm1lZDsKKworCQlwZ3NhX3NldF9hZHZpY2Vf c3RyaW5nKHBnc2FfdW5lc2NhcGVfc3RyaW5nKHN0YXNoX25hbWUpLAorCQkJCQkJCSAgIHF1ZXJ5 SWQsCisJCQkJCQkJICAgcGdzYV91bmVzY2FwZV9zdHJpbmcoYWR2aWNlX3N0cmluZykpOworCQlu dW1fZW50cmllcysrOworCQljb250aW51ZTsKKworbWFsZm9ybWVkOgorCQllcmVwb3J0KFdBUk5J TkcsCisJCQkJZXJybXNnKCJwZ19zdGFzaF9hZHZpY2UgZHVtcCBmaWxlIGhhcyBtYWxmb3JtZWQg ZW50cnksIHNraXBwaW5nIikpOworCX0KKworCUZyZWVGaWxlKGZpbGUpOworCXBmcmVlKGJ1Zi5k YXRhKTsKKworCWVyZXBvcnQoTE9HLAorCQkJZXJybXNnKCJwZ19zdGFzaF9hZHZpY2U6IGxvYWRl ZCAlZCBzdGFzaGVzIHdpdGggJWQgZW50cmllcyBmcm9tIFwiJXNcIiIsCisJCQkJICAgbnVtX3N0 YXNoZXMsIG51bV9lbnRyaWVzLCBQR1NBX0RVTVBfRklMRSkpOworfQorCisvKgorICogQmFja3Ns YXNoLWVzY2FwZSB0aGUgc3RyaW5nIHNvIGl0IGNhbiBiZSB3cml0dGVuIHRvIGEgdGFiLXNlcGFy YXRlZCBmaWxlLgorICoKKyAqIFRoZSBlc2NhcGVkIGNoYXJhY3RlcnMgYXJlIGJhY2tzbGFzaCwg dGFiLCBhbmQgbmV3bGluZS4KKyAqLworc3RhdGljIGNoYXIgKgorcGdzYV9lc2NhcGVfc3RyaW5n KGNoYXIgKnN0cikKK3sKKwlTdHJpbmdJbmZvRGF0YSBidWY7CisKKwlpZiAoIXN0cnBicmsoc3Ry LCAiXFxcdFxuIikpCisJCXJldHVybiBzdHI7CisKKwlpbml0U3RyaW5nSW5mbygmYnVmKTsKKwlm b3IgKGNvbnN0IGNoYXIgKnAgPSBzdHI7ICpwOyBwKyspCisJeworCQlzd2l0Y2ggKCpwKQorCQl7 CisJCQljYXNlICdcXCc6CisJCQkJYXBwZW5kU3RyaW5nSW5mb1N0cmluZygmYnVmLCAiXFxcXCIp OworCQkJCWJyZWFrOworCQkJY2FzZSAnXHQnOgorCQkJCWFwcGVuZFN0cmluZ0luZm9TdHJpbmco JmJ1ZiwgIlxcdCIpOworCQkJCWJyZWFrOworCQkJY2FzZSAnXG4nOgorCQkJCWFwcGVuZFN0cmlu Z0luZm9TdHJpbmcoJmJ1ZiwgIlxcbiIpOworCQkJCWJyZWFrOworCQkJY2FzZSAnXHInOgorCQkJ CWFwcGVuZFN0cmluZ0luZm9TdHJpbmcoJmJ1ZiwgIlxcciIpOworCQkJCWJyZWFrOworCQkJZGVm YXVsdDoKKwkJCQlhcHBlbmRTdHJpbmdJbmZvQ2hhcigmYnVmLCAqcCk7CisJCQkJYnJlYWs7CisJ CX0KKwl9CisKKwlyZXR1cm4gYnVmLmRhdGE7Cit9CisKKy8qCisgKiBVbmVzY2FwZSBhIHN0cmlu ZyB0aGF0IHdhcyBlc2NhcGVkIGZvciBzZXJpYWxpemluZyB0byB0aGUgb24tZGlzayBmaWxlLgor ICovCitzdGF0aWMgY2hhciAqCitwZ3NhX3VuZXNjYXBlX3N0cmluZyhjaGFyICpzdHIpCit7CisJ U3RyaW5nSW5mb0RhdGEgYnVmOworCisJaWYgKCFzdHJjaHIoc3RyLCAnXFwnKSkKKwkJcmV0dXJu IHBzdHJkdXAoc3RyKTsKKworCWluaXRTdHJpbmdJbmZvKCZidWYpOworCWZvciAoY29uc3QgY2hh ciAqcCA9IHN0cjsgKnA7IHArKykKKwl7CisJCWlmICgqcCA9PSAnXFwnICYmIHBbMV0gIT0gJ1ww JykKKwkJeworCQkJcCsrOworCQkJc3dpdGNoICgqcCkKKwkJCXsKKwkJCQljYXNlICdcXCc6CisJ CQkJCWFwcGVuZFN0cmluZ0luZm9DaGFyKCZidWYsICdcXCcpOworCQkJCQlicmVhazsKKwkJCQlj YXNlICd0JzoKKwkJCQkJYXBwZW5kU3RyaW5nSW5mb0NoYXIoJmJ1ZiwgJ1x0Jyk7CisJCQkJCWJy ZWFrOworCQkJCWNhc2UgJ24nOgorCQkJCQlhcHBlbmRTdHJpbmdJbmZvQ2hhcigmYnVmLCAnXG4n KTsKKwkJCQkJYnJlYWs7CisJCQkJY2FzZSAncic6CisJCQkJCWFwcGVuZFN0cmluZ0luZm9DaGFy KCZidWYsICdccicpOworCQkJCQlicmVhazsKKwkJCQlkZWZhdWx0OgorCQkJCQkvKiBVbnJlY29n bml6ZWQgZXNjYXBlOyBrZWVwIGFzLWlzLiAqLworCQkJCQlhcHBlbmRTdHJpbmdJbmZvQ2hhcigm YnVmLCAqcCk7CisJCQkJCWJyZWFrOworCQkJfQorCQl9CisJCWVsc2UKKwkJCWFwcGVuZFN0cmlu Z0luZm9DaGFyKCZidWYsICpwKTsKKwl9CisJcmV0dXJuIGJ1Zi5kYXRhOworfQpkaWZmIC0tZ2l0 IGEvZG9jL3NyYy9zZ21sL3Bnc3Rhc2hhZHZpY2Uuc2dtbCBiL2RvYy9zcmMvc2dtbC9wZ3N0YXNo YWR2aWNlLnNnbWwKaW5kZXggMDg5ZmM2NjQ0NmYuLmNlMmM4ZWMzYWI5IDEwMDY0NAotLS0gYS9k b2Mvc3JjL3NnbWwvcGdzdGFzaGFkdmljZS5zZ21sCisrKyBiL2RvYy9zcmMvc2dtbC9wZ3N0YXNo YWR2aWNlLnNnbWwKQEAgLTE1LDEwICsxNSwxMiBAQAogICA8bGluayBsaW5rZW5kPSJndWMtY29t cHV0ZS1xdWVyeS1pZCI+cXVlcnkgaWRlbnRpZmllcnM8L2xpbms+IHRvIHBsYW4gYWR2aWNlCiAg IHN0cmluZ3MuIFdoZW5ldmVyIGEgc2Vzc2lvbiBpcyBhc2tlZCB0byBwbGFuIGEgcXVlcnkgd2hv c2UgcXVlcnkgSUQgYXBwZWFycwogICBpbiB0aGUgcmVsZXZhbnQgYWR2aWNlIHN0YXNoLCB0aGUg cGxhbiBhZHZpY2Ugc3RyaW5nIGlzIGF1dG9tYXRpY2FsbHkgYXBwbGllZAotICB0byBndWlkZSBw bGFubmluZy4gTm90ZSB0aGF0IGFkdmljZSBzdGFzaGVzIGV4aXN0IHB1cmVseSBpbiBtZW1vcnku IFRoaXMKLSAgbWVhbnMgYm90aCB0aGF0IGl0IGlzIGltcG9ydGFudCB0byBiZSBtaW5kZnVsIG9m IG1lbW9yeSBjb25zdW1wdGlvbiB3aGVuCi0gIGRlY2lkaW5nIGhvdyBtdWNoIHBsYW4gYWR2aWNl IHRvIHN0YXNoLCBhbmQgYWxzbyB0aGF0IGFkdmljZSBzdGFzaGVzIG11c3QKLSAgYmUgcmVjcmVh dGVkIGFuZCByZXBvcHVsYXRlZCB3aGVuZXZlciB0aGUgc2VydmVyIGlzIHJlc3RhcnRlZC4KKyAg dG8gZ3VpZGUgcGxhbm5pbmcuIEFkdmljZSBzdGFzaGVzIGFyZSBoZWxkIGluIG1lbW9yeSwgc28g aXQgaXMgaW1wb3J0YW50CisgIHRvIGJlIG1pbmRmdWwgb2YgbWVtb3J5IGNvbnN1bXB0aW9uIHdo ZW4gZGVjaWRpbmcgaG93IG11Y2ggcGxhbiBhZHZpY2UgdG8KKyAgc3Rhc2guIFRoZSBjb250ZW50 cyBhcmUgYXV0b21hdGljYWxseSBzYXZlZCB0byBhIGZpbGUgY2FsbGVkCisgIDxmaWxlbmFtZT5w Z19zdGFzaF9hZHZpY2UuZW50cmllczwvZmlsZW5hbWU+IHdoZW5ldmVyIHRoZXkgYXJlIG1vZGlm aWVkLAorICBhbmQgcmVzdG9yZWQgd2hlbiB0aGUgZmlyc3Qgc2Vzc2lvbiBhdHRhY2hlcyBhZnRl ciBhIHNlcnZlciByZXN0YXJ0CisgIChpbmNsdWRpbmcgYWZ0ZXIgYSBjcmFzaCkuCiAgPC9wYXJh PgogCiAgPHBhcmE+Ci0tIAoyLjQ3LjEKCg== --000000000000adfef8064e2e5406--