Re: Proposal: knowing detail of config files via SQL

From: Sawada Masahiko <sawada(dot)mshk(at)gmail(dot)com>
To: Stephen Frost <sfrost(at)snowman(dot)net>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, David Johnston <david(dot)g(dot)johnston(at)gmail(dot)com>, David Fetter <david(at)fetter(dot)org>, Robert Haas <robertmhaas(at)gmail(dot)com>, "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Proposal: knowing detail of config files via SQL
Date: 2015-03-05 16:37:15
Message-ID: CAD21AoAYLYsn0FUE-_LRQF2K0c66V8UhGou0xjfrdYFQgmvf_w@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Sat, Feb 28, 2015 at 2:27 PM, Stephen Frost <sfrost(at)snowman(dot)net> wrote:
> Sawada,
>
> * Sawada Masahiko (sawada(dot)mshk(at)gmail(dot)com) wrote:
>> Attached patch is latest version including following changes.
>> - This view is available to super use only
>> - Add sourceline coulmn
>
> Alright, first off, to Josh's point- I'm definitely interested in a
> capability to show where the heck a given config value is coming from.
> I'd be even happier if there was a way to *force* where config values
> have to come from, but that ship sailed a year ago or so. Having this
> be for the files, specifically, seems perfectly reasonable to me. I
> could see having another function which will report where a currently
> set GUC variable came from (eg: ALTER ROLE or ALTER DATABASE), but
> having a function for "which config file is this GUC set in" seems
> perfectly reasonable to me.
>
> To that point, here's a review of this patch.
>
>> diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
>> index 6df6bf2..f628cb0 100644
>> --- a/src/backend/catalog/system_views.sql
>> +++ b/src/backend/catalog/system_views.sql
>> @@ -412,6 +412,11 @@ CREATE RULE pg_settings_n AS
>>
>> GRANT SELECT, UPDATE ON pg_settings TO PUBLIC;
>>
>> +CREATE VIEW pg_file_settings AS
>> + SELECT * FROM pg_show_all_file_settings() AS A;
>> +
>> +REVOKE ALL on pg_file_settings FROM public;
>
> While this generally "works", the usual expectation is that functions
> that should be superuser-only have a check in the function rather than
> depending on the execute privilege. I'm certainly happy to debate the
> merits of that approach, but for the purposes of this patch, I'd suggest
> you stick an if (!superuser()) ereport("must be superuser") into the
> function itself and not work about setting the correct permissions on
> it.
>
>> + ConfigFileVariable *guc;
>
> As this ends up being an array, I'd call it "guc_array" or something
> along those lines. GUC in PG-land has a pretty specific single-entity
> meaning.
>
>> @@ -344,6 +346,21 @@ ProcessConfigFile(GucContext context)
>> PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT);
>> }
>>
>> + guc_file_variables = (ConfigFileVariable *)
>> + guc_malloc(FATAL, num_guc_file_variables * sizeof(struct ConfigFileVariable));
>
> Uh, perhaps I missed it, but what happens on a reload? Aren't we going
> to realloc this every time? Seems like we should be doing a
> guc_malloc() the first time through but doing guc_realloc() after, or
> we'll leak memory on every reload.
>
>> + /*
>> + * Apply guc config parameters to guc_file_variable
>> + */
>> + guc = guc_file_variables;
>> + for (item = head; item; item = item->next, guc++)
>> + {
>> + guc->name = guc_strdup(FATAL, item->name);
>> + guc->value = guc_strdup(FATAL, item->value);
>> + guc->filename = guc_strdup(FATAL, item->filename);
>> + guc->sourceline = item->sourceline;
>> + }
>
> Uh, ditto and double-down here. I don't see a great solution other than
> looping through the previous array and free'ing each of these, since we
> can't depend on the memory context machinery being up and ready at this
> point, as I recall.
>
>> diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
>> index 931993c..c69ce66 100644
>> --- a/src/backend/utils/misc/guc.c
>> +++ b/src/backend/utils/misc/guc.c
>> @@ -3561,9 +3561,17 @@ static const char *const map_old_guc_names[] = {
>> */
>> static struct config_generic **guc_variables;
>>
>> +/*
>> + * lookup of variables for pg_file_settings view.
>> + */
>> +static struct ConfigFileVariable *guc_file_variables;
>> +
>> /* Current number of variables contained in the vector */
>> static int num_guc_variables;
>>
>> +/* Number of file variables */
>> +static int num_guc_file_variables;
>> +
>
> I'd put these together, and add a comment explaining that
> guc_file_variables is an array of length num_guc_file_variables..
>
>> /*
>> + * Return the total number of GUC File variables
>> + */
>> +int
>> +GetNumConfigFileOptions(void)
>> +{
>> + return num_guc_file_variables;
>> +}
>
> I don't see the point of this function..
>
>> +Datum
>> +show_all_file_settings(PG_FUNCTION_ARGS)
>> +{
>> + FuncCallContext *funcctx;
>> + TupleDesc tupdesc;
>> + int call_cntr;
>> + int max_calls;
>> + AttInMetadata *attinmeta;
>> + MemoryContext oldcontext;
>> +
>> + if (SRF_IS_FIRSTCALL())
>> + {
>> + funcctx = SRF_FIRSTCALL_INIT();
>> +
>> + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
>> +
>> + /*
>> + * need a tuple descriptor representing NUM_PG_SETTINGS_ATTS columns
>> + * of the appropriate types
>> + */
>> +
>> + tupdesc = CreateTemplateTupleDesc(NUM_PG_FILE_SETTINGS_ATTS, false);
>> + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
>> + TEXTOID, -1, 0);
>> + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
>> + TEXTOID, -1, 0);
>> + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "sourcefile",
>> + TEXTOID, -1, 0);
>> + TupleDescInitEntry(tupdesc, (AttrNumber) 4, "sourceline",
>> + INT4OID, -1, 0);
>
> As the sourcefile and sourceline were discussed as being the 'key' for
> this, I expected them to be the first columns.. Any reason to not do
> that? It's certainly look cleaner, at least to me, that way.
>
>> + if (call_cntr < max_calls)
>> + {
>> + char *values[NUM_PG_FILE_SETTINGS_ATTS];
>> + HeapTuple tuple;
>> + Datum result;
>> + ConfigFileVariable conf;
>> + char buffer[256];
>> +
>> + conf = guc_file_variables[call_cntr];
>
> I'm a bit nervous that a sighup in the middle could screw this up. Have
> you considered that? At a minimum, I'd suggest a check along the lines
> of:
>
> if (call_cntr > num_guc_file_variables)
> SRF_RETURNDONE();
>
> To try and avoid going past the end of the array.
>
>> + values[0] = conf.name;
>> + values[1] = conf.value;
>> + values[2] = conf.filename;
>> + snprintf(buffer, sizeof(buffer), "%d", conf.sourceline);
>
> Seems like we might be able to use pg_ltoa() there..
>
>> + if (call_cntr >= max_calls)
>> + SRF_RETURN_DONE(funcctx);
>
> Isn't this redundant? We wouldn't be here if this was true.
>
> Just a quick review.
>

Thank you for your review!
Attached file is the latest version (without document patch. I making it now.)
As per discussion, there is no change regarding of super user permission.

--
Regards,

-------
Sawada Masahiko

Attachment Content-Type Size
000_pg_file_settings_view_v3.patch application/octet-stream 8.3 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Stephen Frost 2015-03-05 16:39:55 Re: Proposal: knowing detail of config files via SQL
Previous Message Stephen Frost 2015-03-05 16:36:41 Re: MD5 authentication needs help