Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cshiJ-0007Nd-Ns for pgsql-hackers@arkaria.postgresql.org; Tue, 28 Mar 2017 03:22:31 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1cshiI-0005lo-Lf for pgsql-hackers@arkaria.postgresql.org; Tue, 28 Mar 2017 03:22:30 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1cshgm-00037f-Hk for pgsql-hackers@postgresql.org; Tue, 28 Mar 2017 03:20:56 +0000 Received: from mail-wr0-x22b.google.com ([2a00:1450:400c:c0c::22b]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.84_2) (envelope-from ) id 1cshge-00041E-JW for pgsql-hackers@postgresql.org; Tue, 28 Mar 2017 03:20:55 +0000 Received: by mail-wr0-x22b.google.com with SMTP id u1so83868411wra.2 for ; Mon, 27 Mar 2017 20:20:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to; bh=VGjv7INRD6BM0mVnfsDWgWW1maSgEhq4CE2nLzYB17M=; b=CZw7i7BOyROy00TkJ1uTVrKp1FL6wpEJRZ2DOn02yy1WjjQGuKYPJbiDRsM18P2qVS g1OkNbNhubeqaPNeKSfejZDhaTZDbcUttCieZ56T+8lWJ4jVHPX0TvW4MBrGqEe8YY/y mqqY8wlRMN1Csjry8gbSua0PMDXAXFDAvyJ0VO+ocIhmK/RBS6eA8xmT/AqWBzYMaEoT yunnW//o0vDFVPCxSYaiBVp1gxnha04ONb7QcyK41UD8y+HbgrHT2DXQK8bQzTdx0Ub7 XHswMNeWdm/d1oG3W6GApQAFJE2ohFcVdFBVOZL/5sKoiC0rpEm9wsD/GSLP94wW7Ijl HSlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to; bh=VGjv7INRD6BM0mVnfsDWgWW1maSgEhq4CE2nLzYB17M=; b=sX2P64ylsLq3/Zd9ZkId2JZ/rc54x9Kv+ErmrNwh/9B85BvpFm5aCame7JYzgMXj2u N775haz0ho7DdL8uNvJoNu0bTPLlHb1ICxFYuDePK3oUcbWTKcZrfBTi+3r1Sd2VDQbw EU5Y7a2MBeTgJ9cTcA6RIxF97cfP7At3cSDNHSy/zus93uKXzhtA6sH244puf/wIbAq7 13VkKsCKHTDP0jMNElweC2hkiFnA32fRGWIKpxeEzVLTzYTU6atSFaV0qND+0N0muVFB CijOTwv+R2z8KLQ+/HlFB1nqM3Yr7DQUK31XtUmLAgH+GDnXGoX9dvlbwrY3GtEB6wlJ uCZQ== X-Gm-Message-State: AFeK/H1ADES3HHb66ZVT4z55YrznDQ956UGqAwpfS7cETjInHqQ2YscAHcMTz2O6UD1GhWN6 X-Received: by 10.28.29.138 with SMTP id d132mr11822210wmd.40.1490671246595; Mon, 27 Mar 2017 20:20:46 -0700 (PDT) Received: from [192.168.0.105] (150.123.broadband11.iol.cz. [90.178.123.150]) by smtp.gmail.com with ESMTPSA id t30sm2947001wra.55.2017.03.27.20.20.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Mar 2017 20:20:45 -0700 (PDT) Subject: Re: logical replication launcher crash on buildfarm To: Robert Haas , Andres Freund References: <20170316032833.2zxfnqe3sl3ktrbt@alap3.anarazel.de> <20170316034246.3uurliezczmka6cn@alap3.anarazel.de> <20170316085322.crffknkgee5s6air@alap3.anarazel.de> <368e64f6-ee9a-f09f-82b4-a33b61b28d36@2ndquadrant.com> <20170327165023.t224nralrspk6udc@alap3.anarazel.de> <52d78669-0523-4e60-a263-841c96210256@2ndquadrant.com> <8941c9b1-f6e9-1056-39f2-7bc7336c4d00@2ndquadrant.com> <20170328020422.i4srzzgq4zbzu2ci@alap3.anarazel.de> Cc: "pgsql-hackers@postgresql.org" , Petr Jelinek , Peter Eisentraut From: Petr Jelinek Message-ID: Date: Tue, 28 Mar 2017 05:20:44 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/mixed; boundary="------------B9262B1C47B9ACB2C5A1A658" X-Pg-Spam-Score: -1.9 (-) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-hackers Precedence: bulk Sender: pgsql-hackers-owner@postgresql.org This is a multi-part message in MIME format. --------------B9262B1C47B9ACB2C5A1A658 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit On 28/03/17 04:46, Robert Haas wrote: > On Mon, Mar 27, 2017 at 10:04 PM, Andres Freund wrote: >>> Btw now that I look at the code, I guess we'll want to get rid of >>> bgw_main completely in HEAD given that we can't guarantee it will be >>> valid even for shared_preload_library libraries. For older branches I >>> would leave things as they are in this regard as there don't seem to be >>> any immediate issue for standard binaries. >> >> As long as you fix it so culicidae is happy (in 9.6) ;). I think it's >> fine to just introduce bgw_builtin_id or such, and leave the bgw_main >> code in place in < HEAD. > > I wasn't thinking of introducing bgw_builtin_id. My idea was just > along the lines of > > if (bgw_library_name == NULL && bgw_function_name != NULL) > { > if (strcmp(bgw_function_name, "ParallelQueryMain") == 0) > ParallelQueryMain(blah); > else if (strcmp(bgw_function_name, "LogicalReplicationMain") == 0) > LogicalReplicationMain(blah); > } > > I think something like that is certainly better for the back-branches, > because it doesn't cause an ABI break. But I think it would also be > fine for master. > I had something slightly more complex like the attached in mind. -- Petr Jelinek http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services --------------B9262B1C47B9ACB2C5A1A658 Content-Type: binary/octet-stream; name="0001-Remove-bgw_main-from-bgworker-and-always-use-library.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-Remove-bgw_main-from-bgworker-and-always-use-library.pa"; filename*1="tch" From d548ff5467a6880122b5807add3d3c1febd8022e Mon Sep 17 00:00:00 2001 From: Petr Jelinek Date: Tue, 28 Mar 2017 04:21:46 +0200 Subject: [PATCH] Remove bgw_main from bgworker and always use library/function for loading main entry point --- src/backend/access/transam/parallel.c | 6 +-- src/backend/postmaster/bgworker.c | 81 +++++++++++++++++++----------- src/backend/replication/logical/launcher.c | 6 ++- src/include/access/parallel.h | 2 + src/include/postmaster/bgworker.h | 1 - src/test/modules/test_shm_mq/setup.c | 1 - src/test/modules/worker_spi/worker_spi.c | 4 +- 7 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index 3e0ee87..b3d3853 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -110,7 +110,6 @@ static dlist_head pcxt_list = DLIST_STATIC_INIT(pcxt_list); /* Private functions. */ static void HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg); static void ParallelExtensionTrampoline(dsm_segment *seg, shm_toc *toc); -static void ParallelWorkerMain(Datum main_arg); static void WaitForParallelWorkersToExit(ParallelContext *pcxt); @@ -458,7 +457,8 @@ LaunchParallelWorkers(ParallelContext *pcxt) | BGWORKER_CLASS_PARALLEL; worker.bgw_start_time = BgWorkerStart_ConsistentState; worker.bgw_restart_time = BGW_NEVER_RESTART; - worker.bgw_main = ParallelWorkerMain; + sprintf(worker.bgw_library_name, "postgres"); + sprintf(worker.bgw_function_name, "ParallelWorkerMain"); worker.bgw_main_arg = UInt32GetDatum(dsm_segment_handle(pcxt->seg)); worker.bgw_notify_pid = MyProcPid; memset(&worker.bgw_extra, 0, BGW_EXTRALEN); @@ -931,7 +931,7 @@ AtEOXact_Parallel(bool isCommit) /* * Main entrypoint for parallel workers. */ -static void +void ParallelWorkerMain(Datum main_arg) { dsm_segment *seg; diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index 10e0f88..39a098c 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -15,12 +15,14 @@ #include #include "libpq/pqsignal.h" +#include "access/parallel.h" #include "miscadmin.h" #include "pgstat.h" #include "port/atomics.h" #include "postmaster/bgworker_internals.h" #include "postmaster/postmaster.h" #include "replication/logicallauncher.h" +#include "replication/logicalworker.h" #include "storage/dsm.h" #include "storage/ipc.h" #include "storage/latch.h" @@ -109,14 +111,26 @@ struct BackgroundWorkerHandle static BackgroundWorkerArray *BackgroundWorkerData; /* - * List of workers that are allowed to be started outside of - * shared_preload_libraries. + * List of internal background workers. These are used for mapping the + * function name to actual function when building with EXEC_BACKEND and also + * to allow these to be loaded outside of shared_preload_libraries. */ -static const bgworker_main_type InternalBGWorkers[] = { - ApplyLauncherMain, - NULL +typedef struct InternalBGWorkerMain +{ + char *bgw_function_name; + bgworker_main_type bgw_main; +} InternalBGWorkerMain; + +static const InternalBGWorkerMain InternalBGWorkers[] = { + {"ParallelWorkerMain", ParallelWorkerMain}, + {"ApplyLauncherMain", ApplyLauncherMain}, + {"ApplyWorkerMain", ApplyWorkerMain}, + /* Dummy entry marking end of the array. */ + {NULL, NULL} }; +static bgworker_main_type GetInternalBgWorkerMain(BackgroundWorker *worker); + /* * Calculate shared memory needed. */ @@ -341,7 +355,6 @@ BackgroundWorkerStateChange(void) rw->rw_worker.bgw_flags = slot->worker.bgw_flags; rw->rw_worker.bgw_start_time = slot->worker.bgw_start_time; rw->rw_worker.bgw_restart_time = slot->worker.bgw_restart_time; - rw->rw_worker.bgw_main = slot->worker.bgw_main; rw->rw_worker.bgw_main_arg = slot->worker.bgw_main_arg; memcpy(rw->rw_worker.bgw_extra, slot->worker.bgw_extra, BGW_EXTRALEN); @@ -763,17 +776,14 @@ StartBackgroundWorker(void) } /* - * If bgw_main is set, we use that value as the initial entrypoint. - * However, if the library containing the entrypoint wasn't loaded at - * postmaster startup time, passing it as a direct function pointer is not - * possible. To work around that, we allow callers for whom a function - * pointer is not available to pass a library name (which will be loaded, - * if necessary) and a function name (which will be looked up in the named - * library). + * For internal workers set the entry point to known function address. + * Otherwise use the entry point specified by library name (which will + * be loaded, if necessary) and a function name (which will be looked up + * in the named library). */ - if (worker->bgw_main != NULL) - entrypt = worker->bgw_main; - else + entrypt = GetInternalBgWorkerMain(worker); + + if (entrypt == NULL) entrypt = (bgworker_main_type) load_external_function(worker->bgw_library_name, worker->bgw_function_name, @@ -806,23 +816,13 @@ RegisterBackgroundWorker(BackgroundWorker *worker) { RegisteredBgWorker *rw; static int numworkers = 0; - bool internal = false; - int i; if (!IsUnderPostmaster) ereport(DEBUG1, (errmsg("registering background worker \"%s\"", worker->bgw_name))); - for (i = 0; InternalBGWorkers[i]; i++) - { - if (worker->bgw_main == InternalBGWorkers[i]) - { - internal = true; - break; - } - } - - if (!process_shared_preload_libraries_in_progress && !internal) + if (!process_shared_preload_libraries_in_progress && + GetInternalBgWorkerMain(worker) == NULL) { if (!IsUnderPostmaster) ereport(LOG, @@ -1152,3 +1152,28 @@ TerminateBackgroundWorker(BackgroundWorkerHandle *handle) if (signal_postmaster) SendPostmasterSignal(PMSIGNAL_BACKGROUND_WORKER_CHANGE); } + +/* + * Search the known internal worker array and return its main function + * pointer if found. + * + * Returns NULL if not known internal worker. + */ +static bgworker_main_type +GetInternalBgWorkerMain(BackgroundWorker *worker) +{ + int i; + + /* Internal workers always have to use postgres as library name. */ + if (strncmp(worker->bgw_library_name, "postgres", 8) != 0) + return NULL; + + for (i = 0; InternalBGWorkers[i].bgw_function_name; i++) + { + if (strncmp(InternalBGWorkers[i].bgw_function_name, + worker->bgw_function_name, BGW_MAXLEN) == 0) + return InternalBGWorkers[i].bgw_main; + } + + return NULL; +} diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c index 0d3ec27..226a168 100644 --- a/src/backend/replication/logical/launcher.c +++ b/src/backend/replication/logical/launcher.c @@ -295,7 +295,8 @@ logicalrep_worker_launch(Oid dbid, Oid subid, const char *subname, Oid userid, bgw.bgw_flags = BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION; bgw.bgw_start_time = BgWorkerStart_RecoveryFinished; - bgw.bgw_main = ApplyWorkerMain; + snprintf(bgw.bgw_library_name, BGW_MAXLEN, "postgres"); + snprintf(bgw.bgw_function_name, BGW_MAXLEN, "ApplyWorkerMain"); if (OidIsValid(relid)) snprintf(bgw.bgw_name, BGW_MAXLEN, "logical replication worker for subscription %u sync %u", subid, relid); @@ -553,7 +554,8 @@ ApplyLauncherRegister(void) bgw.bgw_flags = BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION; bgw.bgw_start_time = BgWorkerStart_RecoveryFinished; - bgw.bgw_main = ApplyLauncherMain; + snprintf(bgw.bgw_library_name, BGW_MAXLEN, "postgres"); + snprintf(bgw.bgw_function_name, BGW_MAXLEN, "ApplyLauncherMain"); snprintf(bgw.bgw_name, BGW_MAXLEN, "logical replication launcher"); bgw.bgw_restart_time = 5; diff --git a/src/include/access/parallel.h b/src/include/access/parallel.h index 96ce480..5065a38 100644 --- a/src/include/access/parallel.h +++ b/src/include/access/parallel.h @@ -67,4 +67,6 @@ extern void AtEOXact_Parallel(bool isCommit); extern void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId); extern void ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end); +extern void ParallelWorkerMain(Datum main_arg); + #endif /* PARALLEL_H */ diff --git a/src/include/postmaster/bgworker.h b/src/include/postmaster/bgworker.h index 128e92c..7cc4c89 100644 --- a/src/include/postmaster/bgworker.h +++ b/src/include/postmaster/bgworker.h @@ -91,7 +91,6 @@ typedef struct BackgroundWorker int bgw_flags; BgWorkerStartTime bgw_start_time; int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */ - bgworker_main_type bgw_main; char bgw_library_name[BGW_MAXLEN]; /* only if bgw_main is NULL */ char bgw_function_name[BGW_MAXLEN]; /* only if bgw_main is NULL */ Datum bgw_main_arg; diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index e3c024e..319a67f 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -216,7 +216,6 @@ setup_background_workers(int nworkers, dsm_segment *seg) worker.bgw_flags = BGWORKER_SHMEM_ACCESS; worker.bgw_start_time = BgWorkerStart_ConsistentState; worker.bgw_restart_time = BGW_NEVER_RESTART; - worker.bgw_main = NULL; /* new worker might not have library loaded */ sprintf(worker.bgw_library_name, "test_shm_mq"); sprintf(worker.bgw_function_name, "test_shm_mq_main"); snprintf(worker.bgw_name, BGW_MAXLEN, "test_shm_mq"); diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c index 72ab846..421ec76 100644 --- a/src/test/modules/worker_spi/worker_spi.c +++ b/src/test/modules/worker_spi/worker_spi.c @@ -347,7 +347,8 @@ _PG_init(void) BGWORKER_BACKEND_DATABASE_CONNECTION; worker.bgw_start_time = BgWorkerStart_RecoveryFinished; worker.bgw_restart_time = BGW_NEVER_RESTART; - worker.bgw_main = worker_spi_main; + sprintf(worker.bgw_library_name, "worker_spi"); + sprintf(worker.bgw_function_name, "worker_spi_main"); worker.bgw_notify_pid = 0; /* @@ -378,7 +379,6 @@ worker_spi_launch(PG_FUNCTION_ARGS) BGWORKER_BACKEND_DATABASE_CONNECTION; worker.bgw_start_time = BgWorkerStart_RecoveryFinished; worker.bgw_restart_time = BGW_NEVER_RESTART; - worker.bgw_main = NULL; /* new worker might not have library loaded */ sprintf(worker.bgw_library_name, "worker_spi"); sprintf(worker.bgw_function_name, "worker_spi_main"); snprintf(worker.bgw_name, BGW_MAXLEN, "worker %d", i); -- 2.7.4 --------------B9262B1C47B9ACB2C5A1A658 Content-Type: text/plain Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers --------------B9262B1C47B9ACB2C5A1A658--