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 1wBNvV-0010az-2y for pgsql-hackers@arkaria.postgresql.org; Sat, 11 Apr 2026 02:18:26 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wBNvU-00FF4s-0l for pgsql-hackers@arkaria.postgresql.org; Sat, 11 Apr 2026 02:18:25 +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 1wBNvT-00FF4k-1o for pgsql-hackers@lists.postgresql.org; Sat, 11 Apr 2026 02:18:24 +0000 Received: from mail-yx1-xb12b.google.com ([2607:f8b0:4864:20::b12b]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wBNvQ-00000000QYb-17sX for pgsql-hackers@lists.postgresql.org; Sat, 11 Apr 2026 02:18:23 +0000 Received: by mail-yx1-xb12b.google.com with SMTP id 956f58d0204a3-649278a69c5so2229921d50.3 for ; Fri, 10 Apr 2026 19:18:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1775873899; cv=none; d=google.com; s=arc-20240605; b=OTdqw54AzoMu0NFQpPbMYzLnfHYsm7BMyCDPkVcTscYJ+ADajVcK0XyAhzSZXAfzlV 6JEoAkmnsJIQifN0dd3K0v2kubVaIt+aXsUmBrjcs0zRf4oPv5k1qJw3l1LsEYiR7UeL ACKwSpKH1ONgJXJzFP3mQVCw1BgwrgpqTk7387buTNdJMHnOcpnrxl+/H2kffeSVvg5T 5agLm6sfiFOBjTpoNzBNsmodBVFyM1M5SFet+N8Csk2iQ7UtKYeIHWc1yJbHs6LSPSMo r8JmALXDfh1QCHDwBqrRISouzvGDUXWSg7S4AfI3iilt1cxF/yb/JmJ46g61xblSqI/y 4fNQ== 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=SpEK+3Ko0mg5mrKAri1eMJb1XllQbAm0cPE6Kk4uTro=; fh=y6lKquhcm5NrRy7yNmyWLegA9XrpFL/l4pSJn9ZGrOw=; b=lHALpxxvBM+v1tSfjUVbZFmhgCrzSYfZKNkJ6YFB5/HCrVDbQQdbSiiT13qj/IDEpa ZsWA8NoQBQSMab6EfT/zlpzKbznGYuIB/25pOOdvTmcwbDw0cqCAhvWsiqXibiGIpjwF R05P93VhGum7wnk+G6kuFgBc2ZOc+vEUH0kqA24vnpBbLm+CEV/uzmp1eVYZh6U3mFBm gBlVN4TyoXi7PHqfqUkhquo6Zp2mWmIO0Nzskz7fyVhS0dvnwDQJrE/HOH6oSn4KIvC/ NFd/lhCdIs2+jzAORpxIk6oomB1ey2WKGefJYB3MqBB3lE9Lwc8vOH+/Xp6FMVAfY8bO qnqQ==; 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=gmail.com; s=20251104; t=1775873899; x=1776478699; 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=SpEK+3Ko0mg5mrKAri1eMJb1XllQbAm0cPE6Kk4uTro=; b=UEFgKzw2PrvncW087S85PoZysWPNQqaNihShKEhv7Hk4tOQ9DMQkinCdl3mcZrj6// ne9TRArQQXihOn+AiC+/aohOJPtFCweNsphVWs7SgtSVT+qlgXc8xb/O6BelqzAqLKMv Xr4/aJTyPjb32ej5D26DR17XeCp1cParGilxyf9R9Dh3iJ+yhJcUghMJfgIj1sw+BCes is41qo75imRBGx3kc354gm9CijIAzLWvcG2hGqsrfC3n1PNapJSphGbEXnSiuSz5nGsE XoLRi0RZxir7sMYEKdm1frcskzdB+jexRCIERRa+g0D7OxEXstm2uaZJyExuy4NkHmsW zStA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775873899; x=1776478699; 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=SpEK+3Ko0mg5mrKAri1eMJb1XllQbAm0cPE6Kk4uTro=; b=cCn7+GkH7MIzZPJ0xzB+YrDaSm/Hux/9V4j+/M8xHDdrw2S73EBbISZ3wvE7VMcZe1 GZE98J0yJnmdLlGp3LFEopU1YqmXfDGkdd0F+i6HuF0bQy+YLjZFR4CawlwBlqv87mNj kkZlt+ReLgbNg0sd9WvhvKpNkdgyCfzW6NyfOcjq5O3OiVCexow9VBLC77oeL8HZUhPI 0Wb5VWL/9eMT8I4OnT7nO7XtxOYITY7AcnwvFAFYuVUFpQifzMuBjt0Jdr6mpfga5xpx reI3UXv4zvtjl8Ln+TX0X9W67x8F/+ToYdMdcX1KLN5LFyjeCG/IyY+d0TjgZEbGlXDx OtBA== X-Gm-Message-State: AOJu0YwBSaaCGRMljLVv5O4C3DbNfpUplWS8YeJMEZrCFnCZtI9ZOtOQ AWnRdba9LNk5TVV5DgyIBjY77AAomJ3FOL9o7WfJiQbVYM5zBAyzf9M3kxMXMqvmhHdP7/f6YXM aQhBVRPB2yfdwqhLs131QFqGfWlz2vhZLwV+380v9bA== X-Gm-Gg: AeBDietqQ/z2OnkTCZpgeqoizpo8moJ65tOtPZQh7o6O3IVqx8urh4XxJuItLbjNgMI 1Od3aKtM4Hck/fdhxxdDVp8N2QKon9DXnajPBud9Wjz/UilNuGcCNAKBawH7NXIwOoviu1L+dvI qsVBWlZ6NAZiPjzYkSdGMhVatzo7lvwdu7o/n7z1BVPC5/ynudR6d42yGTXKZEklNnxP5l0APpA 1nhMvv7/j22IXArpp/m1c9obPv/MbGYqQr5K88V+UuiO59wARmyGaAW8FYV0/SW3+itWfkoIrZH J/iKJJGyEzJTDkJtpGynrfvaf3bTStPLzMrtdc3LRhaezGjpQqI= X-Received: by 2002:a05:690e:2541:b0:64c:a09f:12ab with SMTP id 956f58d0204a3-65198b193d8mr4077012d50.30.1775873899026; Fri, 10 Apr 2026 19:18:19 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Haibo Yan Date: Fri, 10 Apr 2026 19:18:07 -0700 X-Gm-Features: AQROBzBdxeRbgHfd4_ZWFRyL60v79dUggQyY9wlHclaCOIxF6EoCGeOV1CsvhPw Message-ID: Subject: Re: [PATCH] Fix: Partitioned parent index remains invalid after child indexes are repaired To: Mohamed ALi Cc: pgsql-hackers@lists.postgresql.org Content-Type: multipart/mixed; boundary="000000000000eb0bee064f25dc1a" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000eb0bee064f25dc1a Content-Type: multipart/alternative; boundary="000000000000eb0bed064f25dc18" --000000000000eb0bed064f25dc18 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Fri, Apr 10, 2026 at 5:55=E2=80=AFPM Haibo Yan w= rote: > On Wed, Apr 8, 2026 at 11:17=E2=80=AFPM Mohamed ALi = wrote: > >> Hi hackers, >> >> A partitioned (parent) index in PostgreSQL can become permanently >> stuck with `indisvalid =3D false` even after all of its child partition >> indexes have been repaired and are valid. There is no built-in >> mechanism to re-validate the parent index after a child is fixed via >> `REINDEX`. This affects all currently supported PostgreSQL versions >> (13 through 18) >> The root cause is that `validatePartitionedIndex()` =E2=80=94 the only >> function that can mark a partitioned index as valid is never called >> after `REINDEX` operations, and is skipped when re-running `ALTER >> INDEX ATTACH PARTITION` on an already-attached index. >> >> How the Bug Manifests >> >> Typical Scenario : >> 1. A partitioned table has multiple partitions. >> 2. The user creates indexes on partitions concurrently. One fails (due >> to deadlock, cancellation, timeout, etc.), leaving an invalid >> partition index. >> 3. A parent index is created (or the invalid index is attached to an >> existing parent). The parent is correctly marked `indisvalid =3D false` >> because at least one child is invalid. >> 4. The user fixes the broken child index with `REINDEX INDEX >> CONCURRENTLY`. >> 5. The child index becomes valid (`indisvalid =3D true`). >> 6. The parent index remains `indisvalid =3D false` permanently. No SQL >> command can fix it. >> >> Reproduction steps: >> >> ```sql >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> -- SETUP: Partitioned table with two partitions and sample data >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> DROP TABLE IF EXISTS orders; >> CREATE TABLE orders ( >> id serial, >> order_date date NOT NULL, >> amount numeric >> ) PARTITION BY RANGE (order_date); >> CREATE TABLE orders_2023 PARTITION OF orders >> FOR VALUES FROM ('2023-01-01') TO ('2024-01-01'); >> CREATE TABLE orders_2024 PARTITION OF orders >> FOR VALUES FROM ('2024-01-01') TO ('2025-01-01'); >> INSERT INTO orders (order_date, amount) >> SELECT d, random() * 1000 >> FROM generate_series('2023-01-01'::date, '2023-12-31'::date, '1 day') d; >> INSERT INTO orders (order_date, amount) >> SELECT d, random() * 1000 >> FROM generate_series('2024-01-01'::date, '2024-12-31'::date, '1 day') d; >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> -- STEP 1: Create parent index with ONLY (starts as invalid) >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> CREATE INDEX orders_amount_idx ON ONLY orders (amount); >> -- Verify: parent index is invalid (no children attached yet) >> SELECT c.relname, i.indisvalid >> FROM pg_class c >> JOIN pg_index i ON c.oid =3D i.indexrelid >> WHERE c.relname LIKE 'orders%idx%' >> ORDER BY c.relname; >> -- Expected: >> -- orders_amount_idx | f >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> -- STEP 2: Create valid index on first partition >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> CREATE INDEX CONCURRENTLY orders_2023_amount_idx ON orders_2023 (amount)= ; >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> -- STEP 3: Create an INVALID index on second partition >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> -- In a separate session, hold a lock: >> BEGIN; LOCK TABLE orders_2024 IN SHARE MODE; >> -- Then in the main session: >> SET statement_timeout =3D '1ms'; >> CREATE INDEX CONCURRENTLY orders_2024_amount_idx ON orders_2024 (amount)= ; >> RESET statement_timeout; >> -- it will fail/timeout, leaving an invalid index. >> -- Verify state: >> SELECT c.relname, i.indisvalid >> FROM pg_class c >> JOIN pg_index i ON c.oid =3D i.indexrelid >> WHERE c.relname LIKE 'orders%idx%' >> ORDER BY c.relname; >> -- Expected: >> -- orders_2023_amount_idx | t (valid) >> -- orders_2024_amount_idx | f (invalid) >> -- orders_amount_idx | f (invalid, created with ONLY) >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> -- STEP 4: Attach both partition indexes to the parent >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> -- Attach the invalid one first >> ALTER INDEX orders_amount_idx ATTACH PARTITION orders_2024_amount_idx; >> -- Succeeds. Parent stays invalid (correct =E2=80=94 child is invalid). >> -- Attach the valid one >> ALTER INDEX orders_amount_idx ATTACH PARTITION orders_2023_amount_idx; >> -- Succeeds. Parent still invalid (correct =E2=80=94 one child still inv= alid). >> -- Verify attachment and validity: >> SELECT c.relname, i.indisvalid, >> pg_get_indexdef(i.indexrelid) AS indexdef >> FROM pg_class c >> JOIN pg_index i ON c.oid =3D i.indexrelid >> WHERE c.relname LIKE 'orders%amount%' >> ORDER BY c.relname; >> -- Expected: >> -- orders_2023_amount_idx | t >> -- orders_2024_amount_idx | f >> -- orders_amount_idx | f >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> -- STEP 5: Fix the invalid child index via REINDEX >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> REINDEX INDEX CONCURRENTLY orders_2024_amount_idx; >> -- Verify: child is now valid >> SELECT c.relname, i.indisvalid >> FROM pg_class c >> JOIN pg_index i ON c.oid =3D i.indexrelid >> WHERE c.relname LIKE 'orders%amount%' >> ORDER BY c.relname; >> -- ACTUAL (buggy) result: >> -- orders_2023_amount_idx | t (valid) >> -- orders_2024_amount_idx | t (valid =E2=80=94 fixed by REINDEX) >> -- orders_amount_idx | f (STILL INVALID =E2=80=94 this is the bu= g!) >> -- >> -- EXPECTED result (if bug were fixed): >> -- orders_2023_amount_idx | t >> -- orders_2024_amount_idx | t >> -- orders_amount_idx | t (should be valid now) >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> -- STEP 6: Demonstrate that re-running ATTACH does not help >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> ALTER INDEX orders_amount_idx ATTACH PARTITION orders_2024_amount_idx; >> -- Returns "ALTER INDEX" (succeeds silently, does nothing) >> SELECT c.relname, i.indisvalid >> FROM pg_class c >> JOIN pg_index i ON c.oid =3D i.indexrelid >> WHERE c.relname LIKE 'orders%amount%' >> ORDER BY c.relname; >> -- Parent is STILL invalid. The "silently do nothing" path >> -- skips validatePartitionedIndex() entirely. >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> -- CLEANUP >> -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> DROP TABLE orders; >> ``` >> >> >> Root Cause Analysis: >> >> Where `validatePartitionedIndex()` Is Called >> >> The function is called in exactly these code paths: >> 1. During `ALTER INDEX ... ATTACH PARTITION` =E2=80=94 inside >> `ATExecAttachPartitionIdx()` >> 2. During `ALTER TABLE ... ATTACH PARTITION` =E2=80=94 via >> `AttachPartitionEnsureIndexes()` >> 3. During `CREATE INDEX` on partitioned tables =E2=80=94 via `DefineInde= x()` >> It is NOT called: >> - After `REINDEX` of a partitioned index >> - During any maintenance operation >> - As any periodic validation check >> >> Bug 1: REINDEX Does Not Validate Parent >> >> >> When `reindex_index()` in `src/backend/catalog/index.c` marks a >> partition index as valid (setting `indisvalid =3D true`), it does not >> check whether the parent partitioned index should also become valid. >> The function simply updates the child's `pg_index` entry and returns. >> >> Bug 2: Re-running ATTACH Skips Validation >> >> >> In `ATExecAttachPartitionIdx()` (tablecmds.c, around line 21923 in PG >> 16 / line ~22900 in HEAD): >> >> https://github.com/postgres/postgres/blob/master/src/backend/commands/ta= blecmds.c#L21923 >> >> ```c >> /* Silently do nothing if already in the right state */ >> currParent =3D partIdx->rd_rel->relispartition ? >> get_partition_parent(partIdxId, false) : InvalidOid; >> if (currParent !=3D RelationGetRelid(parentIdx)) >> { >> // ... all validation checks and attachment logic ... >> validatePartitionedIndex(parentIdx, parentTbl); // ONLY called here >> } >> // If already attached, entire block is skipped =E2=80=94 no validation! >> ``` >> >> When the child is already attached (`currParent =3D=3D parentIdx`), the >> condition is false, the entire if-block is skipped, and >> `validatePartitionedIndex()` is never called. The comment "Silently do >> nothing if already in the right state" is misleading "already >> attached" does not mean "parent validity is correct." >> >> Proposed Fixes: >> >> Fix 1 : Always Validate Parent Index in ALTER INDEX ATTACH PARTITION >> >> Patch File : 0001-Always-validate-parent-index-in-ALTER-INDEX-ATTACH.pat= ch >> >> Move the validatePartitionedIndex() call outside the if-block so it runs >> unconditionally =E2=80=94 both when a new attachment is made and when th= e >> partition is >> already attached. This provides a user-accessible recovery path: after >> fixing a >> child index with REINDEX, re-running ALTER INDEX ATTACH PARTITION trigge= rs >> parent validation. >> >> When the partition is already attached, a NOTICE is emitted: >> >> NOTICE: partition index "child_idx" is already attached to >> "parent_idx", validating parent index >> >> >> This follows PostgreSQL's existing convention of using NOTICE for >> informational messages about no-op or reduced-scope operations (e.g., >> DROP TABLE IF EXISTS, CREATE INDEX IF NOT EXISTS). It tells the user: >> >> 1- Nothing went wrong >> 2- The index was already attached (so they know the state) >> 3- Validation still happened (so they know the fix path works) >> >> >> Fix 2: Validate Parent Partitioned Index After REINDEX of Child >> >> Patch File : 0001-Validate-parent-partitioned-index-after-REINDEX.patch >> >> Same underlying bug but this patch addresses it from the >> REINDEX side. When a partition index is repaired via REINDEX or >> REINDEX CONCURRENTLY, the parent partitioned index remains permanently >> stuck with indisvalid =3D false even though all children are now valid. >> >> This is because validatePartitionedIndex() =E2=80=94 the only function t= hat can >> mark a partitioned index as valid is never called from any REINDEX code >> path. >> >> >> validatePartitionedIndex() is only called during: >> >> 1- ALTER INDEX ... ATTACH PARTITION (tablecmds.c) >> 2- ALTER TABLE ... ATTACH PARTITION (tablecmds.c) >> 3- CREATE INDEX on partitioned tables (indexcmds.c) >> >> It is NOT called after: >> >> 1- REINDEX INDEX (regular) =E2=80=94 handled by reindex_index() in index= .c >> 2- REINDEX INDEX CONCURRENTLY =E2=80=94 handled by ReindexRelationConcur= rently() >> >> in indexcmds.c, which uses index_concurrently_swap() in index.c >> >> Three changes are made: >> >> 1. Make validatePartitionedIndex() public >> The function was static in tablecmds.c. It is now exported via >> tablecmds.h so it can be called from index.c and indexcmds.c. >> >> Files changed: >> >> src/backend/commands/tablecmds.c =E2=80=94 remove static, update comment >> src/include/commands/tablecmds.h =E2=80=94 add extern declaration >> >> 2. Call from reindex_index() (regular REINDEX) >> After reindex_index() marks a partition index as valid (indisvalid =3D >> true), >> check if the index is a partition (iRel->rd_rel->relispartition) and if >> so, >> look up the parent and call validatePartitionedIndex(). >> >> A CommandCounterIncrement() is required before the call so that the >> child's >> updated indisvalid is visible to the syscache lookup that >> validatePartitionedIndex() performs internally. >> >> File changed: src/backend/catalog/index.c >> >> 3. Call from ReindexRelationConcurrently() (REINDEX CONCURRENTLY) >> REINDEX CONCURRENTLY uses a completely different code path: it creates a >> new >> index, builds it concurrently, then swaps it with the old one via >> index_concurrently_swap(). The new index inherits the old index's >> partition >> status during the swap. >> >> After the swap and the existing CommandCounterIncrement() (which makes t= he >> swap visible), check if the new index is a partition and call >> validatePartitionedIndex() on the parent. >> >> File changed: src/backend/commands/indexcmds.c >> >> Multi-level Hierarchy Support >> validatePartitionedIndex() already handles multi-level partition >> hierarchies. >> When it marks a mid-level parent valid, it checks if that parent is >> itself a >> partition and recursively validates the grandparent. No additional >> recursion >> logic is needed in the REINDEX patches. >> >> >> Thanks, >> Mohamed Ali >> Senior DBE >> AWS RDS >> > > Hi, Mohamed > > Thanks for working on this. I went through the problem statement and the > two proposed fixes. I agree that the underlying issue looks real: after > repairing an invalid child index with REINDEX, the parent partitioned ind= ex > can remain stuck in an invalid state because validatePartitionedIndex() > is not reached from the relevant REINDEX paths. The analysis around > ATExecAttachPartitionIdx() also looks correct: when the child index is > already attached, the current code takes the no-op path and skips the > validation call entirely. > > Overall, I think this is worth fixing, but I do not view the two patches > equally. > > I think patch 2 is the real fix. The state transition that matters here i= s > that a child index goes from invalid to valid, and the natural place to > trigger parent revalidation is where that transition actually happens, > namely in REINDEX. By contrast, patch 1 feels more like a secondary > hardening/workaround path: it makes ALTER INDEX ... ATTACH PARTITION > retry parent validation even in the already-attached case, but that is no= t > really where the underlying state change happens. > > My main comments are below. > > 1. Patch 2 should be treated as the primary fix > > This seems like the correct place to repair the catalog state. If REINDEX > repairs a partition index that was previously invalid, and that index is > attached to a partitioned parent index, then rechecking the parent with > validatePartitionedIndex() is a reasonable and direct solution. > > I also think it is good that the patch covers both the regular REINDEX > path and the REINDEX CONCURRENTLY path. Those are distinct enough that > both need explicit attention, and the extra CommandCounterIncrement() > before revalidation also seems necessary. > > So at a high level, this patch makes sense to me. > > 2. I am less convinced by patch 1 in its current form > > The main issue here is not correctness, but design and placement. > > Once the child is already attached, ALTER INDEX ... ATTACH PARTITION is > conceptually supposed to be a no-op. With this patch, it becomes a generi= c > =E2=80=9Cretry parent validation=E2=80=9D hook. That means users can run = an attach command > that does not change attachment state at all, yet still triggers a full > parent validation attempt. > > That is especially questionable if there are still other invalid child > indexes elsewhere under the same parent. In that case, each > already-attached ATTACH command will do the validation work again, but it > is already known in advance that the parent still cannot become valid. So > this is not =E2=80=9Creinvalidating=E2=80=9D anything, but it is repeated= checking with no > state change, which feels misplaced on a no-op path. > > Because of that, I do not think patch 1 should be the main bug fix. At > most, I would see it as an optional hardening patch. > > 3. The NOTICE added by patch 1 does not seem like a good fit > > The existing code explicitly says =E2=80=9CSilently do nothing if already= in the > right state=E2=80=9D. Changing that into a NOTICE every time we hit the > already-attached case seems noisy to me. > > If the community decides that the validation call should stay in this > path, I would still suggest dropping the NOTICE. The command is > syntactically an ATTACH command, not a repair command, and emitting a > message for an otherwise no-op case does not feel very PostgreSQL-like. > > 4. Please double-check coverage of all REINDEX entry points > > I agree with the direction in patch 2, but I think reviewers will want > confidence that all relevant REINDEX flows are covered consistently. > > For example, it would be good to confirm that the fix behaves correctly > not just for REINDEX INDEX, but also for the broader forms that > eventually reach the same logic, such as REINDEX TABLE, and that there is > no alternate path where a repaired child index can still leave the parent > stale. > > 5. Multi-level partition trees need explicit testing > > One especially important point here is recursion. If a repaired child > index causes its immediate parent partitioned index to become valid, and > that parent is itself a child of another partitioned index, we need to be > sure that validity propagates all the way up as intended. > > The current reasoning suggests that validatePartitionedIndex() already > handles that, but this is important enough that it should be demonstrated > with a regression test, not just assumed. > > Minor comments: > > > - > > In patch 1, I would avoid turning the already-attached path into a > behavioral special case unless there is a strong reason to keep it. It > would be cleaner if the fix relied primarily on the actual state-chang= ing > paths. > - > > If patch 1 remains, I would remove the NOTICE. > - > > The commit message for patch 2 should clearly explain why REINDEX is > the right place to do this, rather than making ATTACH PARTITION the re= pair > mechanism. > - > > It may also help to mention explicitly whether the extra validation > call is only intended for indexes that were previously invalid and hav= e > just been repaired, since that is an important part of why the patch i= s > reasonably narrow. > > I do not think the current patches are complete without regression > coverage. At minimum, I think the following tests should be added: > > > 1. > > Regular REINDEX case > > Create a partitioned table with a parent index left invalid initially, > then attach child indexes such that one child index is invalid. Repair= that > child with plain REINDEX INDEX, and verify that the child becomes > valid and the parent also becomes valid. > 2. > > REINDEX CONCURRENTLY case > > Same setup, but use REINDEX INDEX CONCURRENTLY. This should be tested > separately because the code path is different. > 3. > > Multi-level partition hierarchy > > Use at least a three-level hierarchy and verify that repairing a > leaf-level invalid child index can cause validity to propagate upward > through intermediate partitioned indexes. > 4. > > Negative case > > Repair one child index while another child index under the same parent > remains invalid, and verify that the parent remains invalid. > 5. > > Already-attached ATTACH PARTITION case > > Only if patch 1 is kept: exercise ALTER INDEX ... ATTACH PARTITION on > a child index that is already attached, and verify both behaviors: > > > - > > parent becomes valid if all children are now valid > - > > parent stays invalid if some other child is still invalid > > My overall view is: > > > - The bug itself looks real. > - The diagnosis looks sound. > - Patch 2 is the right direction and should be the primary fix. > - Patch 1 is much less compelling as written, and I would not take it > as the main solution. > - The series needs regression tests before it is ready. > > Regards, > Haibo > Hi, Mohamed I took a look at this patch and added some regression coverage for it. While doing that, I found that the current concurrent-path fix is not quite complete. The new tests exposed crashes in existing REINDEX CONCURRENTLY regression coverage, and the root cause appears to be that in the concurrent path, validatePartitionedIndex() can eventually reach catalog update code at a point where there is no active/registered snapshot. That leads to the HaveRegisteredOrActiveSnapshot() assertion failure. So the overall bug diagnosis still looks correct to me, and the plain REINDEX direction also looks right, but the REINDEX CONCURRENTLY path needs an additional fix around the call site/context. Based on that, I prepared a v2 on top of your patch. It includes: - a fix for the concurrent-path snapshot issue - narrower handling for the concurrent path so it only does parent revalidation for the actual repair case - regression tests covering: - plain REINDEX INDEX - a negative case where another invalid sibling keeps the parent invalid - multi-level partition hierarchies - REINDEX TABLE If my understanding above looks right to you, I think this v2 is a better base for further review. Thanks, Haibo --000000000000eb0bed064f25dc18 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Fri, Apr 10, 2026 at 5:55=E2=80=AFPM H= aibo Yan <tristan.yim@gmail.com= > wrote:
On Wed, Apr 8, 2026 at 11:17=E2=80=AFPM Mohamed ALi <moali.pg@gmail.com> wrote:<= /div>
Hi hackers,

A partitioned (parent) index in PostgreSQL can become permanently
stuck with `indisvalid =3D false` even after all of its child partition
indexes have been repaired and are valid. There is no built-in
mechanism to re-validate the parent index after a child is fixed via
`REINDEX`. This affects all currently supported PostgreSQL versions
(13 through 18)
The root cause is that `validatePartitionedIndex()` =E2=80=94 the only
function that can mark a partitioned index as valid is never called
after `REINDEX` operations, and is skipped when re-running `ALTER
INDEX ATTACH PARTITION` on an already-attached index.

How the Bug Manifests

Typical Scenario :
1. A partitioned table has multiple partitions.
2. The user creates indexes on partitions concurrently. One fails (due
to deadlock, cancellation, timeout, etc.), leaving an invalid
partition index.
3. A parent index is created (or the invalid index is attached to an
existing parent). The parent is correctly marked `indisvalid =3D false`
because at least one child is invalid.
4. The user fixes the broken child index with `REINDEX INDEX CONCURRENTLY`.=
5. The child index becomes valid (`indisvalid =3D true`).
6. The parent index remains `indisvalid =3D false` permanently. No SQL
command can fix it.

Reproduction steps:

```sql
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- SETUP: Partitioned table with two partitions and sample data
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
DROP TABLE IF EXISTS orders;
CREATE TABLE orders (
=C2=A0 =C2=A0 id serial,
=C2=A0 =C2=A0 order_date date NOT NULL,
=C2=A0 =C2=A0 amount numeric
) PARTITION BY RANGE (order_date);
CREATE TABLE orders_2023 PARTITION OF orders
=C2=A0 =C2=A0 FOR VALUES FROM ('2023-01-01') TO ('2024-01-01= 9;);
CREATE TABLE orders_2024 PARTITION OF orders
=C2=A0 =C2=A0 FOR VALUES FROM ('2024-01-01') TO ('2025-01-01= 9;);
INSERT INTO orders (order_date, amount)
SELECT d, random() * 1000
FROM generate_series('2023-01-01'::date, '2023-12-31'::date= , '1 day') d;
INSERT INTO orders (order_date, amount)
SELECT d, random() * 1000
FROM generate_series('2024-01-01'::date, '2024-12-31'::date= , '1 day') d;
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- STEP 1: Create parent index with ONLY (starts as invalid)
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
CREATE INDEX orders_amount_idx ON ONLY orders (amount);
-- Verify: parent index is invalid (no children attached yet)
SELECT c.relname, i.indisvalid
FROM pg_class c
JOIN pg_index i ON c.oid =3D i.indexrelid
WHERE c.relname LIKE 'orders%idx%'
ORDER BY c.relname;
-- Expected:
--=C2=A0 orders_amount_idx | f
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- STEP 2: Create valid index on first partition
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
CREATE INDEX CONCURRENTLY orders_2023_amount_idx ON orders_2023 (amount); -- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- STEP 3: Create an INVALID index on second partition
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- In a separate session, hold a lock:
BEGIN; LOCK TABLE orders_2024 IN SHARE MODE;
-- Then in the main session:
SET statement_timeout =3D '1ms';
CREATE INDEX CONCURRENTLY orders_2024_amount_idx ON orders_2024 (amount); RESET statement_timeout;
-- it will fail/timeout, leaving an invalid index.
-- Verify state:
SELECT c.relname, i.indisvalid
FROM pg_class c
JOIN pg_index i ON c.oid =3D i.indexrelid
WHERE c.relname LIKE 'orders%idx%'
ORDER BY c.relname;
-- Expected:
--=C2=A0 orders_2023_amount_idx | t=C2=A0 =C2=A0(valid)
--=C2=A0 orders_2024_amount_idx | f=C2=A0 =C2=A0(invalid)
--=C2=A0 orders_amount_idx=C2=A0 =C2=A0 =C2=A0 | f=C2=A0 =C2=A0(invalid, cr= eated with ONLY)
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- STEP 4: Attach both partition indexes to the parent
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- Attach the invalid one first
ALTER INDEX orders_amount_idx ATTACH PARTITION orders_2024_amount_idx;
-- Succeeds. Parent stays invalid (correct =E2=80=94 child is invalid).
-- Attach the valid one
ALTER INDEX orders_amount_idx ATTACH PARTITION orders_2023_amount_idx;
-- Succeeds. Parent still invalid (correct =E2=80=94 one child still invali= d).
-- Verify attachment and validity:
SELECT c.relname, i.indisvalid,
=C2=A0 =C2=A0 =C2=A0 =C2=A0pg_get_indexdef(i.indexrelid) AS indexdef
FROM pg_class c
JOIN pg_index i ON c.oid =3D i.indexrelid
WHERE c.relname LIKE 'orders%amount%'
ORDER BY c.relname;
-- Expected:
--=C2=A0 orders_2023_amount_idx | t
--=C2=A0 orders_2024_amount_idx | f
--=C2=A0 orders_amount_idx=C2=A0 =C2=A0 =C2=A0 | f
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- STEP 5: Fix the invalid child index via REINDEX
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
REINDEX INDEX CONCURRENTLY orders_2024_amount_idx;
-- Verify: child is now valid
SELECT c.relname, i.indisvalid
FROM pg_class c
JOIN pg_index i ON c.oid =3D i.indexrelid
WHERE c.relname LIKE 'orders%amount%'
ORDER BY c.relname;
-- ACTUAL (buggy) result:
--=C2=A0 orders_2023_amount_idx | t=C2=A0 =C2=A0(valid)
--=C2=A0 orders_2024_amount_idx | t=C2=A0 =C2=A0(valid =E2=80=94 fixed by R= EINDEX)
--=C2=A0 orders_amount_idx=C2=A0 =C2=A0 =C2=A0 | f=C2=A0 =C2=A0(STILL INVAL= ID =E2=80=94 this is the bug!)
--
-- EXPECTED result (if bug were fixed):
--=C2=A0 orders_2023_amount_idx | t
--=C2=A0 orders_2024_amount_idx | t
--=C2=A0 orders_amount_idx=C2=A0 =C2=A0 =C2=A0 | t=C2=A0 =C2=A0(should be v= alid now)
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- STEP 6: Demonstrate that re-running ATTACH does not help
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
ALTER INDEX orders_amount_idx ATTACH PARTITION orders_2024_amount_idx;
-- Returns "ALTER INDEX" (succeeds silently, does nothing)
SELECT c.relname, i.indisvalid
FROM pg_class c
JOIN pg_index i ON c.oid =3D i.indexrelid
WHERE c.relname LIKE 'orders%amount%'
ORDER BY c.relname;
-- Parent is STILL invalid. The "silently do nothing" path
-- skips validatePartitionedIndex() entirely.
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- CLEANUP
-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
DROP TABLE orders;
```


Root Cause Analysis:

Where `validatePartitionedIndex()` Is Called

The function is called in exactly these code paths:
1. During `ALTER INDEX ... ATTACH PARTITION` =E2=80=94 inside
`ATExecAttachPartitionIdx()`
2. During `ALTER TABLE ... ATTACH PARTITION` =E2=80=94 via
`AttachPartitionEnsureIndexes()`
3. During `CREATE INDEX` on partitioned tables =E2=80=94 via `DefineIndex()= `
It is NOT called:
- After `REINDEX` of a partitioned index
- During any maintenance operation
- As any periodic validation check

Bug 1: REINDEX Does Not Validate Parent


When `reindex_index()` in `src/backend/catalog/index.c` marks a
partition index as valid (setting `indisvalid =3D true`), it does not
check whether the parent partitioned index should also become valid.
The function simply updates the child's `pg_index` entry and returns.
Bug 2: Re-running ATTACH Skips Validation


In `ATExecAttachPartitionIdx()` (tablecmds.c, around line 21923 in PG
16 / line ~22900 in HEAD):
https://gith= ub.com/postgres/postgres/blob/master/src/backend/commands/tablecmds.c#L2192= 3

```c
/* Silently do nothing if already in the right state */
currParent =3D partIdx->rd_rel->relispartition ?
=C2=A0 =C2=A0 get_partition_parent(partIdxId, false) : InvalidOid;
if (currParent !=3D RelationGetRelid(parentIdx))
{
=C2=A0 =C2=A0 // ... all validation checks and attachment logic ...
=C2=A0 =C2=A0 validatePartitionedIndex(parentIdx, parentTbl);=C2=A0 // ONLY= called here
}
// If already attached, entire block is skipped =E2=80=94 no validation! ```

When the child is already attached (`currParent =3D=3D parentIdx`), the
condition is false, the entire if-block is skipped, and
`validatePartitionedIndex()` is never called. The comment "Silently do=
nothing if already in the right state" is misleading=C2=A0 "alrea= dy
attached" does not mean "parent validity is correct."

Proposed Fixes:

Fix 1 : Always Validate Parent Index in ALTER INDEX ATTACH PARTITION

Patch File : 0001-Always-validate-parent-index-in-ALTER-INDEX-ATTACH.patch<= br>
Move the validatePartitionedIndex() call outside the if-block so it runs unconditionally =E2=80=94 both when a new attachment is made and when the p= artition is
already attached. This provides a user-accessible recovery path: after fixi= ng a
child index with REINDEX, re-running ALTER INDEX ATTACH PARTITION triggers<= br> parent validation.

When the partition is already attached, a NOTICE is emitted:

NOTICE:=C2=A0 partition index "child_idx" is already attached to<= br> "parent_idx", validating parent index


This follows PostgreSQL's existing convention of using NOTICE for
informational messages about no-op or reduced-scope operations (e.g.,
DROP TABLE IF EXISTS, CREATE INDEX IF NOT EXISTS). It tells the user:

1- Nothing went wrong
2- The index was already attached (so they know the state)
3-=C2=A0 Validation still happened (so they know the fix path works)


Fix 2: Validate Parent Partitioned Index After REINDEX of Child

Patch File : 0001-Validate-parent-partitioned-index-after-REINDEX.patch

Same underlying bug but this patch addresses it from the
REINDEX side. When a partition index is repaired via REINDEX or
REINDEX CONCURRENTLY, the parent partitioned index remains permanently
stuck with indisvalid =3D false even though all children are now valid.

This is because validatePartitionedIndex() =E2=80=94 the only function that= can
mark a partitioned index as valid is never called from any REINDEX code
path.


validatePartitionedIndex() is only called during:

1- ALTER INDEX ... ATTACH PARTITION (tablecmds.c)
2- ALTER TABLE ... ATTACH PARTITION (tablecmds.c)
3- CREATE INDEX on partitioned tables (indexcmds.c)

It is NOT called after:

1- REINDEX INDEX (regular) =E2=80=94 handled by reindex_index() in index.c<= br> 2- REINDEX INDEX CONCURRENTLY =E2=80=94 handled by ReindexRelationConcurren= tly()

in indexcmds.c, which uses index_concurrently_swap() in index.c

Three changes are made:

1. Make validatePartitionedIndex() public
The function was static in tablecmds.c. It is now exported via
tablecmds.h so it can be called from index.c and indexcmds.c.

Files changed:

src/backend/commands/tablecmds.c =E2=80=94 remove static, update comment src/include/commands/tablecmds.h =E2=80=94 add extern declaration

2. Call from reindex_index() (regular REINDEX)
After reindex_index() marks a partition index as valid (indisvalid =3D true= ),
check if the index is a partition (iRel->rd_rel->relispartition) and = if so,
look up the parent and call validatePartitionedIndex().

A CommandCounterIncrement() is required before the call so that the child&#= 39;s
updated indisvalid is visible to the syscache lookup that
validatePartitionedIndex() performs internally.

File changed: src/backend/catalog/index.c

3. Call from ReindexRelationConcurrently() (REINDEX CONCURRENTLY)
REINDEX CONCURRENTLY uses a completely different code path: it creates a ne= w
index, builds it concurrently, then swaps it with the old one via
index_concurrently_swap(). The new index inherits the old index's parti= tion
status during the swap.

After the swap and the existing CommandCounterIncrement() (which makes the<= br> swap visible), check if the new index is a partition and call
validatePartitionedIndex() on the parent.

File changed: src/backend/commands/indexcmds.c

Multi-level Hierarchy Support
validatePartitionedIndex() already handles multi-level partition hierarchie= s.
When it marks a mid-level parent valid, it checks if that parent is itself = a
partition and recursively validates the grandparent. No additional recursio= n
logic is needed in the REINDEX patches.


Thanks,
Mohamed Ali
Senior DBE
AWS RDS

Hi, Mohamed

Thanks for working on this. I went through the problem statement and the= two proposed fixes. I agree that the underlying issue looks real: after re= pairing an invalid child index with REINDEX, the parent partitioned index c= an remain stuck in an invalid state because validatePartitionedIndex(= ) is not reached from the relevant REINDEX paths. The analysis aroun= d ATExecAttachPartitionIdx() also looks correct: when the chil= d index is already attached, the current code takes the no-op path and skip= s the validation call entirely.

Overall, I think this is worth fixing, but I do not view the two patches= equally.

I think patch 2 is the real fix. The state transition that matters here = is that a child index goes from invalid to valid, and the natural place to = trigger parent revalidation is where that transition actually happens, name= ly in REINDEX. By contrast, patch 1 feels more like a secondary hardening/w= orkaround path: it makes ALTER INDEX ... ATTACH PARTITION retr= y parent validation even in the already-attached case, but that is not real= ly where the underlying state change happens.

My main comments are below.

1. Patch 2 should be treated as the primary fix

This seems like the correct place to repair the catalog state. If REINDE= X repairs a partition index that was previously invalid, and that index is = attached to a partitioned parent index, then rechecking the parent with validatePartitionedIndex() is a reasonable and direct solution.

I also think it is good that the patch covers both the regular REINDEX p= ath and the REINDEX CONCURRENTLY path. Those are distinct enou= gh that both need explicit attention, and the extra CommandCounterInc= rement() before revalidation also seems necessary.

So at a high level, this patch makes sense to me.

2. I am less convinced by patch 1 in its current form

The main issue here is not correctness, but design and placement.

Once the child is already attached, ALTER INDEX ... ATTACH PARTITI= ON is conceptually supposed to be a no-op. With this patch, it becom= es a generic =E2=80=9Cretry parent validation=E2=80=9D hook. That means use= rs can run an attach command that does not change attachment state at all, = yet still triggers a full parent validation attempt.

That is especially questionable if there are still other invalid child i= ndexes elsewhere under the same parent. In that case, each already-attached= ATTACH command will do the validation work again, but it is already known = in advance that the parent still cannot become valid. So this is not =E2=80= =9Creinvalidating=E2=80=9D anything, but it is repeated checking with no st= ate change, which feels misplaced on a no-op path.

Because of that, I do not think patch 1 should be the main bug fix. At m= ost, I would see it as an optional hardening patch.

3. The NOTICE added by patch 1 does not seem like a goo= d fit

The existing code explicitly says =E2=80=9CSilently do nothing if alread= y in the right state=E2=80=9D. Changing that into a NOTICE every time we hi= t the already-attached case seems noisy to me.

If the community decides that the validation call should stay in this pa= th, I would still suggest dropping the NOTICE. The command is syntactically= an ATTACH command, not a repair command, and emitting a message for an oth= erwise no-op case does not feel very PostgreSQL-like.

4. Please double-check coverage of all REINDEX entry po= ints

I agree with the direction in patch 2, but I think reviewers will want c= onfidence that all relevant REINDEX flows are covered consistently.

For example, it would be good to confirm that the fix behaves correctly = not just for REINDEX INDEX, but also for the broader forms tha= t eventually reach the same logic, such as REINDEX TABLE, and = that there is no alternate path where a repaired child index can still leav= e the parent stale.

5. Multi-level partition trees need explicit testing

= One especially important point here is recursion. If a repaired child index= causes its immediate parent partitioned index to become valid, and that pa= rent is itself a child of another partitioned index, we need to be sure tha= t validity propagates all the way up as intended.

The current reasoning suggests that validatePartitionedIndex() already handles that, but this is important enough that it should be de= monstrated with a regression test, not just assumed.

Minor comments:

  • In patch 1, I would avoid turning the already-attached path into a behav= ioral special case unless there is a strong reason to keep it. It would be = cleaner if the fix relied primarily on the actual state-changing paths.

  • If patch 1 remains, I would remove the NOTICE.

  • The commit message for patch 2 should clearly explain why REINDEX is the= right place to do this, rather than making ATTACH PARTITION the repair mec= hanism.

  • It may also help to mention explicitly whether the extra validation call= is only intended for indexes that were previously invalid and have just be= en repaired, since that is an important part of why the patch is reasonably= narrow.

I do not think the current patches are complete without regression cover= age. At minimum, I think the following tests should be added:

  1. Regular REINDEX case

    Create a partitioned table with a parent index left invalid initially, t= hen attach child indexes such that one child index is invalid. Repair that = child with plain REINDEX INDEX, and verify that the child beco= mes valid and the parent also becomes valid.

  2. REINDEX CONCURRENTLY case

    Same setup, but use REINDEX INDEX CONCURRENTLY. This should= be tested separately because the code path is different.

  3. Multi-level partition hierarchy

    Use at least a three-level hierarchy and verify that repairing a leaf-le= vel invalid child index can cause validity to propagate upward through inte= rmediate partitioned indexes.

  4. Negative case

    Repair one child index while another child index under the same parent r= emains invalid, and verify that the parent remains invalid.

  5. Already-attached ATTACH PARTITION case

    Only if patch 1 is kept: exercise ALTER INDEX ... ATTACH PARTITION= on a child index that is already attached, and verify both behavior= s:

  • parent becomes valid if all children are now valid

  • parent stays invalid if some other child is still invalid

My overall view is:

  • The bug itself looks real.
  • The diagnosi= s looks sound.
  • Patch 2 is the right direction and should be the pri= mary fix.
  • Patch 1 is much less compelling as written, and I would n= ot take it as the main solution.
  • The series needs regression tests = before it is ready.

Regards,

Haibo=C2=A0

Hi, Moha= med
I took a look at this patch and added some regression coverage for i= t.
While doing that, I found that the current concurrent-path fix is not= quite complete. The new tests exposed crashes in existing REINDEX CONCURRE= NTLY regression coverage, and the root cause appears to be that in the conc= urrent path, validatePartitionedIndex() can eventually reach catalog update= code at a point where there is no active/registered snapshot. That leads t= o the HaveRegisteredOrActiveSnapshot() assertion failure.
So the overall= bug diagnosis still looks correct to me, and the plain REINDEX direction a= lso looks right, but the REINDEX CONCURRENTLY path needs an additional fix = around the call site/context.
Based on that, I prepared a v2 on top of y= our patch. It includes:
  • a fix for the concurrent-path snapshot i= ssue
  • narrower handling for the concurrent path so it only does pare= nt revalidation for the actual repair case
  • regression tests coverin= g:
  • plain REINDEX INDEX
  • a negative case where another invali= d sibling keeps the parent invalid
  • multi-level partition hierarchie= s
  • REINDEX TABLE
If my understanding above looks right to y= ou, I think this v2 is a better base for further review.
Thanks,
Haib= o
--000000000000eb0bed064f25dc18-- --000000000000eb0bee064f25dc1a Content-Type: application/octet-stream; name="v2-0001-fix-revalidate-parent-partitioned-index-after-chi.patch" Content-Disposition: attachment; filename="v2-0001-fix-revalidate-parent-partitioned-index-after-chi.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mntpgcp40 RnJvbSBjYmNmMjdkZDUxZjA4ZDlkMzEwM2RkOThkOGY5ZjFlYzJhOThlZTExIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBIYWlibyBZYW4gPGhhaWJvLnlhbkBhcHBsZS5jb20+CkRhdGU6 IEZyaSwgMTAgQXByIDIwMjYgMTk6MDc6MTcgLTA3MDAKU3ViamVjdDogW1BBVENIIHYyXSBmaXg6 IHJldmFsaWRhdGUgcGFyZW50IHBhcnRpdGlvbmVkIGluZGV4IGFmdGVyIGNoaWxkCiBSRUlOREVY CgpXaGVuIFJFSU5ERVggcmVwYWlycyBhbiBpbnZhbGlkIGNoaWxkIHBhcnRpdGlvbiBpbmRleCwg dGhlIHBhcmVudApwYXJ0aXRpb25lZCBpbmRleCBjYW4gcmVtYWluIHN0dWNrIHdpdGggaW5kaXN2 YWxpZCA9IGZhbHNlIGJlY2F1c2UKdmFsaWRhdGVQYXJ0aXRpb25lZEluZGV4KCkgaXMgbm90IGNh bGxlZCBmcm9tIHRoZSBjb3JyZXNwb25kaW5nClJFSU5ERVggcGF0aC4KCkV4cG9ydCB2YWxpZGF0 ZVBhcnRpdGlvbmVkSW5kZXgoKSBhbmQgaW52b2tlIGl0IHdoZW4gUkVJTkRFWCBhY3R1YWxseQpy ZXBhaXJzIGEgcHJldmlvdXNseSBpbnZhbGlkIGNoaWxkIHBhcnRpdGlvbiBpbmRleC4gIEZvciBw bGFpbgpSRUlOREVYLCBkbyB0aGlzIGFmdGVyIENvbW1hbmRDb3VudGVySW5jcmVtZW50KCkgc28g dGhlIGNoaWxkJ3MgbmV3CmluZGlzdmFsaWQgc3RhdGUgaXMgdmlzaWJsZS4gIERvIHRoZSBlcXVp dmFsZW50IGZvciBSRUlOREVYCkNPTkNVUlJFTlRMWSBvbmx5IGZvciB0aGUgdHJ1ZSByZXBhaXIg Y2FzZSBhbmQgYXQgYSBwb2ludCB3aXRoIHRoZQpyZXF1aXJlZCBzbmFwc2hvdC9jYXRhbG9nLXVw ZGF0ZSBwcmVjb25kaXRpb25zLgoKQWRkIHJlZ3Jlc3Npb24gdGVzdHMgZm9yIHBsYWluIFJFSU5E RVgsIHBhcnRpYWwgcmVwYWlyIHdpdGggYW5vdGhlcgppbnZhbGlkIHNpYmxpbmcsIG11bHRpLWxl dmVsIHBhcnRpdGlvbiB0cmVlcywgYW5kIFJFSU5ERVggVEFCTEUuCi0tLQogc3JjL2JhY2tlbmQv Y2F0YWxvZy9pbmRleC5jICAgICAgICAgICAgfCAgMzIgKysrKwogc3JjL2JhY2tlbmQvY29tbWFu ZHMvaW5kZXhjbWRzLmMgICAgICAgfCAgNDIgKysrKysrCiBzcmMvYmFja2VuZC9jb21tYW5kcy90 YWJsZWNtZHMuYyAgICAgICB8ICAgOSArLQogc3JjL2luY2x1ZGUvY29tbWFuZHMvdGFibGVjbWRz LmggICAgICAgfCAgIDIgKwogc3JjL3Rlc3QvcmVncmVzcy9leHBlY3RlZC9pbmRleGluZy5vdXQg fCAxOTYgKysrKysrKysrKysrKysrKysrKysrKysrKwogc3JjL3Rlc3QvcmVncmVzcy9zcWwvaW5k ZXhpbmcuc3FsICAgICAgfCAxMjQgKysrKysrKysrKysrKysrKwogNiBmaWxlcyBjaGFuZ2VkLCA0 MDIgaW5zZXJ0aW9ucygrKSwgMyBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQgYS9zcmMvYmFja2Vu ZC9jYXRhbG9nL2luZGV4LmMgYi9zcmMvYmFja2VuZC9jYXRhbG9nL2luZGV4LmMKaW5kZXggOTQw N2MzNTdmMjcuLjMwYzg3MTQ4MjU1IDEwMDY0NAotLS0gYS9zcmMvYmFja2VuZC9jYXRhbG9nL2lu ZGV4LmMKKysrIGIvc3JjL2JhY2tlbmQvY2F0YWxvZy9pbmRleC5jCkBAIC0zOTA1LDYgKzM5MDUs MzggQEAgcmVpbmRleF9pbmRleChjb25zdCBSZWluZGV4U3RtdCAqc3RtdCwgT2lkIGluZGV4SWQs CiAJCQlDYWNoZUludmFsaWRhdGVSZWxjYWNoZShoZWFwUmVsYXRpb24pOwogCQl9CiAKKwkJLyoK KwkJICogSWYgdGhpcyBpbmRleCBpcyBhIHBhcnRpdGlvbiBvZiBhIHBhcnRpdGlvbmVkIGluZGV4 LCBhbmQgd2UganVzdAorCQkgKiBtYXJrZWQgaXQgdmFsaWQsIGNoZWNrIGlmIHRoZSBwYXJlbnQg cGFydGl0aW9uZWQgaW5kZXggY2FuIG5vdyBiZQorCQkgKiBtYXJrZWQgdmFsaWQgdG9vLiAgVGhp cyBoYW5kbGVzIHRoZSBjYXNlIHdoZXJlIGFuIGludmFsaWQgcGFydGl0aW9uCisJCSAqIGluZGV4 IHdhcyBhdHRhY2hlZCB0byBhIHBhcnRpdGlvbmVkIGluZGV4IChtYWtpbmcgdGhlIHBhcmVudAor CQkgKiBpbnZhbGlkKSwgdGhlbiBsYXRlciBmaXhlZCB2aWEgUkVJTkRFWC4gIHZhbGlkYXRlUGFy dGl0aW9uZWRJbmRleAorCQkgKiB3aWxsIHJlY3Vyc2UgdXAgdGhlIGhpZXJhcmNoeSBpZiBuZWVk ZWQuCisJCSAqLworCQlpZiAoaW5kZXhfYmFkICYmIGlSZWwtPnJkX3JlbC0+cmVsaXNwYXJ0aXRp b24pCisJCXsKKwkJCU9pZAkJCXBhcmVudElkeElkOworCisJCQkvKiBNYWtlIHRoZSBjaGlsZCdz IGluZGlzdmFsaWQgdXBkYXRlIHZpc2libGUgZm9yIHZhbGlkYXRpb24gKi8KKwkJCUNvbW1hbmRD b3VudGVySW5jcmVtZW50KCk7CisKKwkJCXBhcmVudElkeElkID0gZ2V0X3BhcnRpdGlvbl9wYXJl bnQoaW5kZXhJZCwgZmFsc2UpOworCQkJaWYgKE9pZElzVmFsaWQocGFyZW50SWR4SWQpKQorCQkJ eworCQkJCVJlbGF0aW9uCXBhcmVudElkeDsKKwkJCQlSZWxhdGlvbglwYXJlbnRUYmw7CisKKwkJ CQlwYXJlbnRJZHggPSBpbmRleF9vcGVuKHBhcmVudElkeElkLCBBY2Nlc3NTaGFyZUxvY2spOwor CQkJCXBhcmVudFRibCA9IHRhYmxlX29wZW4ocGFyZW50SWR4LT5yZF9pbmRleC0+aW5kcmVsaWQs CisJCQkJCQkJCQkgICBBY2Nlc3NTaGFyZUxvY2spOworCisJCQkJdmFsaWRhdGVQYXJ0aXRpb25l ZEluZGV4KHBhcmVudElkeCwgcGFyZW50VGJsKTsKKworCQkJCXRhYmxlX2Nsb3NlKHBhcmVudFRi bCwgQWNjZXNzU2hhcmVMb2NrKTsKKwkJCQlpbmRleF9jbG9zZShwYXJlbnRJZHgsIEFjY2Vzc1No YXJlTG9jayk7CisJCQl9CisJCX0KKwogCQl0YWJsZV9jbG9zZShwZ19pbmRleCwgUm93RXhjbHVz aXZlTG9jayk7CiAJfQogCmRpZmYgLS1naXQgYS9zcmMvYmFja2VuZC9jb21tYW5kcy9pbmRleGNt ZHMuYyBiL3NyYy9iYWNrZW5kL2NvbW1hbmRzL2luZGV4Y21kcy5jCmluZGV4IDlhYjc0YzhkZjBh Li41NDg3N2QzMjZlNyAxMDA2NDQKLS0tIGEvc3JjL2JhY2tlbmQvY29tbWFuZHMvaW5kZXhjbWRz LmMKKysrIGIvc3JjL2JhY2tlbmQvY29tbWFuZHMvaW5kZXhjbWRzLmMKQEAgLTM0LDYgKzM0LDcg QEAKICNpbmNsdWRlICJjYXRhbG9nL3BnX2NvbnN0cmFpbnQuaCIKICNpbmNsdWRlICJjYXRhbG9n L3BnX2RhdGFiYXNlLmgiCiAjaW5jbHVkZSAiY2F0YWxvZy9wZ19pbmhlcml0cy5oIgorI2luY2x1 ZGUgImNhdGFsb2cvcGFydGl0aW9uLmgiCiAjaW5jbHVkZSAiY2F0YWxvZy9wZ19uYW1lc3BhY2Uu aCIKICNpbmNsdWRlICJjYXRhbG9nL3BnX29wY2xhc3MuaCIKICNpbmNsdWRlICJjYXRhbG9nL3Bn X3RhYmxlc3BhY2UuaCIKQEAgLTM2MDEsNiArMzYwMiw3IEBAIFJlaW5kZXhSZWxhdGlvbkNvbmN1 cnJlbnRseShjb25zdCBSZWluZGV4U3RtdCAqc3RtdCwgT2lkIHJlbGF0aW9uT2lkLCBjb25zdCBS ZWluCiAJCU9pZAkJCXRhYmxlSWQ7CiAJCU9pZAkJCWFtSWQ7CiAJCWJvb2wJCXNhZmU7CQkvKiBm b3Igc2V0X2luZGV4c2FmZV9wcm9jZmxhZ3MgKi8KKwkJYm9vbAkJd2FzSW52YWxpZDsgLyogaW5k ZXggd2FzIGludmFsaWQgYmVmb3JlIHJlaW5kZXggKi8KIAl9IFJlaW5kZXhJbmRleEluZm87CiAJ TGlzdAkgICAqaGVhcFJlbGF0aW9uSWRzID0gTklMOwogCUxpc3QJICAgKmluZGV4SWRzID0gTklM OwpAQCAtMzk2MSw2ICszOTYzLDcgQEAgUmVpbmRleFJlbGF0aW9uQ29uY3VycmVudGx5KGNvbnN0 IFJlaW5kZXhTdG10ICpzdG10LCBPaWQgcmVsYXRpb25PaWQsIGNvbnN0IFJlaW4KIAogCQlpZHgt PnRhYmxlSWQgPSBSZWxhdGlvbkdldFJlbGlkKGhlYXBSZWwpOwogCQlpZHgtPmFtSWQgPSBpbmRl eFJlbC0+cmRfcmVsLT5yZWxhbTsKKwkJaWR4LT53YXNJbnZhbGlkID0gIWluZGV4UmVsLT5yZF9p bmRleC0+aW5kaXN2YWxpZDsKIAogCQkvKiBUaGlzIGZ1bmN0aW9uIHNob3VsZG4ndCBiZSBjYWxs ZWQgZm9yIHRlbXBvcmFyeSByZWxhdGlvbnMuICovCiAJCWlmIChpbmRleFJlbC0+cmRfcmVsLT5y ZWxwZXJzaXN0ZW5jZSA9PSBSRUxQRVJTSVNURU5DRV9URU1QKQpAQCAtNDMyMCw2ICs0MzIzLDQ1 IEBAIFJlaW5kZXhSZWxhdGlvbkNvbmN1cnJlbnRseShjb25zdCBSZWluZGV4U3RtdCAqc3RtdCwg T2lkIHJlbGF0aW9uT2lkLCBjb25zdCBSZWluCiAJCSAqIGNoYXJhY3RlcnMuCiAJCSAqLwogCQlD b21tYW5kQ291bnRlckluY3JlbWVudCgpOworCisJCS8qCisJCSAqIElmIGEgcHJldmlvdXNseS1p bnZhbGlkIHBhcnRpdGlvbiBpbmRleCB3YXMganVzdCByZXBsYWNlZCBieQorCQkgKiBhIHZhbGlk IG9uZSAoaS5lLiwgdGhlIG9sZCBpbmRleCB3YXMgaW52YWxpZCBiZWZvcmUgdGhpcworCQkgKiBS RUlOREVYKSwgY2hlY2sgd2hldGhlciB0aGUgcGFyZW50IHBhcnRpdGlvbmVkIGluZGV4IGNhbiBu b3cKKwkJICogYmUgbWFya2VkIHZhbGlkLiAgV2Ugb25seSBkbyB0aGlzIGZvciB0aGUgIndhcyBp bnZhbGlkIC0+IG5vdworCQkgKiB2YWxpZCIgdHJhbnNpdGlvbiB0byBtYXRjaCB0aGUgbm9uLWNv bmN1cnJlbnQgcGF0aCBpbgorCQkgKiByZWluZGV4X2luZGV4KCkuCisJCSAqCisJCSAqIEEgc25h cHNob3QgaXMgbmVlZGVkIGJlY2F1c2UgdmFsaWRhdGVQYXJ0aXRpb25lZEluZGV4KCkgbWF5CisJ CSAqIHVwZGF0ZSBwZ19pbmRleCB2aWEgQ2F0YWxvZ1R1cGxlVXBkYXRlKCksIHdoaWNoIHJlcXVp cmVzIGFuCisJCSAqIGFjdGl2ZSBzbmFwc2hvdC4gIFRoaXMgaXMgc2FmZTogdGhlIENDSSBhYm92 ZSBoYXMgbWFkZSB0aGUKKwkJICogc3dhcCB2aXNpYmxlLCBzbyB0aGUgc25hcHNob3Qgd2lsbCBz ZWUgdGhlIG5ldyBpbmRleCBpbiBpdHMKKwkJICogY29ycmVjdCBwYXJ0aXRpb24gcG9zaXRpb24u CisJCSAqLworCQlpZiAob2xkaWR4LT53YXNJbnZhbGlkICYmIGdldF9yZWxfcmVsaXNwYXJ0aXRp b24obmV3aWR4LT5pbmRleElkKSkKKwkJeworCQkJT2lkCQkJcGFyZW50SWR4SWQ7CisKKwkJCXBh cmVudElkeElkID0gZ2V0X3BhcnRpdGlvbl9wYXJlbnQobmV3aWR4LT5pbmRleElkLCB0cnVlKTsK KwkJCWlmIChPaWRJc1ZhbGlkKHBhcmVudElkeElkKSkKKwkJCXsKKwkJCQlSZWxhdGlvbglwYXJl bnRJZHg7CisJCQkJUmVsYXRpb24JcGFyZW50VGJsOworCisJCQkJUHVzaEFjdGl2ZVNuYXBzaG90 KEdldFRyYW5zYWN0aW9uU25hcHNob3QoKSk7CisKKwkJCQlwYXJlbnRJZHggPSBpbmRleF9vcGVu KHBhcmVudElkeElkLCBBY2Nlc3NTaGFyZUxvY2spOworCQkJCXBhcmVudFRibCA9IHRhYmxlX29w ZW4ocGFyZW50SWR4LT5yZF9pbmRleC0+aW5kcmVsaWQsCisJCQkJCQkJCQkgICBBY2Nlc3NTaGFy ZUxvY2spOworCisJCQkJdmFsaWRhdGVQYXJ0aXRpb25lZEluZGV4KHBhcmVudElkeCwgcGFyZW50 VGJsKTsKKworCQkJCXRhYmxlX2Nsb3NlKHBhcmVudFRibCwgQWNjZXNzU2hhcmVMb2NrKTsKKwkJ CQlpbmRleF9jbG9zZShwYXJlbnRJZHgsIEFjY2Vzc1NoYXJlTG9jayk7CisKKwkJCQlQb3BBY3Rp dmVTbmFwc2hvdCgpOworCQkJfQorCQl9CiAJfQogCiAJLyogQ29tbWl0IHRoaXMgdHJhbnNhY3Rp b24gYW5kIG1ha2UgaW5kZXggc3dhcHMgdmlzaWJsZSAqLwpkaWZmIC0tZ2l0IGEvc3JjL2JhY2tl bmQvY29tbWFuZHMvdGFibGVjbWRzLmMgYi9zcmMvYmFja2VuZC9jb21tYW5kcy90YWJsZWNtZHMu YwppbmRleCBlZWMwOWJhMWRlZC4uZWNjYTIyZWZmYjMgMTAwNjQ0Ci0tLSBhL3NyYy9iYWNrZW5k L2NvbW1hbmRzL3RhYmxlY21kcy5jCisrKyBiL3NyYy9iYWNrZW5kL2NvbW1hbmRzL3RhYmxlY21k cy5jCkBAIC03NDYsNyArNzQ2LDYgQEAgc3RhdGljIHZvaWQgRGV0YWNoUGFydGl0aW9uRmluYWxp emUoUmVsYXRpb24gcmVsLCBSZWxhdGlvbiBwYXJ0UmVsLAogc3RhdGljIE9iamVjdEFkZHJlc3Mg QVRFeGVjRGV0YWNoUGFydGl0aW9uRmluYWxpemUoUmVsYXRpb24gcmVsLCBSYW5nZVZhciAqbmFt ZSk7CiBzdGF0aWMgT2JqZWN0QWRkcmVzcyBBVEV4ZWNBdHRhY2hQYXJ0aXRpb25JZHgoTGlzdCAq KndxdWV1ZSwgUmVsYXRpb24gcGFyZW50SWR4LAogCQkJCQkJCQkJCQkgIFJhbmdlVmFyICpuYW1l KTsKLXN0YXRpYyB2b2lkIHZhbGlkYXRlUGFydGl0aW9uZWRJbmRleChSZWxhdGlvbiBwYXJ0ZWRJ ZHgsIFJlbGF0aW9uIHBhcnRlZFRibCk7CiBzdGF0aWMgdm9pZCByZWZ1c2VEdXBlSW5kZXhBdHRh Y2goUmVsYXRpb24gcGFyZW50SWR4LCBSZWxhdGlvbiBwYXJ0SWR4LAogCQkJCQkJCQkgIFJlbGF0 aW9uIHBhcnRpdGlvblRibCk7CiBzdGF0aWMgdm9pZCB2ZXJpZnlQYXJ0aXRpb25JbmRleE5vdE51 bGwoSW5kZXhJbmZvICppaW5mbywgUmVsYXRpb24gcGFydGl0aW9uKTsKQEAgLTIyMDYyLDEyICsy MjA2MSwxNiBAQCByZWZ1c2VEdXBlSW5kZXhBdHRhY2goUmVsYXRpb24gcGFyZW50SWR4LCBSZWxh dGlvbiBwYXJ0SWR4LCBSZWxhdGlvbiBwYXJ0aXRpb25UYgogfQogCiAvKgorICogdmFsaWRhdGVQ YXJ0aXRpb25lZEluZGV4CisgKgogICogVmVyaWZ5IHdoZXRoZXIgdGhlIHNldCBvZiBhdHRhY2hl ZCBwYXJ0aXRpb24gaW5kZXhlcyB0byBhIHBhcmVudCBpbmRleCBvbgogICogYSBwYXJ0aXRpb25l ZCB0YWJsZSBpcyBjb21wbGV0ZS4gIElmIGl0IGlzLCBtYXJrIHRoZSBwYXJlbnQgaW5kZXggdmFs aWQuCiAgKgotICogVGhpcyBzaG91bGQgYmUgY2FsbGVkIGVhY2ggdGltZSBhIHBhcnRpdGlvbiBp bmRleCBpcyBhdHRhY2hlZC4KKyAqIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBlYWNoIHRpbWUgYSBw YXJ0aXRpb24gaW5kZXggaXMgYXR0YWNoZWQsIGFuZCBhbHNvCisgKiBhZnRlciBhIHBhcnRpdGlv biBpbmRleCBpcyByZXBhaXJlZCB2aWEgUkVJTkRFWCwgc28gdGhhdCB0aGUgcGFyZW50IGNhbgor ICogYmUgbWFya2VkIHZhbGlkIG9uY2UgYWxsIGNoaWxkcmVuIGFyZSB2YWxpZC4KICAqLwotc3Rh dGljIHZvaWQKK3ZvaWQKIHZhbGlkYXRlUGFydGl0aW9uZWRJbmRleChSZWxhdGlvbiBwYXJ0ZWRJ ZHgsIFJlbGF0aW9uIHBhcnRlZFRibCkKIHsKIAlSZWxhdGlvbglpbmhlcml0c1JlbDsKZGlmZiAt LWdpdCBhL3NyYy9pbmNsdWRlL2NvbW1hbmRzL3RhYmxlY21kcy5oIGIvc3JjL2luY2x1ZGUvY29t bWFuZHMvdGFibGVjbWRzLmgKaW5kZXggYzNkODUxOGNiNjIuLjg0OTgzZmI3ZTk1IDEwMDY0NAot LS0gYS9zcmMvaW5jbHVkZS9jb21tYW5kcy90YWJsZWNtZHMuaAorKysgYi9zcmMvaW5jbHVkZS9j b21tYW5kcy90YWJsZWNtZHMuaApAQCAtMTA4LDQgKzEwOCw2IEBAIGV4dGVybiB2b2lkIFJhbmdl VmFyQ2FsbGJhY2tPd25zUmVsYXRpb24oY29uc3QgUmFuZ2VWYXIgKnJlbGF0aW9uLAogZXh0ZXJu IGJvb2wgUGFydENvbnN0cmFpbnRJbXBsaWVkQnlSZWxDb25zdHJhaW50KFJlbGF0aW9uIHNjYW5y ZWwsCiAJCQkJCQkJCQkJCQkgTGlzdCAqcGFydENvbnN0cmFpbnQpOwogCitleHRlcm4gdm9pZCB2 YWxpZGF0ZVBhcnRpdGlvbmVkSW5kZXgoUmVsYXRpb24gcGFydGVkSWR4LCBSZWxhdGlvbiBwYXJ0 ZWRUYmwpOworCiAjZW5kaWYJCQkJCQkJLyogVEFCTEVDTURTX0ggKi8KZGlmZiAtLWdpdCBhL3Ny Yy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvaW5kZXhpbmcub3V0IGIvc3JjL3Rlc3QvcmVncmVzcy9l eHBlY3RlZC9pbmRleGluZy5vdXQKaW5kZXggZjUwODY4Y2E2YTYuLjA1MTkzNDAxMzE1IDEwMDY0 NAotLS0gYS9zcmMvdGVzdC9yZWdyZXNzL2V4cGVjdGVkL2luZGV4aW5nLm91dAorKysgYi9zcmMv dGVzdC9yZWdyZXNzL2V4cGVjdGVkL2luZGV4aW5nLm91dApAQCAtMTU5MSw2ICsxNTkxLDIwMiBA QCBzZWxlY3QgaW5kZXhyZWxpZDo6cmVnY2xhc3MsIGluZGlzdmFsaWQsCiAoNSByb3dzKQogCiBk cm9wIHRhYmxlIHBhcnRlZF9pc3ZhbGlkX3RhYjsKKy0tIENoZWNrIHRoYXQgUkVJTkRFWCBvZiBh biBpbnZhbGlkIHBhcnRpdGlvbiBpbmRleCB2YWxpZGF0ZXMgdGhlIHBhcmVudAorLS0gcGFydGl0 aW9uZWQgaW5kZXggKGFuZCByZWN1cnNlcyB1cHdhcmQgdGhyb3VnaCBtdWx0aS1sZXZlbCBoaWVy YXJjaGllcykuCistLSBUZXN0OiBiYXNpYyBSRUlOREVYIElOREVYIHJlcGFpcnMgaW52YWxpZCBj aGlsZCBhbmQgdmFsaWRhdGVzIHBhcmVudC4KK2NyZWF0ZSB0YWJsZSByZWluZGV4X3B2IChhIGlu dCwgYiBpbnQpIHBhcnRpdGlvbiBieSByYW5nZSAoYSk7CitjcmVhdGUgdGFibGUgcmVpbmRleF9w dl8xIHBhcnRpdGlvbiBvZiByZWluZGV4X3B2IGZvciB2YWx1ZXMgZnJvbSAoMSkgdG8gKDEwKTsK Ky0tIENyZWF0ZSBhbiBpbnZhbGlkIGluZGV4IG9uIHRoZSBwYXJ0aXRpb24gdmlhIGEgZmFpbGVk IGNvbmN1cnJlbnQgYnVpbGQuCitpbnNlcnQgaW50byByZWluZGV4X3B2XzEgdmFsdWVzICgxLCAw KTsKK2NyZWF0ZSBpbmRleCBjb25jdXJyZW50bHkgcmVpbmRleF9wdl8xX2lkeCBvbiByZWluZGV4 X3B2XzEgKChhIC8gYikpOworRVJST1I6ICBkaXZpc2lvbiBieSB6ZXJvCistLSBDcmVhdGUgdGhl IHBhcnRpdGlvbmVkIGluZGV4OyBpdCBwaWNrcyB1cCB0aGUgaW52YWxpZCBjaGlsZCwgc28gYm90 aAorLS0gcGFyZW50IGFuZCBjaGlsZCBhcmUgaW52YWxpZC4KK2NyZWF0ZSBpbmRleCByZWluZGV4 X3B2X2lkeCBvbiByZWluZGV4X3B2ICgoYSAvIGIpKTsKK3NlbGVjdCBpbmRleHJlbGlkOjpyZWdj bGFzcywgaW5kaXN2YWxpZAorICBmcm9tIHBnX2luZGV4IHdoZXJlIGluZGV4cmVsaWQ6OnJlZ2Ns YXNzOjp0ZXh0IGxpa2UgJ3JlaW5kZXhfcHYlJworICBvcmRlciBieSBpbmRleHJlbGlkOjpyZWdj bGFzczo6dGV4dCBjb2xsYXRlICJDIjsKKyAgICBpbmRleHJlbGlkICAgIHwgaW5kaXN2YWxpZCAK Ky0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0KKyByZWluZGV4X3B2XzFfaWR4IHwgZgor IHJlaW5kZXhfcHZfaWR4ICAgfCBmCisoMiByb3dzKQorCistLSBGaXggdGhlIGRhdGEgYW5kIFJF SU5ERVggdGhlIGNoaWxkLiAgVXNlIFRSVU5DQVRFIChub3QgREVMRVRFKSBzbyB0aGF0CistLSBk ZWFkIHR1cGxlcyB3aXRoIHRoZSBlcnJvci1jYXVzaW5nIGV4cHJlc3Npb24gYXJlIHBoeXNpY2Fs bHkgcmVtb3ZlZDsKKy0tIFJFSU5ERVggZXZhbHVhdGVzIGV4cHJlc3Npb25zIG9uIGFsbCBoZWFw IHR1cGxlcyBpbmNsdWRpbmcgcmVjZW50bHktZGVhZAorLS0gb25lcywgYW5kIGNvbmN1cnJlbnQg dGVzdCBzZXNzaW9ucyBjYW4gcHJldmVudCBWQUNVVU0gZnJvbSBjbGVhbmluZyB0aGVtLgordHJ1 bmNhdGUgcmVpbmRleF9wdl8xOworcmVpbmRleCBpbmRleCByZWluZGV4X3B2XzFfaWR4OworLS0g Qm90aCBjaGlsZCBhbmQgcGFyZW50IHNob3VsZCBub3cgYmUgdmFsaWQuCitzZWxlY3QgaW5kZXhy ZWxpZDo6cmVnY2xhc3MsIGluZGlzdmFsaWQKKyAgZnJvbSBwZ19pbmRleCB3aGVyZSBpbmRleHJl bGlkOjpyZWdjbGFzczo6dGV4dCBsaWtlICdyZWluZGV4X3B2JScKKyAgb3JkZXIgYnkgaW5kZXhy ZWxpZDo6cmVnY2xhc3M6OnRleHQgY29sbGF0ZSAiQyI7CisgICAgaW5kZXhyZWxpZCAgICB8IGlu ZGlzdmFsaWQgCistLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tCisgcmVpbmRleF9wdl8x X2lkeCB8IHQKKyByZWluZGV4X3B2X2lkeCAgIHwgdAorKDIgcm93cykKKworZHJvcCB0YWJsZSBy ZWluZGV4X3B2OworLS0gVGVzdDogbmVnYXRpdmUgY2FzZSDigJQgcGFyZW50IHN0YXlzIGludmFs aWQgd2hpbGUgYW55IGNoaWxkIHJlbWFpbnMgaW52YWxpZC4KK2NyZWF0ZSB0YWJsZSByZWluZGV4 X3B2MiAoYSBpbnQsIGIgaW50KSBwYXJ0aXRpb24gYnkgcmFuZ2UgKGEpOworY3JlYXRlIHRhYmxl IHJlaW5kZXhfcHYyXzEgcGFydGl0aW9uIG9mIHJlaW5kZXhfcHYyIGZvciB2YWx1ZXMgZnJvbSAo MSkgdG8gKDEwKTsKK2NyZWF0ZSB0YWJsZSByZWluZGV4X3B2Ml8yIHBhcnRpdGlvbiBvZiByZWlu ZGV4X3B2MiBmb3IgdmFsdWVzIGZyb20gKDEwKSB0byAoMjApOworLS0gQ3JlYXRlIGludmFsaWQg aW5kZXhlcyBvbiBib3RoIGNoaWxkcmVuLgoraW5zZXJ0IGludG8gcmVpbmRleF9wdjJfMSB2YWx1 ZXMgKDEsIDApOworY3JlYXRlIGluZGV4IGNvbmN1cnJlbnRseSByZWluZGV4X3B2Ml8xX2lkeCBv biByZWluZGV4X3B2Ml8xICgoYSAvIGIpKTsKK0VSUk9SOiAgZGl2aXNpb24gYnkgemVybworaW5z ZXJ0IGludG8gcmVpbmRleF9wdjJfMiB2YWx1ZXMgKDEwLCAwKTsKK2NyZWF0ZSBpbmRleCBjb25j dXJyZW50bHkgcmVpbmRleF9wdjJfMl9pZHggb24gcmVpbmRleF9wdjJfMiAoKGEgLyBiKSk7CitF UlJPUjogIGRpdmlzaW9uIGJ5IHplcm8KKy0tIFBhcmVudCBwaWNrcyB1cCBib3RoIGludmFsaWQg Y2hpbGRyZW4uCitjcmVhdGUgaW5kZXggcmVpbmRleF9wdjJfaWR4IG9uIHJlaW5kZXhfcHYyICgo YSAvIGIpKTsKKy0tIEZpeCBvbmx5IGNoaWxkIDEgYW5kIHJlaW5kZXggaXQuCit0cnVuY2F0ZSBy ZWluZGV4X3B2Ml8xOworcmVpbmRleCBpbmRleCByZWluZGV4X3B2Ml8xX2lkeDsKKy0tIFBhcmVu dCBtdXN0IHJlbWFpbiBpbnZhbGlkIGJlY2F1c2UgY2hpbGQgMiBpcyBzdGlsbCBpbnZhbGlkLgor c2VsZWN0IGluZGV4cmVsaWQ6OnJlZ2NsYXNzLCBpbmRpc3ZhbGlkCisgIGZyb20gcGdfaW5kZXgg d2hlcmUgaW5kZXhyZWxpZDo6cmVnY2xhc3M6OnRleHQgbGlrZSAncmVpbmRleF9wdjIlJworICBv cmRlciBieSBpbmRleHJlbGlkOjpyZWdjbGFzczo6dGV4dCBjb2xsYXRlICJDIjsKKyAgICBpbmRl eHJlbGlkICAgICB8IGluZGlzdmFsaWQgCistLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0t LQorIHJlaW5kZXhfcHYyXzFfaWR4IHwgdAorIHJlaW5kZXhfcHYyXzJfaWR4IHwgZgorIHJlaW5k ZXhfcHYyX2lkeCAgIHwgZgorKDMgcm93cykKKworLS0gTm93IGZpeCBjaGlsZCAyIGFzIHdlbGwu Cit0cnVuY2F0ZSByZWluZGV4X3B2Ml8yOworcmVpbmRleCBpbmRleCByZWluZGV4X3B2Ml8yX2lk eDsKKy0tIE5vdyB0aGUgcGFyZW50IHNob3VsZCBiZSB2YWxpZC4KK3NlbGVjdCBpbmRleHJlbGlk OjpyZWdjbGFzcywgaW5kaXN2YWxpZAorICBmcm9tIHBnX2luZGV4IHdoZXJlIGluZGV4cmVsaWQ6 OnJlZ2NsYXNzOjp0ZXh0IGxpa2UgJ3JlaW5kZXhfcHYyJScKKyAgb3JkZXIgYnkgaW5kZXhyZWxp ZDo6cmVnY2xhc3M6OnRleHQgY29sbGF0ZSAiQyI7CisgICAgaW5kZXhyZWxpZCAgICAgfCBpbmRp c3ZhbGlkIAorLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0KKyByZWluZGV4X3B2Ml8x X2lkeCB8IHQKKyByZWluZGV4X3B2Ml8yX2lkeCB8IHQKKyByZWluZGV4X3B2Ml9pZHggICB8IHQK KygzIHJvd3MpCisKK2Ryb3AgdGFibGUgcmVpbmRleF9wdjI7CistLSBUZXN0OiBtdWx0aS1sZXZl bCBoaWVyYXJjaHkg4oCUIHZhbGlkaXR5IHByb3BhZ2F0ZXMgdXB3YXJkIHRocm91Z2ggYWxsIGxl dmVscy4KK2NyZWF0ZSB0YWJsZSByZWluZGV4X3B2MyAoYSBpbnQsIGIgaW50KSBwYXJ0aXRpb24g YnkgcmFuZ2UgKGEpOworY3JlYXRlIHRhYmxlIHJlaW5kZXhfcHYzX21pZCBwYXJ0aXRpb24gb2Yg cmVpbmRleF9wdjMKKyAgZm9yIHZhbHVlcyBmcm9tICgxKSB0byAoMjApIHBhcnRpdGlvbiBieSBy YW5nZSAoYSk7CitjcmVhdGUgdGFibGUgcmVpbmRleF9wdjNfbWlkXzEgcGFydGl0aW9uIG9mIHJl aW5kZXhfcHYzX21pZAorICBmb3IgdmFsdWVzIGZyb20gKDEpIHRvICgxMCk7CitjcmVhdGUgdGFi bGUgcmVpbmRleF9wdjNfbWlkXzIgcGFydGl0aW9uIG9mIHJlaW5kZXhfcHYzX21pZAorICBmb3Ig dmFsdWVzIGZyb20gKDEwKSB0byAoMjApOworY3JlYXRlIHRhYmxlIHJlaW5kZXhfcHYzX290aGVy IHBhcnRpdGlvbiBvZiByZWluZGV4X3B2MworICBmb3IgdmFsdWVzIGZyb20gKDIwKSB0byAoMzAp OworLS0gQ3JlYXRlIGFuIGludmFsaWQgaW5kZXggb25seSBvbiBvbmUgbGVhZi4KK2luc2VydCBp bnRvIHJlaW5kZXhfcHYzX21pZF8xIHZhbHVlcyAoMSwgMCk7CitjcmVhdGUgaW5kZXggY29uY3Vy cmVudGx5IHJlaW5kZXhfcHYzX21pZF8xX2lkeCBvbiByZWluZGV4X3B2M19taWRfMSAoKGEgLyBi KSk7CitFUlJPUjogIGRpdmlzaW9uIGJ5IHplcm8KKy0tIENyZWF0ZSB0aGUgdG9wLWxldmVsIHBh cnRpdGlvbmVkIGluZGV4LiAgVGhlIGludmFsaWQgbGVhZiBtYWtlcyB0aGUKKy0tIGludGVybWVk aWF0ZSBhbmQgcm9vdCBpbmRleGVzIGludmFsaWQgYXMgd2VsbC4KK2NyZWF0ZSBpbmRleCByZWlu ZGV4X3B2M19pZHggb24gcmVpbmRleF9wdjMgKChhIC8gYikpOworc2VsZWN0IGluZGV4cmVsaWQ6 OnJlZ2NsYXNzLCBpbmRpc3ZhbGlkLAorICAgICAgIGluZHJlbGlkOjpyZWdjbGFzcywgaW5ocGFy ZW50OjpyZWdjbGFzcworICBmcm9tIHBnX2luZGV4IGlkeCBsZWZ0IGpvaW4KKyAgICAgICBwZ19p bmhlcml0cyBpbmggb24gKGlkeC5pbmRleHJlbGlkID0gaW5oLmluaHJlbGlkKQorICB3aGVyZSBp bmRleHJlbGlkOjpyZWdjbGFzczo6dGV4dCBsaWtlICdyZWluZGV4X3B2MyUnCisgIG9yZGVyIGJ5 IGluZGV4cmVsaWQ6OnJlZ2NsYXNzOjp0ZXh0IGNvbGxhdGUgIkMiOworICAgICAgICAgaW5kZXhy ZWxpZCAgICAgICAgIHwgaW5kaXN2YWxpZCB8ICAgICBpbmRyZWxpZCAgICAgIHwgICAgICAgIGlu aHBhcmVudCAgICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0t LS0rLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIHJlaW5k ZXhfcHYzX2lkeCAgICAgICAgICAgIHwgZiAgICAgICAgICB8IHJlaW5kZXhfcHYzICAgICAgIHwg CisgcmVpbmRleF9wdjNfbWlkXzFfaWR4ICAgICAgfCBmICAgICAgICAgIHwgcmVpbmRleF9wdjNf bWlkXzEgfCByZWluZGV4X3B2M19taWRfZXhwcl9pZHgKKyByZWluZGV4X3B2M19taWRfMl9leHBy X2lkeCB8IHQgICAgICAgICAgfCByZWluZGV4X3B2M19taWRfMiB8IHJlaW5kZXhfcHYzX21pZF9l eHByX2lkeAorIHJlaW5kZXhfcHYzX21pZF9leHByX2lkeCAgIHwgZiAgICAgICAgICB8IHJlaW5k ZXhfcHYzX21pZCAgIHwgcmVpbmRleF9wdjNfaWR4CisgcmVpbmRleF9wdjNfb3RoZXJfZXhwcl9p ZHggfCB0ICAgICAgICAgIHwgcmVpbmRleF9wdjNfb3RoZXIgfCByZWluZGV4X3B2M19pZHgKKyg1 IHJvd3MpCisKKy0tIEZpeCBhbmQgcmVpbmRleCB0aGUgbGVhZi4KK3RydW5jYXRlIHJlaW5kZXhf cHYzX21pZF8xOworcmVpbmRleCBpbmRleCByZWluZGV4X3B2M19taWRfMV9pZHg7CistLSBBbGwg bGV2ZWxzIHNob3VsZCBub3cgYmUgdmFsaWQgKGNhc2NhZGluZyB1cHdhcmQpLgorc2VsZWN0IGlu ZGV4cmVsaWQ6OnJlZ2NsYXNzLCBpbmRpc3ZhbGlkLAorICAgICAgIGluZHJlbGlkOjpyZWdjbGFz cywgaW5ocGFyZW50OjpyZWdjbGFzcworICBmcm9tIHBnX2luZGV4IGlkeCBsZWZ0IGpvaW4KKyAg ICAgICBwZ19pbmhlcml0cyBpbmggb24gKGlkeC5pbmRleHJlbGlkID0gaW5oLmluaHJlbGlkKQor ICB3aGVyZSBpbmRleHJlbGlkOjpyZWdjbGFzczo6dGV4dCBsaWtlICdyZWluZGV4X3B2MyUnCisg IG9yZGVyIGJ5IGluZGV4cmVsaWQ6OnJlZ2NsYXNzOjp0ZXh0IGNvbGxhdGUgIkMiOworICAgICAg ICAgaW5kZXhyZWxpZCAgICAgICAgIHwgaW5kaXN2YWxpZCB8ICAgICBpbmRyZWxpZCAgICAgIHwg ICAgICAgIGluaHBhcmVudCAgICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSst LS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LQorIHJlaW5kZXhfcHYzX2lkeCAgICAgICAgICAgIHwgdCAgICAgICAgICB8IHJlaW5kZXhfcHYz ICAgICAgIHwgCisgcmVpbmRleF9wdjNfbWlkXzFfaWR4ICAgICAgfCB0ICAgICAgICAgIHwgcmVp bmRleF9wdjNfbWlkXzEgfCByZWluZGV4X3B2M19taWRfZXhwcl9pZHgKKyByZWluZGV4X3B2M19t aWRfMl9leHByX2lkeCB8IHQgICAgICAgICAgfCByZWluZGV4X3B2M19taWRfMiB8IHJlaW5kZXhf cHYzX21pZF9leHByX2lkeAorIHJlaW5kZXhfcHYzX21pZF9leHByX2lkeCAgIHwgdCAgICAgICAg ICB8IHJlaW5kZXhfcHYzX21pZCAgIHwgcmVpbmRleF9wdjNfaWR4CisgcmVpbmRleF9wdjNfb3Ro ZXJfZXhwcl9pZHggfCB0ICAgICAgICAgIHwgcmVpbmRleF9wdjNfb3RoZXIgfCByZWluZGV4X3B2 M19pZHgKKyg1IHJvd3MpCisKK2Ryb3AgdGFibGUgcmVpbmRleF9wdjM7CistLSBUZXN0OiBSRUlO REVYIFRBQkxFIG9uIGEgcGFydGl0aW9uIGFsc28gdmFsaWRhdGVzIHRoZSBwYXJlbnQuCitjcmVh dGUgdGFibGUgcmVpbmRleF9wdjQgKGEgaW50LCBiIGludCkgcGFydGl0aW9uIGJ5IHJhbmdlIChh KTsKK2NyZWF0ZSB0YWJsZSByZWluZGV4X3B2NF8xIHBhcnRpdGlvbiBvZiByZWluZGV4X3B2NCBm b3IgdmFsdWVzIGZyb20gKDEpIHRvICgxMCk7CitpbnNlcnQgaW50byByZWluZGV4X3B2NF8xIHZh bHVlcyAoMSwgMCk7CitjcmVhdGUgaW5kZXggY29uY3VycmVudGx5IHJlaW5kZXhfcHY0XzFfaWR4 IG9uIHJlaW5kZXhfcHY0XzEgKChhIC8gYikpOworRVJST1I6ICBkaXZpc2lvbiBieSB6ZXJvCitj cmVhdGUgaW5kZXggcmVpbmRleF9wdjRfaWR4IG9uIHJlaW5kZXhfcHY0ICgoYSAvIGIpKTsKKy0t IEFsc28gYWRkIGEgcmVndWxhciBpbmRleCBmb3IgUkVJTkRFWCBUQUJMRSB0byBwcm9jZXNzLgor Y3JlYXRlIGluZGV4IHJlaW5kZXhfcHY0X2FfaWR4IG9uIHJlaW5kZXhfcHY0IChhKTsKK3NlbGVj dCBpbmRleHJlbGlkOjpyZWdjbGFzcywgaW5kaXN2YWxpZAorICBmcm9tIHBnX2luZGV4IHdoZXJl IGluZGV4cmVsaWQ6OnJlZ2NsYXNzOjp0ZXh0IGxpa2UgJ3JlaW5kZXhfcHY0JScKKyAgb3JkZXIg YnkgaW5kZXhyZWxpZDo6cmVnY2xhc3M6OnRleHQgY29sbGF0ZSAiQyI7CisgICAgIGluZGV4cmVs aWQgICAgICB8IGluZGlzdmFsaWQgCistLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0t CisgcmVpbmRleF9wdjRfMV9hX2lkeCB8IHQKKyByZWluZGV4X3B2NF8xX2lkeCAgIHwgZgorIHJl aW5kZXhfcHY0X2FfaWR4ICAgfCB0CisgcmVpbmRleF9wdjRfaWR4ICAgICB8IGYKKyg0IHJvd3Mp CisKK3RydW5jYXRlIHJlaW5kZXhfcHY0XzE7CityZWluZGV4IHRhYmxlIHJlaW5kZXhfcHY0XzE7 CistLSBCb3RoIHRoZSBleHByZXNzaW9uIGluZGV4IGFuZCBwYXJlbnQgc2hvdWxkIGJlIHZhbGlk IG5vdy4KK3NlbGVjdCBpbmRleHJlbGlkOjpyZWdjbGFzcywgaW5kaXN2YWxpZAorICBmcm9tIHBn X2luZGV4IHdoZXJlIGluZGV4cmVsaWQ6OnJlZ2NsYXNzOjp0ZXh0IGxpa2UgJ3JlaW5kZXhfcHY0 JScKKyAgb3JkZXIgYnkgaW5kZXhyZWxpZDo6cmVnY2xhc3M6OnRleHQgY29sbGF0ZSAiQyI7Cisg ICAgIGluZGV4cmVsaWQgICAgICB8IGluZGlzdmFsaWQgCistLS0tLS0tLS0tLS0tLS0tLS0tLS0r LS0tLS0tLS0tLS0tCisgcmVpbmRleF9wdjRfMV9hX2lkeCB8IHQKKyByZWluZGV4X3B2NF8xX2lk eCAgIHwgdAorIHJlaW5kZXhfcHY0X2FfaWR4ICAgfCB0CisgcmVpbmRleF9wdjRfaWR4ICAgICB8 IHQKKyg0IHJvd3MpCisKK2Ryb3AgdGFibGUgcmVpbmRleF9wdjQ7CistLSBUZXN0OiBSRUlOREVY IElOREVYIENPTkNVUlJFTlRMWSBhbHNvIHZhbGlkYXRlcyB0aGUgcGFyZW50LgorY3JlYXRlIHRh YmxlIHJlaW5kZXhfcHY1IChhIGludCwgYiBpbnQpIHBhcnRpdGlvbiBieSByYW5nZSAoYSk7Citj cmVhdGUgdGFibGUgcmVpbmRleF9wdjVfMSBwYXJ0aXRpb24gb2YgcmVpbmRleF9wdjUgZm9yIHZh bHVlcyBmcm9tICgxKSB0byAoMTApOworaW5zZXJ0IGludG8gcmVpbmRleF9wdjVfMSB2YWx1ZXMg KDEsIDApOworY3JlYXRlIGluZGV4IGNvbmN1cnJlbnRseSByZWluZGV4X3B2NV8xX2lkeCBvbiBy ZWluZGV4X3B2NV8xICgoYSAvIGIpKTsKK0VSUk9SOiAgZGl2aXNpb24gYnkgemVybworY3JlYXRl IGluZGV4IHJlaW5kZXhfcHY1X2lkeCBvbiByZWluZGV4X3B2NSAoKGEgLyBiKSk7CitzZWxlY3Qg aW5kZXhyZWxpZDo6cmVnY2xhc3MsIGluZGlzdmFsaWQKKyAgZnJvbSBwZ19pbmRleCB3aGVyZSBp bmRleHJlbGlkOjpyZWdjbGFzczo6dGV4dCBsaWtlICdyZWluZGV4X3B2NSUnCisgIG9yZGVyIGJ5 IGluZGV4cmVsaWQ6OnJlZ2NsYXNzOjp0ZXh0IGNvbGxhdGUgIkMiOworICAgIGluZGV4cmVsaWQg ICAgIHwgaW5kaXN2YWxpZCAKKy0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tCisgcmVp bmRleF9wdjVfMV9pZHggfCBmCisgcmVpbmRleF9wdjVfaWR4ICAgfCBmCisoMiByb3dzKQorCit0 cnVuY2F0ZSByZWluZGV4X3B2NV8xOworcmVpbmRleCBpbmRleCBjb25jdXJyZW50bHkgcmVpbmRl eF9wdjVfMV9pZHg7CistLSBCb3RoIHNob3VsZCBiZSB2YWxpZC4KK3NlbGVjdCBpbmRleHJlbGlk OjpyZWdjbGFzcywgaW5kaXN2YWxpZAorICBmcm9tIHBnX2luZGV4IHdoZXJlIGluZGV4cmVsaWQ6 OnJlZ2NsYXNzOjp0ZXh0IGxpa2UgJ3JlaW5kZXhfcHY1JScKKyAgb3JkZXIgYnkgaW5kZXhyZWxp ZDo6cmVnY2xhc3M6OnRleHQgY29sbGF0ZSAiQyI7CisgICAgaW5kZXhyZWxpZCAgICAgfCBpbmRp c3ZhbGlkIAorLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0KKyByZWluZGV4X3B2NV8x X2lkeCB8IHQKKyByZWluZGV4X3B2NV9pZHggICB8IHQKKygyIHJvd3MpCisKK2Ryb3AgdGFibGUg cmVpbmRleF9wdjU7CiAtLSBDaGVjayBzdGF0ZSBvZiByZXBsaWNhIGluZGV4ZXMgd2hlbiBhdHRh Y2hpbmcgYSBwYXJ0aXRpb24uCiBiZWdpbjsKIGNyZWF0ZSB0YWJsZSBwYXJ0ZWRfcmVwbGljYV90 YWIgKGlkIGludCBub3QgbnVsbCkgcGFydGl0aW9uIGJ5IHJhbmdlIChpZCk7CmRpZmYgLS1naXQg YS9zcmMvdGVzdC9yZWdyZXNzL3NxbC9pbmRleGluZy5zcWwgYi9zcmMvdGVzdC9yZWdyZXNzL3Nx bC9pbmRleGluZy5zcWwKaW5kZXggMTI5MTMwZDA0ZDQuLjM4NjAyZGIxZTIyIDEwMDY0NAotLS0g YS9zcmMvdGVzdC9yZWdyZXNzL3NxbC9pbmRleGluZy5zcWwKKysrIGIvc3JjL3Rlc3QvcmVncmVz cy9zcWwvaW5kZXhpbmcuc3FsCkBAIC04NzYsNiArODc2LDEzMCBAQCBzZWxlY3QgaW5kZXhyZWxp ZDo6cmVnY2xhc3MsIGluZGlzdmFsaWQsCiAgIG9yZGVyIGJ5IGluZGV4cmVsaWQ6OnJlZ2NsYXNz Ojp0ZXh0IGNvbGxhdGUgIkMiOwogZHJvcCB0YWJsZSBwYXJ0ZWRfaXN2YWxpZF90YWI7CiAKKy0t IENoZWNrIHRoYXQgUkVJTkRFWCBvZiBhbiBpbnZhbGlkIHBhcnRpdGlvbiBpbmRleCB2YWxpZGF0 ZXMgdGhlIHBhcmVudAorLS0gcGFydGl0aW9uZWQgaW5kZXggKGFuZCByZWN1cnNlcyB1cHdhcmQg dGhyb3VnaCBtdWx0aS1sZXZlbCBoaWVyYXJjaGllcykuCisKKy0tIFRlc3Q6IGJhc2ljIFJFSU5E RVggSU5ERVggcmVwYWlycyBpbnZhbGlkIGNoaWxkIGFuZCB2YWxpZGF0ZXMgcGFyZW50LgorY3Jl YXRlIHRhYmxlIHJlaW5kZXhfcHYgKGEgaW50LCBiIGludCkgcGFydGl0aW9uIGJ5IHJhbmdlIChh KTsKK2NyZWF0ZSB0YWJsZSByZWluZGV4X3B2XzEgcGFydGl0aW9uIG9mIHJlaW5kZXhfcHYgZm9y IHZhbHVlcyBmcm9tICgxKSB0byAoMTApOworLS0gQ3JlYXRlIGFuIGludmFsaWQgaW5kZXggb24g dGhlIHBhcnRpdGlvbiB2aWEgYSBmYWlsZWQgY29uY3VycmVudCBidWlsZC4KK2luc2VydCBpbnRv IHJlaW5kZXhfcHZfMSB2YWx1ZXMgKDEsIDApOworY3JlYXRlIGluZGV4IGNvbmN1cnJlbnRseSBy ZWluZGV4X3B2XzFfaWR4IG9uIHJlaW5kZXhfcHZfMSAoKGEgLyBiKSk7CistLSBDcmVhdGUgdGhl IHBhcnRpdGlvbmVkIGluZGV4OyBpdCBwaWNrcyB1cCB0aGUgaW52YWxpZCBjaGlsZCwgc28gYm90 aAorLS0gcGFyZW50IGFuZCBjaGlsZCBhcmUgaW52YWxpZC4KK2NyZWF0ZSBpbmRleCByZWluZGV4 X3B2X2lkeCBvbiByZWluZGV4X3B2ICgoYSAvIGIpKTsKK3NlbGVjdCBpbmRleHJlbGlkOjpyZWdj bGFzcywgaW5kaXN2YWxpZAorICBmcm9tIHBnX2luZGV4IHdoZXJlIGluZGV4cmVsaWQ6OnJlZ2Ns YXNzOjp0ZXh0IGxpa2UgJ3JlaW5kZXhfcHYlJworICBvcmRlciBieSBpbmRleHJlbGlkOjpyZWdj bGFzczo6dGV4dCBjb2xsYXRlICJDIjsKKy0tIEZpeCB0aGUgZGF0YSBhbmQgUkVJTkRFWCB0aGUg Y2hpbGQuICBVc2UgVFJVTkNBVEUgKG5vdCBERUxFVEUpIHNvIHRoYXQKKy0tIGRlYWQgdHVwbGVz IHdpdGggdGhlIGVycm9yLWNhdXNpbmcgZXhwcmVzc2lvbiBhcmUgcGh5c2ljYWxseSByZW1vdmVk OworLS0gUkVJTkRFWCBldmFsdWF0ZXMgZXhwcmVzc2lvbnMgb24gYWxsIGhlYXAgdHVwbGVzIGlu Y2x1ZGluZyByZWNlbnRseS1kZWFkCistLSBvbmVzLCBhbmQgY29uY3VycmVudCB0ZXN0IHNlc3Np b25zIGNhbiBwcmV2ZW50IFZBQ1VVTSBmcm9tIGNsZWFuaW5nIHRoZW0uCit0cnVuY2F0ZSByZWlu ZGV4X3B2XzE7CityZWluZGV4IGluZGV4IHJlaW5kZXhfcHZfMV9pZHg7CistLSBCb3RoIGNoaWxk IGFuZCBwYXJlbnQgc2hvdWxkIG5vdyBiZSB2YWxpZC4KK3NlbGVjdCBpbmRleHJlbGlkOjpyZWdj bGFzcywgaW5kaXN2YWxpZAorICBmcm9tIHBnX2luZGV4IHdoZXJlIGluZGV4cmVsaWQ6OnJlZ2Ns YXNzOjp0ZXh0IGxpa2UgJ3JlaW5kZXhfcHYlJworICBvcmRlciBieSBpbmRleHJlbGlkOjpyZWdj bGFzczo6dGV4dCBjb2xsYXRlICJDIjsKK2Ryb3AgdGFibGUgcmVpbmRleF9wdjsKKworLS0gVGVz dDogbmVnYXRpdmUgY2FzZSDigJQgcGFyZW50IHN0YXlzIGludmFsaWQgd2hpbGUgYW55IGNoaWxk IHJlbWFpbnMgaW52YWxpZC4KK2NyZWF0ZSB0YWJsZSByZWluZGV4X3B2MiAoYSBpbnQsIGIgaW50 KSBwYXJ0aXRpb24gYnkgcmFuZ2UgKGEpOworY3JlYXRlIHRhYmxlIHJlaW5kZXhfcHYyXzEgcGFy dGl0aW9uIG9mIHJlaW5kZXhfcHYyIGZvciB2YWx1ZXMgZnJvbSAoMSkgdG8gKDEwKTsKK2NyZWF0 ZSB0YWJsZSByZWluZGV4X3B2Ml8yIHBhcnRpdGlvbiBvZiByZWluZGV4X3B2MiBmb3IgdmFsdWVz IGZyb20gKDEwKSB0byAoMjApOworLS0gQ3JlYXRlIGludmFsaWQgaW5kZXhlcyBvbiBib3RoIGNo aWxkcmVuLgoraW5zZXJ0IGludG8gcmVpbmRleF9wdjJfMSB2YWx1ZXMgKDEsIDApOworY3JlYXRl IGluZGV4IGNvbmN1cnJlbnRseSByZWluZGV4X3B2Ml8xX2lkeCBvbiByZWluZGV4X3B2Ml8xICgo YSAvIGIpKTsKK2luc2VydCBpbnRvIHJlaW5kZXhfcHYyXzIgdmFsdWVzICgxMCwgMCk7CitjcmVh dGUgaW5kZXggY29uY3VycmVudGx5IHJlaW5kZXhfcHYyXzJfaWR4IG9uIHJlaW5kZXhfcHYyXzIg KChhIC8gYikpOworLS0gUGFyZW50IHBpY2tzIHVwIGJvdGggaW52YWxpZCBjaGlsZHJlbi4KK2Ny ZWF0ZSBpbmRleCByZWluZGV4X3B2Ml9pZHggb24gcmVpbmRleF9wdjIgKChhIC8gYikpOworLS0g Rml4IG9ubHkgY2hpbGQgMSBhbmQgcmVpbmRleCBpdC4KK3RydW5jYXRlIHJlaW5kZXhfcHYyXzE7 CityZWluZGV4IGluZGV4IHJlaW5kZXhfcHYyXzFfaWR4OworLS0gUGFyZW50IG11c3QgcmVtYWlu IGludmFsaWQgYmVjYXVzZSBjaGlsZCAyIGlzIHN0aWxsIGludmFsaWQuCitzZWxlY3QgaW5kZXhy ZWxpZDo6cmVnY2xhc3MsIGluZGlzdmFsaWQKKyAgZnJvbSBwZ19pbmRleCB3aGVyZSBpbmRleHJl bGlkOjpyZWdjbGFzczo6dGV4dCBsaWtlICdyZWluZGV4X3B2MiUnCisgIG9yZGVyIGJ5IGluZGV4 cmVsaWQ6OnJlZ2NsYXNzOjp0ZXh0IGNvbGxhdGUgIkMiOworLS0gTm93IGZpeCBjaGlsZCAyIGFz IHdlbGwuCit0cnVuY2F0ZSByZWluZGV4X3B2Ml8yOworcmVpbmRleCBpbmRleCByZWluZGV4X3B2 Ml8yX2lkeDsKKy0tIE5vdyB0aGUgcGFyZW50IHNob3VsZCBiZSB2YWxpZC4KK3NlbGVjdCBpbmRl eHJlbGlkOjpyZWdjbGFzcywgaW5kaXN2YWxpZAorICBmcm9tIHBnX2luZGV4IHdoZXJlIGluZGV4 cmVsaWQ6OnJlZ2NsYXNzOjp0ZXh0IGxpa2UgJ3JlaW5kZXhfcHYyJScKKyAgb3JkZXIgYnkgaW5k ZXhyZWxpZDo6cmVnY2xhc3M6OnRleHQgY29sbGF0ZSAiQyI7Citkcm9wIHRhYmxlIHJlaW5kZXhf cHYyOworCistLSBUZXN0OiBtdWx0aS1sZXZlbCBoaWVyYXJjaHkg4oCUIHZhbGlkaXR5IHByb3Bh Z2F0ZXMgdXB3YXJkIHRocm91Z2ggYWxsIGxldmVscy4KK2NyZWF0ZSB0YWJsZSByZWluZGV4X3B2 MyAoYSBpbnQsIGIgaW50KSBwYXJ0aXRpb24gYnkgcmFuZ2UgKGEpOworY3JlYXRlIHRhYmxlIHJl aW5kZXhfcHYzX21pZCBwYXJ0aXRpb24gb2YgcmVpbmRleF9wdjMKKyAgZm9yIHZhbHVlcyBmcm9t ICgxKSB0byAoMjApIHBhcnRpdGlvbiBieSByYW5nZSAoYSk7CitjcmVhdGUgdGFibGUgcmVpbmRl eF9wdjNfbWlkXzEgcGFydGl0aW9uIG9mIHJlaW5kZXhfcHYzX21pZAorICBmb3IgdmFsdWVzIGZy b20gKDEpIHRvICgxMCk7CitjcmVhdGUgdGFibGUgcmVpbmRleF9wdjNfbWlkXzIgcGFydGl0aW9u IG9mIHJlaW5kZXhfcHYzX21pZAorICBmb3IgdmFsdWVzIGZyb20gKDEwKSB0byAoMjApOworY3Jl YXRlIHRhYmxlIHJlaW5kZXhfcHYzX290aGVyIHBhcnRpdGlvbiBvZiByZWluZGV4X3B2MworICBm b3IgdmFsdWVzIGZyb20gKDIwKSB0byAoMzApOworLS0gQ3JlYXRlIGFuIGludmFsaWQgaW5kZXgg b25seSBvbiBvbmUgbGVhZi4KK2luc2VydCBpbnRvIHJlaW5kZXhfcHYzX21pZF8xIHZhbHVlcyAo MSwgMCk7CitjcmVhdGUgaW5kZXggY29uY3VycmVudGx5IHJlaW5kZXhfcHYzX21pZF8xX2lkeCBv biByZWluZGV4X3B2M19taWRfMSAoKGEgLyBiKSk7CistLSBDcmVhdGUgdGhlIHRvcC1sZXZlbCBw YXJ0aXRpb25lZCBpbmRleC4gIFRoZSBpbnZhbGlkIGxlYWYgbWFrZXMgdGhlCistLSBpbnRlcm1l ZGlhdGUgYW5kIHJvb3QgaW5kZXhlcyBpbnZhbGlkIGFzIHdlbGwuCitjcmVhdGUgaW5kZXggcmVp bmRleF9wdjNfaWR4IG9uIHJlaW5kZXhfcHYzICgoYSAvIGIpKTsKK3NlbGVjdCBpbmRleHJlbGlk OjpyZWdjbGFzcywgaW5kaXN2YWxpZCwKKyAgICAgICBpbmRyZWxpZDo6cmVnY2xhc3MsIGluaHBh cmVudDo6cmVnY2xhc3MKKyAgZnJvbSBwZ19pbmRleCBpZHggbGVmdCBqb2luCisgICAgICAgcGdf aW5oZXJpdHMgaW5oIG9uIChpZHguaW5kZXhyZWxpZCA9IGluaC5pbmhyZWxpZCkKKyAgd2hlcmUg aW5kZXhyZWxpZDo6cmVnY2xhc3M6OnRleHQgbGlrZSAncmVpbmRleF9wdjMlJworICBvcmRlciBi eSBpbmRleHJlbGlkOjpyZWdjbGFzczo6dGV4dCBjb2xsYXRlICJDIjsKKy0tIEZpeCBhbmQgcmVp bmRleCB0aGUgbGVhZi4KK3RydW5jYXRlIHJlaW5kZXhfcHYzX21pZF8xOworcmVpbmRleCBpbmRl eCByZWluZGV4X3B2M19taWRfMV9pZHg7CistLSBBbGwgbGV2ZWxzIHNob3VsZCBub3cgYmUgdmFs aWQgKGNhc2NhZGluZyB1cHdhcmQpLgorc2VsZWN0IGluZGV4cmVsaWQ6OnJlZ2NsYXNzLCBpbmRp c3ZhbGlkLAorICAgICAgIGluZHJlbGlkOjpyZWdjbGFzcywgaW5ocGFyZW50OjpyZWdjbGFzcwor ICBmcm9tIHBnX2luZGV4IGlkeCBsZWZ0IGpvaW4KKyAgICAgICBwZ19pbmhlcml0cyBpbmggb24g KGlkeC5pbmRleHJlbGlkID0gaW5oLmluaHJlbGlkKQorICB3aGVyZSBpbmRleHJlbGlkOjpyZWdj bGFzczo6dGV4dCBsaWtlICdyZWluZGV4X3B2MyUnCisgIG9yZGVyIGJ5IGluZGV4cmVsaWQ6OnJl Z2NsYXNzOjp0ZXh0IGNvbGxhdGUgIkMiOworZHJvcCB0YWJsZSByZWluZGV4X3B2MzsKKworLS0g VGVzdDogUkVJTkRFWCBUQUJMRSBvbiBhIHBhcnRpdGlvbiBhbHNvIHZhbGlkYXRlcyB0aGUgcGFy ZW50LgorY3JlYXRlIHRhYmxlIHJlaW5kZXhfcHY0IChhIGludCwgYiBpbnQpIHBhcnRpdGlvbiBi eSByYW5nZSAoYSk7CitjcmVhdGUgdGFibGUgcmVpbmRleF9wdjRfMSBwYXJ0aXRpb24gb2YgcmVp bmRleF9wdjQgZm9yIHZhbHVlcyBmcm9tICgxKSB0byAoMTApOworaW5zZXJ0IGludG8gcmVpbmRl eF9wdjRfMSB2YWx1ZXMgKDEsIDApOworY3JlYXRlIGluZGV4IGNvbmN1cnJlbnRseSByZWluZGV4 X3B2NF8xX2lkeCBvbiByZWluZGV4X3B2NF8xICgoYSAvIGIpKTsKK2NyZWF0ZSBpbmRleCByZWlu ZGV4X3B2NF9pZHggb24gcmVpbmRleF9wdjQgKChhIC8gYikpOworLS0gQWxzbyBhZGQgYSByZWd1 bGFyIGluZGV4IGZvciBSRUlOREVYIFRBQkxFIHRvIHByb2Nlc3MuCitjcmVhdGUgaW5kZXggcmVp bmRleF9wdjRfYV9pZHggb24gcmVpbmRleF9wdjQgKGEpOworc2VsZWN0IGluZGV4cmVsaWQ6OnJl Z2NsYXNzLCBpbmRpc3ZhbGlkCisgIGZyb20gcGdfaW5kZXggd2hlcmUgaW5kZXhyZWxpZDo6cmVn Y2xhc3M6OnRleHQgbGlrZSAncmVpbmRleF9wdjQlJworICBvcmRlciBieSBpbmRleHJlbGlkOjpy ZWdjbGFzczo6dGV4dCBjb2xsYXRlICJDIjsKK3RydW5jYXRlIHJlaW5kZXhfcHY0XzE7CityZWlu ZGV4IHRhYmxlIHJlaW5kZXhfcHY0XzE7CistLSBCb3RoIHRoZSBleHByZXNzaW9uIGluZGV4IGFu ZCBwYXJlbnQgc2hvdWxkIGJlIHZhbGlkIG5vdy4KK3NlbGVjdCBpbmRleHJlbGlkOjpyZWdjbGFz cywgaW5kaXN2YWxpZAorICBmcm9tIHBnX2luZGV4IHdoZXJlIGluZGV4cmVsaWQ6OnJlZ2NsYXNz Ojp0ZXh0IGxpa2UgJ3JlaW5kZXhfcHY0JScKKyAgb3JkZXIgYnkgaW5kZXhyZWxpZDo6cmVnY2xh c3M6OnRleHQgY29sbGF0ZSAiQyI7Citkcm9wIHRhYmxlIHJlaW5kZXhfcHY0OworCistLSBUZXN0 OiBSRUlOREVYIElOREVYIENPTkNVUlJFTlRMWSBhbHNvIHZhbGlkYXRlcyB0aGUgcGFyZW50Lgor Y3JlYXRlIHRhYmxlIHJlaW5kZXhfcHY1IChhIGludCwgYiBpbnQpIHBhcnRpdGlvbiBieSByYW5n ZSAoYSk7CitjcmVhdGUgdGFibGUgcmVpbmRleF9wdjVfMSBwYXJ0aXRpb24gb2YgcmVpbmRleF9w djUgZm9yIHZhbHVlcyBmcm9tICgxKSB0byAoMTApOworaW5zZXJ0IGludG8gcmVpbmRleF9wdjVf MSB2YWx1ZXMgKDEsIDApOworY3JlYXRlIGluZGV4IGNvbmN1cnJlbnRseSByZWluZGV4X3B2NV8x X2lkeCBvbiByZWluZGV4X3B2NV8xICgoYSAvIGIpKTsKK2NyZWF0ZSBpbmRleCByZWluZGV4X3B2 NV9pZHggb24gcmVpbmRleF9wdjUgKChhIC8gYikpOworc2VsZWN0IGluZGV4cmVsaWQ6OnJlZ2Ns YXNzLCBpbmRpc3ZhbGlkCisgIGZyb20gcGdfaW5kZXggd2hlcmUgaW5kZXhyZWxpZDo6cmVnY2xh c3M6OnRleHQgbGlrZSAncmVpbmRleF9wdjUlJworICBvcmRlciBieSBpbmRleHJlbGlkOjpyZWdj bGFzczo6dGV4dCBjb2xsYXRlICJDIjsKK3RydW5jYXRlIHJlaW5kZXhfcHY1XzE7CityZWluZGV4 IGluZGV4IGNvbmN1cnJlbnRseSByZWluZGV4X3B2NV8xX2lkeDsKKy0tIEJvdGggc2hvdWxkIGJl IHZhbGlkLgorc2VsZWN0IGluZGV4cmVsaWQ6OnJlZ2NsYXNzLCBpbmRpc3ZhbGlkCisgIGZyb20g cGdfaW5kZXggd2hlcmUgaW5kZXhyZWxpZDo6cmVnY2xhc3M6OnRleHQgbGlrZSAncmVpbmRleF9w djUlJworICBvcmRlciBieSBpbmRleHJlbGlkOjpyZWdjbGFzczo6dGV4dCBjb2xsYXRlICJDIjsK K2Ryb3AgdGFibGUgcmVpbmRleF9wdjU7CisKIC0tIENoZWNrIHN0YXRlIG9mIHJlcGxpY2EgaW5k ZXhlcyB3aGVuIGF0dGFjaGluZyBhIHBhcnRpdGlvbi4KIGJlZ2luOwogY3JlYXRlIHRhYmxlIHBh cnRlZF9yZXBsaWNhX3RhYiAoaWQgaW50IG5vdCBudWxsKSBwYXJ0aXRpb24gYnkgcmFuZ2UgKGlk KTsKLS0gCjIuNTIuMAoK --000000000000eb0bee064f25dc1a--