On Tue, Feb 5, 2019 at 6:35 PM Waldek Kozaczuk <[email protected]> wrote:

>
> Let me recap couple of things at least for my own sake of having better
> understanding of the problem. So there are two aspects around resolv.conf -
> (1) how the file is used and (2) how it constructed. As far as 1) goes
> normally apps rely on libc to resolve host names which hides existence of
> the file. In OSv case which uses musl you can see details here -
> https://wiki.musl-libc.org/functional-differences-from-glibc.html (see
> 'Names Resolver/DNS section'). Golang (and probably Erlang) are different
> and they directly use resolve.conf - I think this golang source code has
> details of the logic -
> https://github.com/golang/go/blob/9ff11b026089791c4d2bc14c17647f3cb4f4aa22/src/net/conf.go#L100
> .
>
> I have also found article of how resolv.conf is constructed -
> https://www.ctrl.blog/entry/resolvconf-tutorial.
>
> So here is what I propose:
> 1. Make simple change to golang module to add the default resolv.conf (see
> https://github.com/cloudius-systems/osv-apps/blob/master/erlang/default/resolv.conf
> for example) which points to Google public DNS server. This would make all
> Golang apps work out of the box as far as making outgoing HTTP calls which
> we discover does not work unless resolv.conf is present. This fix is super
> trivial.
> 2. For efficiency reasons to make Golang apps use DNS server that is
> resolved as part of DHCP lookup. I agree with Brian's approach that this
> should be optional.
>

I think the easiest and perhaps best approach would be to have the DHCP
client write a file /etc/resolv.conf when it discovers the DNS server? This
is what happens in my Linux system - the /etc/resolv.conf  on my laptop has:

# Generated by NetworkManager
nameserver 192.168.0.1

To support the case where the /etc filesystem is read-only, we can do the
following: In the read-only filesystem, put in /etc/resolv.conf a symbolic
link to /tmp/resolv.conf, assuming we always mount a writable /tmp. Then,
when dhcp.cc will write to "/etc/resolv.conf" (overwritten, e.g., open()
with O_TRUNC), it will actually write to that file on /tmp and succeed.


> I wonder what others think?
>
> Waldek
>
> PS. Please see my patch comments below.
>
> On Friday, January 25, 2019 at 11:27:37 AM UTC-5, Brian Ledbetter wrote:
>>
>> Here's my first stab at solving this problem in a backwards-compatible
>> way, let me know what you think.  I've added a --resolv flag to the loader
>> to enable this behavior.
>>
>> Please see
> https://github.com/cloudius-systems/osv/wiki/Formatting-and-sending-patches
> for how to format and send patches to the group. Thanks.
>
>> patch-dhcp.cc:
>>
>> --- ./core/dhcp.cc~     2019-01-25 11:18:29.173860626 -0500
>> +++ ./core/dhcp.cc      2019-01-25 11:17:19.546083373 -0500
>>
> I agree that dhcp.cc is the right place for this logic.
>
>> @@ -29,6 +29,12 @@
>>  #include <libc/network/__dns.hh>
>>
>>  using namespace boost::asio;
>> +bool generate_resolv_conf = false;
>> +
>> +void enable_resolv_conf()
>> +{
>> +       generate_resolv_conf = true;
>> +}
>>
>>  dhcp::dhcp_worker net_dhcp_worker;
>>
>> @@ -720,6 +726,31 @@
>>              });
>>
>>              osv::set_dns_config(dm.get_dns_ips(),
>> std::vector<std::string>());
>> +
>> +           // Some linux applications (go, erlang) depend on
>> /etc/resolv.conf to be
>> +           // populated with DNS server information in order to
>> function. The --resolv
>> +           // option has been added to the kernel loader, which will
>> enable this
>> +           // feature.
>> +           //
>> +           // TODO: It's possible that the /etc directory does not exist
>> at this time.
>> +           // We should ideally check and create it if necessary. What's
>> the right
>> +           // way to do that?
>>
> Probably. What if the filesystem is read-only\?
>
>> +           //
>> +           // TODO: We are currently ignoring DHCP-provided default
>> domain
>> +           // names. I'll have to dig further into the code to see if I
>> can ingest
>> +           // those.
>> +           //
>> +           if( generate_resolv_conf )
>> +           {
>> +                   FILE *f = fopen("/etc/resolv.conf", "w+");
>>
> Should we be appending if file already exists rather than overwrite it?
>
>> +                   if( f ) {
>> +                           fprintf( f, "## Autoconfigured by DHCP\n" );
>>
> I think this fprintf is redundant - you are printing the result below
> anyway.
>
>> +                           for( auto &ip : dm.get_dns_ips() )
>> +                           {
>> +                                   fprintf( f, "server %s\n",
>> ip.to_string().c_str() );
>> +                                   dhcp_i( "Added DNS server: %s\n",
>> ip.to_string().c_str() );
>> +                           }
>> +                           fclose( f );
>> +                           dhcp_i( "Generated /etc/resolv.conf" );
>>
> You could refine this message that it was generated from DHCP.
>
>> +                   }
>>
> Should we be handling the error of opening file and warn user that we
> could not generate the file?
>
>> +           }
>> +
>>              if (dm.get_hostname().size()) {
>>                     sethostname(dm.get_hostname().c_str(),
>> dm.get_hostname().size());
>>                  dhcp_i("Set hostname to: %s", dm.get_hostname().c_str());
>>
>>
>> patch-loader.cc:
>>
>> --- ./loader.cc~        2019-01-25 11:10:40.091359718 -0500
>> +++ ./loader.cc 2019-01-25 11:11:40.243167695 -0500
>> @@ -144,10 +144,13 @@
>>  bool opt_assign_net = false;
>>  bool opt_maxnic = false;
>>  int maxnic;
>> +static bool opt_resolv_conf = false;
>>
>>  static int sampler_frequency;
>>  static bool opt_enable_sampler = false;
>>
>> +void enable_resolv_conf();
>> +
>>  void parse_options(int loader_argc, char** loader_argv)
>>  {
>>      namespace bpo = boost::program_options;
>> @@ -182,6 +185,7 @@
>>          ("delay", bpo::value<float>()->default_value(0), "delay in
>> seconds before boot")
>>          ("redirect", bpo::value<std::string>(), "redirect stdout and
>> stderr to file")
>>          ("disable_rofs_cache", "disable ROFS memory cache")
>> +        ("resolv", "generate an /etc/resolv.conf file with DHCP DNS
>> values (for Linux compatibility)")
>>      ;
>>      bpo::variables_map vars;
>>      // don't allow --foo bar (require --foo=bar) so we can find the
>> first non-option
>> @@ -234,6 +238,11 @@
>>          enable_verbose();
>>      }
>>
>> +    if (vars.count("resolv")) {
>> +        opt_resolv_conf = true;
>> +        enable_resolv_conf();
>> +    }
>> +
>>      if (vars.count("sampler")) {
>>          sampler_frequency = vars["sampler"].as<int>();
>>          opt_enable_sampler = true;
>>
>>
>> patch-run.py:
>>
>> --- ./scripts/run.py~   2019-01-25 11:14:20.858654652 -0500
>> +++ ./scripts/run.py    2019-01-25 11:14:52.406553829 -0500
>> @@ -43,6 +43,8 @@
>>              execute = cmdline.read()
>>      if options.verbose:
>>          execute = "--verbose " + execute
>> +    if options.resolv:
>> +        execute = "--resolv " + execute
>>
> Maybe resolve_DNS?
>
>>
>>      if options.jvm_debug or options.jvm_suspend:
>>          if '-agentlib:jdwp' in execute:
>> @@ -461,6 +463,8 @@
>>                          help="Enable graphics mode.")
>>      parser.add_argument("-V", "--verbose", action="store_true",
>>                          help="pass --verbose to OSv, to display more
>> debugging information on the console")
>> +    parser.add_argument("--resolv", action="store_true",
>> +                        help="pass --resolv to OSv, to generate an
>> /etc/resolv.conf file for Linux compatibility")
>>      parser.add_argument("--forward", metavar="RULE", action="append",
>> default=[],
>>                          help="add network forwarding RULE (QEMU syntax)")
>>      parser.add_argument("--dry-run", action="store_true",
>>
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "OSv Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to