unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Name service switch configuration
@ 2015-02-04 22:00 Ludovic Courtès
  2015-02-25  7:37 ` Mark H Weaver
  0 siblings, 1 reply; 4+ messages in thread
From: Ludovic Courtès @ 2015-02-04 22:00 UTC (permalink / raw)
  To: guix-devel

[-- Attachment #1: Type: text/plain, Size: 6039 bytes --]

Hello Guix!

Commit 996ed73 adds support to configure libc’s name service switch
(NSS).  To enable something like nss-mdns (for the resolution of
‘.local’ names), one needs two things:

  1. Add this snippet to the ‘operating-system’ declaration:

     (name-service-switch (name-service-switch
                            (hosts (list %files
                                         (name-service
                                           (name "mdns_minimal")
                                           (reaction (lookup-specification
                                                      (not-found => return))))
                                         (name-service
                                           (name "dns"))
                                         (name-service
                                           (name "mdns"))))))

   2. Arrange to have ‘nscd-service’ called with:

        #:name-services (list nss-mdns)

And that works!

The reason to have complete bindings for nsswitch.conf, as opposed to
letting users write nsswitch.conf snippets directly, is that it’s
hopefully nicer to work with, allows for static checking, and is
inexpensive in terms of maintenance since the NSS interface is
essentially frozen.

However!  Currently, step #2 is absurdly difficult.  The ‘nscd-service’
call is buried in ‘%base-services’, so one needs to either expand
‘%base-services’, simply modifying the ‘nscd-service’ call to have the
required argument, or to maintain a local modification in (gnu system
base).  This sucks.

The solution to that will be to make service instances declarative (as
opposed to being a list of opaque monadic values as is currently the
case.)  That will allow users to, say, map/filter over ‘%base-services’
and change the options as they see fit.  I’ll try to come up with a
proposal for that soon, but ideas are welcome.

Below is the NSS documentation from the manual.

Comments welcome!

Ludo’.


6.2.9 Name Service Switch
-------------------------

The ‘(gnu system nss)’ module provides bindings to the configuration
file of libc’s "name service switch" or "NSS" (*note (libc)NSS
Configuration File::).  In a nutshell, the NSS is a mechanism that
allows libc to be extended with new “name” lookup methods for system
databases, which includes host names, service names, user accounts, and
more (*note System Databases and Name Service Switch: (libc)Name Service
Switch.).

   The NSS configuration specifies, for each system database, which
lookup method is to be used, and how the various methods are chained
together—for instance, under which circumstances NSS should try the next
method in the list.  The NSS configuration is given in the
‘name-service-switch’ field of ‘operating-system’ declarations (*note
‘name-service-switch’: operating-system Reference.).

   As an example, the declaration below configures the NSS to use the
‘nss-mdns’ back-end for host name lookups:

     (name-service-switch
        (hosts (list %files    ;first, check /etc/hosts

                     ;; If the above did not succeed, try
                     ;; with 'mdns_minimal'.
                     (name-service
                       (name "mdns_minimal")

                       ;; 'mdns_minimal' is authoritative for
                       ;; '.local'.  When it returns "not found",
                       ;; no need to try the next methods.
                       (reaction (lookup-specification
                                  (not-found => return))))

                     ;; Then fall back to DNS.
                     (name-service
                       (name "dns"))

                     ;; Finally, try with the "full" 'mdns'.
                     (name-service
                       (name "mdns")))))

   The reference for name service switch configuration is given below.
It is a direct mapping of the C library’s configuration file format, so
please refer to the C library manual for more information (*note
(libc)NSS Configuration File::).  Compared to libc’s NSS configuration
file format, it has the advantage not only of adding this warm
parenthetic feel that we like, but also static checks: you’ll know about
syntax errors and typos as soon as you run ‘guix system’.

 -- Scheme Variable: %default-nss
     This is the default name service switch configuration, a
     ‘name-service-switch’ object.

 -- Data Type: name-service-switch

     This is the data type representation the configuration of libc’s
     name service switch (NSS). Each field below represents one of the
     supported system databases.

     ‘aliases’
     ‘ethers’
     ‘group’
     ‘gshadow’
     ‘hosts’
     ‘initgroups’
     ‘netgroup’
     ‘networks’
     ‘password’
     ‘public-key’
     ‘rpc’
     ‘services’
     ‘shadow’
          The system databases handled by the NSS. Each of these fields
          must be a list of ‘<name-service>’ objects (see below.)

 -- Data Type: name-service

     This is the data type representing an actual name service and the
     associated lookup action.

     ‘name’
          A string denoting the name service (*note (libc)Services in
          the NSS configuration::).

          Note that name services listed here must be visible to nscd.
          This is achieved by passing the ‘#:name-services’ argument to
          ‘nscd-service’ the list of packages providing the needed name
          services (*note ‘nscd-service’: Base Services.).

     ‘reaction’
          An action specified using the ‘lookup-specification’ macro
          (*note (libc)Actions in the NSS configuration::).  For
          example:

               (lookup-specification (unavailable => continue)
                                     (success => return))


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Name service switch configuration
  2015-02-04 22:00 Name service switch configuration Ludovic Courtès
@ 2015-02-25  7:37 ` Mark H Weaver
  2015-02-25 17:07   ` Ludovic Courtès
  0 siblings, 1 reply; 4+ messages in thread
From: Mark H Weaver @ 2015-02-25  7:37 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 1365 bytes --]

Hi Ludovic!

ludo@gnu.org (Ludovic Courtès) writes:

> Commit 996ed73 adds support to configure libc’s name service switch
> (NSS).  To enable something like nss-mdns (for the resolution of
> ‘.local’ names), one needs two things:
>
>   1. Add this snippet to the ‘operating-system’ declaration:
>
>      (name-service-switch (name-service-switch
>                             (hosts (list %files
>                                          (name-service
>                                            (name "mdns_minimal")
>                                            (reaction (lookup-specification
>                                                       (not-found => return))))
>                                          (name-service
>                                            (name "dns"))
>                                          (name-service
>                                            (name "mdns"))))))
>
>    2. Arrange to have ‘nscd-service’ called with:
>
>         #:name-services (list nss-mdns)
>
> And that works!

Sounds great, except that it doesn't work for me :-(

I've done as you recommended, and "avahi-browse -avr" successfully shows
names of *.local hosts, but if I try to do name lookups on those names,
they always fail.

I've attached my OS configuration.  Any ideas?

      Mark


[-- Attachment #2: jojen OS configuration --]
[-- Type: text/plain, Size: 7407 bytes --]

;; GNU Guix operating system configuration for jojen

(use-modules (gnu)
             (gnu services)
             (guix gexp)
             (guix store)
             (guix monads))

(use-package-modules base bash admin wicd pulseaudio avahi vim linux)
(use-service-modules xorg avahi dbus networking)

(define (temperature-regulation-service)
  (with-monad %store-monad
    (return
     (service
      (documentation "Regulate temperature on an overclocked Libreboot X60.")
      (provision '(temperature-regulation))
      (requirement '(user-processes))
      (start #~(lambda _
                 (let ((pid (primitive-fork)))
                   (if (positive? pid)
                       pid
                       (let ()
                         (define (current-temp)
                           (call-with-input-file
                               "/sys/class/thermal/thermal_zone0/temp"
                             read))
                         (define (set-cpu1-online! online?)
                           (call-with-output-file
                               "/sys/devices/system/cpu/cpu1/online"
                             (lambda (port)
                               (write (if online? 1 0) port))))
                         (let loop ()
                           (let ((temp (current-temp)))
                             (cond ((< temp 88000) (set-cpu1-online! #t))
                                   ((> temp 92000) (set-cpu1-online! #f))))
                           (sleep 2)
                           (loop)))))))
      (stop #~(make-kill-destructor))
      (respawn? #t)))))

(define (powertop-auto-tune-service)
  (let ((powertop #~(string-append #$powertop "/sbin/powertop")))
    (with-monad %store-monad
      (return
       (service
        (documentation "Run powertop --auto-tune.")
        (provision '(powertop-auto-tune))
        (requirement '(user-processes))
        (start #~(lambda _
                   (zero? (system* #$powertop "--auto-tune")))))))))

(define (hdparm-service device)
  (let ((hdparm #~(string-append #$hdparm "/sbin/hdparm")))
    (with-monad %store-monad
      (return
       (service
        (documentation "Disable power management on drive.")
        (provision (list (symbol-append 'hdparm- (string->symbol device))))
        (requirement '(user-processes))
        (start #~(lambda _
                   (let ((pid (primitive-fork)))
                     (if (positive? pid)
                         pid
                         (let loop ()
                           (unless (zero? (system* #$hdparm "-B" "255" #$device))
                             (format (current-error-port)
                                     "hdparm failed!~%"))
                           (sleep 15)
                           (loop))))))
        (stop #~(make-kill-destructor))
        (respawn? #t))))))

(define (anti-caps-lock-service)
  (let ((dumpkeys #~(string-append #$kbd  "/bin/dumpkeys"))
        (loadkeys #~(string-append #$kbd  "/bin/loadkeys"))
        (grep     #~(string-append #$grep "/bin/grep"))
        (sed      #~(string-append #$sed  "/bin/sed"))
        (bash     #~(string-append #$bash "/bin/bash")))
    (with-monad %store-monad
      (return
       (service
        (documentation "Change caps-lock to control on the ttys.")
        (provision '(anti-caps-lock))
        (requirement '(user-processes))
        (start
         #~(lambda _
             (zero? (system* #$bash "-c"
                             (string-append #$dumpkeys " | "
                                            #$grep " Caps_Lock | "
                                            #$sed " s/Caps_Lock/Control/g | "
                                            #$loadkeys))))))))))

(define (sound-volume-service)
  (let ((amixer #~(string-append #$alsa-utils "/bin/amixer")))
    (with-monad %store-monad
      (return
       (service
        (documentation "Initialize sound volume to maximum.")
        (provision '(sound-volume-service))
        (requirement '(user-processes))
        (start
         #~(lambda _
             (zero? (system* #$amixer "-q" "set" "Master" "100%")))))))))

(operating-system
  (host-name "jojen")
  (timezone "US/Eastern")
  (locale "en_US.utf8")

  (bootloader (grub-configuration (device "/dev/sda")
				  (default-entry 0)
				  (timeout 1)))

  (swap-devices '("/dev/sda5"))
  (file-systems (cons* (file-system (device "jojen-root")
                                    (title 'label)
                                    (mount-point "/")
                                    (type "ext4"))
                       (file-system (device "jojen-videos")
                                    (title 'label)
                                    (mount-point "/home/mhw/Videos")
                                    (type "ext4")
                                    (flags '(no-dev no-suid)))
                       %base-file-systems))

  (users (list (user-account
                (name "mhw")
		(uid 1000)
                (group "mhw")
                (supplementary-groups
                 '("wheel" "users" "audio" "video" "dialout" "netdev"))
                (home-directory "/home/mhw"))))
  (groups (cons* (user-group
		  (name "mhw")
		  (id 1000))
		 %base-groups))

  (name-service-switch (name-service-switch
                        (hosts (list %files
                                     (name-service
                                      (name "mdns_minimal")
                                      (reaction (lookup-specification
                                                 (not-found => return))))
                                     (name-service
                                      (name "dns"))
                                     (name-service
                                      (name "mdns"))))))

  (packages (cons* vim iproute iw wicd pulseaudio avahi
                   %base-packages))

  (services
   (let ((motd (text-file "motd" "
This is the GNU operating system, welcome!\n\n")))
     (list (slim-service)
           (dbus-service (list avahi pulseaudio wicd))
           (wicd-service)
           (avahi-service)
           (nscd-service #:name-services (list nss-mdns))
           (tor-service)
           (bitlbee-service)

           (temperature-regulation-service)
           (powertop-auto-tune-service)
           (hdparm-service "/dev/sda")
           (anti-caps-lock-service)
           (sound-volume-service)

           (console-font-service "tty1")
           (console-font-service "tty2")
           (console-font-service "tty3")
           (console-font-service "tty4")
           (console-font-service "tty5")
           (console-font-service "tty6")

           (mingetty-service "tty1" #:motd motd)
           (mingetty-service "tty2" #:motd motd)
           (mingetty-service "tty3" #:motd motd)
           (mingetty-service "tty4" #:motd motd)
           (mingetty-service "tty5" #:motd motd)
           (mingetty-service "tty6" #:motd motd)
           (static-networking-service "lo" "127.0.0.1"
                                      #:provision '(loopback))
           (syslog-service)
           (guix-service)

           ;; The LVM2 rules are needed as soon as LVM2 or the device-mapper is
           ;; used, so enable them by default.  The FUSE and ALSA rules are
           ;; less critical, but handy.
           (udev-service #:rules (list lvm2 fuse alsa-utils))))))

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Name service switch configuration
  2015-02-25  7:37 ` Mark H Weaver
@ 2015-02-25 17:07   ` Ludovic Courtès
  2015-02-26  7:21     ` Mark H Weaver
  0 siblings, 1 reply; 4+ messages in thread
From: Ludovic Courtès @ 2015-02-25 17:07 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guix-devel

Mark H Weaver <mhw@netris.org> skribis:

> Sounds great, except that it doesn't work for me :-(
>
> I've done as you recommended, and "avahi-browse -avr" successfully shows
> names of *.local hosts, but if I try to do name lookups on those names,
> they always fail.
>
> I've attached my OS configuration.  Any ideas?

Long story short: there was a bug fixed by 60a2d27.

I’ve tried your OS config in a VM.  Everything looks good: nsswitch.conf
is OK, and we can see that libnss_mdns.so is mapped into nscd’s address
space.

Yet looking up ‘jojen.local’ doesn’t work.  I added some nscd debugging
like this:

           (nscd-service
            (nscd-configuration (inherit %nscd-default-configuration)
                                (debug-level 10))
            #:name-services (list nss-mdns))

/var/log/nscd.log shows warns about missing /var/db/nscd directory and
/etc/resolv.conf, which I added (with “dhclient eth0” for the latter),
to no avail.

Then I notice that even my config, which works on the bare metal,
doesn’t work in the VM.  I strace nscd in the VM to notice that it tries
to connect to /run/avahi-daemon/socket, which doesn’t exist.  This is
where I realize that my real root partition has /var/run as a symlink to
/run, which is why I don’t have the problem.  Pheeww.

Can you confirm that it works now?  :-)

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Name service switch configuration
  2015-02-25 17:07   ` Ludovic Courtès
@ 2015-02-26  7:21     ` Mark H Weaver
  0 siblings, 0 replies; 4+ messages in thread
From: Mark H Weaver @ 2015-02-26  7:21 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

ludo@gnu.org (Ludovic Courtès) writes:

> Mark H Weaver <mhw@netris.org> skribis:
>
>> Sounds great, except that it doesn't work for me :-(
>>
>> I've done as you recommended, and "avahi-browse -avr" successfully shows
>> names of *.local hosts, but if I try to do name lookups on those names,
>> they always fail.
>>
>> I've attached my OS configuration.  Any ideas?
>
> Long story short: there was a bug fixed by 60a2d27.

[...]

> Can you confirm that it works now?  :-)

Yes, it does.  Thank you!

    Mark

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-02-26  7:21 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-04 22:00 Name service switch configuration Ludovic Courtès
2015-02-25  7:37 ` Mark H Weaver
2015-02-25 17:07   ` Ludovic Courtès
2015-02-26  7:21     ` Mark H Weaver

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).