Re: [RFC PATCH 0/1] Enable config.d directory to be processed.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 11/3/20 5:14 AM, Alice Mitchell wrote:
> I know the code doesn't look like very much but it does do exactly what
> I suggest, and i feel is quite a simple and elegant solution that is
> inline with what many of services do.
I'm not saying the include does not work... 
Its just the example you gave does not work.

I mistakenly include the sub conf in the sub conf
which cause an infinite loop... but again that was
a pilot error on my part.

> 
> relative_path() is just as it suggests only for building relative
> paths, whatever comes out of it, either the constructed relative path
> or the untouched absolute one gets handed to glob(3) which builds a
> list of files which match the wildcard pattern given, the for() loop
> around conf_readfile()/conf_parse() loads all of the contents of those
> files into the current transaction as if it was one big config file,
> the wildcard pattern will also do the file extension matching that
> Chuck suggested.
Here is what I'm seeing:
mount -v steved-fedora:/home/tmp /mnt/tmp
conf_readfile: stat(/etc/nfsmount.conf) 0 errno 2
relative_path: newfile '/etc/nfsmount.conf.d/*.conf'
conf_parse_line: relpath '/etc/nfsmount.conf.d/*.conf'
conf_readfile: stat(/etc/nfsmount.conf.d/*.conf) -1 errno 2 
conf_parse_line: subconf '(null)'
^^^^ this NULL stop the processing so the vers=4 mount option 
is never processed in the sub config file. 

> 
> Looking around many other services handle config directories in the
> same way, not all admittedly, but things like apache always handled
> their config this way and at Vincents suggestion I checked and this is
> also how autofs handles it, a directive in the main config file that
> loads a subdirectory.
> 
> /etc/auto.master :
> # Include /etc/auto.master.d/*.autofs
> # The included files must conform to the format of this file.
> #
> +dir:/etc/auto.master.d
Question I have is... Do all the files under /etc/auto.master.d
get processed?

> 
> So the patch i included adds comparable functionality to all of the NFS
> tools, you simply add the include line to the master config files that
> require directory configs as well.
Well not all of the tools... As said before, I pattern my patch
after what exportfs does with /etc/export.d. 

steved.
> 
> -Alice
> 
> 
> 
> On Mon, 2020-11-02 at 14:42 -0500, Steve Dickson wrote:
>> Hello,
>>
>> On 11/2/20 10:57 AM, Alice Mitchell wrote:
>>> On Mon, 2020-11-02 at 09:23 -0500, Steve Dickson wrote:
>>>> Hello,
>>>>
>>>> On 11/2/20 8:24 AM, Steve Dickson wrote:
>>>>>> You would need to write an equivalent of conf_load_file()
>>>>>> that
>>>>>> created a new transaction id and read in all the files before
>>>>>> committing them to do it this way.
>>>
>>> How about the following as an alternative...
>>>
>>> It changes none of the past behaviour, but if you wanted to add an
>>> optional directory structure to a config file then simply add this
>>> to
>>> the default single config file that we ship.
>>>
>>> /etc/nfsmount.conf:
>>> [NFSMount_Global_Options]
>>> include=-/etc/nfsmount.conf.d/*.conf
>> If it was this simple I would go for it... 
>> but it just not work... as expected. Here is why.
>>
>> In relative_path() looks at the new file 
>> (/etc/nfsmount.conf.d/*.conf). If the path starts
>> with '/',  the path is strdup-ed and returned.
>>
>> The '*' is never expanded. Even if it was... there
>> no code (that I see) that will process multiple
>> files.   TBL... This works 
>> include=-/etc/nfsmount.conf.d/nfsmount.conf
>>
>> This doesn't 
>> include=-/etc/nfsmount.conf.d/*.conf
>>
>> Also I don't know if it is a good idea to have the sub configs
>> dependent on the main config file. If the main config is remove
>> the sub config will never be seen. Is that a good thing?
>>
>> I'm thinking we go with processing the sub configs separate 
>> from the main config and allow multiple sub configs be processed 
>> if they end with ".config" (mrchuck's suggestion).
>>
>> Then document all this in the man pages.  
>>
>> The last question should the main config be process,
>> not at all or after or before the sub configs?
>>
>> steved.
>>   
>>>
>>> The leading minus tells it that it isnt an error if its empty, and
>>> it
>>> will load all of the fragments it finds in there as well as the
>>> existing single file.  Apply the same structure to any existing
>>> config
>>> file that you want to also have a directory for.
>>>
>>> -Alice
>>>
>>>
>>>
>>> diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c
>>> index 58c03911..aade50c8 100644
>>> --- a/support/nfs/conffile.c
>>> +++ b/support/nfs/conffile.c
>>> @@ -53,6 +53,7 @@
>>>  #include <libgen.h>
>>>  #include <sys/file.h>
>>>  #include <time.h>
>>> +#include <glob.h>
>>>  
>>>  #include "conffile.h"
>>>  #include "xlog.h"
>>> @@ -690,6 +691,7 @@ conf_parse_line(int trans, char *line, const
>>> char *filename, int lineno, char **
>>>  	if (strcasecmp(line, "include")==0) {
>>>  		/* load and parse subordinate config files */
>>>  		_Bool optional = false;
>>> +		glob_t globdata;
>>>  
>>>  		if (val && *val == '-') {
>>>  			optional = true;
>>> @@ -704,33 +706,46 @@ conf_parse_line(int trans, char *line, const
>>> char *filename, int lineno, char **
>>>  			return;
>>>  		}
>>>  
>>> -		subconf = conf_readfile(relpath);
>>> -		if (subconf == NULL) {
>>> -			if (!optional)
>>> -				xlog_warn("config error at %s:%d: error
>>> loading included config",
>>> -					  filename, lineno);
>>> -			if (relpath)
>>> -				free(relpath);
>>> -			return;
>>> -		}
>>> +		if (glob(relpath, GLOB_MARK|GLOB_NOCHECK, NULL,
>>> &globdata)) {
>>> +			xlog_warn("config error at %s:%d: error with
>>> matching pattern", filename, lineno);
>>> +		} else 
>>> +		{
>>> +			for (size_t g=0; g<globdata.gl_pathc; g++) {
>>> +				const char * subpath =
>>> globdata.gl_pathv[g];
>>>  
>>> -		/* copy the section data so the included file can
>>> inherit it
>>> -		 * without accidentally changing it for us */
>>> -		if (*section != NULL) {
>>> -			inc_section = strdup(*section);
>>> -			if (*subsection != NULL)
>>> -				inc_subsection = strdup(*subsection);
>>> -		}
>>> +				if (subpath[strlen(subpath)-1] == '/')
>>> {
>>> +					continue;
>>> +				}
>>> +				subconf = conf_readfile(subpath);
>>> +				if (subconf == NULL) {
>>> +					if (!optional)
>>> +						xlog_warn("config error
>>> at %s:%d: error loading included config",
>>> +							  filename,
>>> lineno);
>>> +					if (relpath)
>>> +						free(relpath);
>>> +					return;
>>> +				}
>>> +
>>> +				/* copy the section data so the
>>> included file can inherit it
>>> +				 * without accidentally changing it for
>>> us */
>>> +				if (*section != NULL) {
>>> +					inc_section = strdup(*section);
>>> +					if (*subsection != NULL)
>>> +						inc_subsection =
>>> strdup(*subsection);
>>> +				}
>>>  
>>> -		conf_parse(trans, subconf, &inc_section,
>>> &inc_subsection, relpath);
>>> +				conf_parse(trans, subconf,
>>> &inc_section, &inc_subsection, relpath);
>>>  
>>> -		if (inc_section)
>>> -			free(inc_section);
>>> -		if (inc_subsection)
>>> -			free(inc_subsection);
>>> +				if (inc_section)
>>> +					free(inc_section);
>>> +				if (inc_subsection)
>>> +					free(inc_subsection);
>>> +				free(subconf);
>>> +			}
>>> +		}
>>>  		if (relpath)
>>>  			free(relpath);
>>> -		free(subconf);
>>> +		globfree(&globdata);
>>>  	} else {
>>>  		/* XXX Perhaps should we not ignore errors?  */
>>>  		conf_set(trans, *section, *subsection, line, val, 0,
>>> 0);
>>>
>>>
> 




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux