Subject: Re: bug#41541: merge wip-hurd-vm

From: Ludovic Courtès <[email-masked]>
Date: Tue, 02 Jun 2020 14:40:24 +0200

Hi,

Jan Nieuwenhuizen <[email-masked]> skribis:

>> Having an RC argument passed directly by the bootloader seems like a
>> good way to proceed for me. This is somehow remotely similar to what we
>> are doing with the "initrd" on Linux (pointing to some piece of code
>> that needs to be loaded before starting the init process).
>>
>> You would also need to store this RC argument in the <boot-parameters>
>> record, by adding a new field or stuffing it in the "initrd"
>> field. Then, we wouldn't need an extra service I guess.
>
> Hmm...I don't understand...probably I'm missing something.
>
> I was thinking to just extend boot-parameters with
> --rc-file=%hurd-rc-script, and then add %hurd-rc-script to the SYSTEM
> service...How would I get the RC script into SYSTEM without a service?

Normally, if you have the system (as returned by ‘guix system build’),
that’s enough to derive any other kind of thing you might want.

So for example, you could have a “startup” (or “rc”) entry in the
‘system’ directory by extending ‘system-service-type’.  And since the
system is known from the boot command line, bingo.

The guideline IMO should be to remain as close as possible to Guix
System on GNU/Linux.  It’s OK to depart a bit from upstream Hurd though
because those bits are not actually used (Debian does its own thing).

>> If we are going that way, the procedures in (gnu build hurd-boot) could
>> be passed the "hurd" package to install, and we could maybe get rig of
>> the "/hurd" symlink?
>
> Hehe, that would be nice...but IME /hurd isn't easy to get rid of.

Some of the /hurd names are embedded in libc, via the Hurd’s paths.h.
Some names are compared by string (!); for instance, symlink.c in libc
has:

  /* A symlink is a file whose translator is "/hurd/symlink\0target\0".  */

  memcpy (buf, _HURD_SYMLINK, sizeof (_HURD_SYMLINK));
  memcpy (&buf[sizeof (_HURD_SYMLINK)], from, len);

That makes it next to impossible to remove /hurd.

I think it should be treated like /bin/sh and /run/current-system: set
up at activation time.

>>>From e11e59cbcd9165e3b885c1019e19aaab471f5498 Mon Sep 17 00:00:00 2001
> From: "Jan (janneke) Nieuwenhuizen" <[email-masked]>
> Date: Thu, 30 Apr 2020 15:40:07 +0200
> Subject: [PATCH] gnu: services: Add %hurd-startup-service.
>
> This decouples startup of the Hurd from the "hurd" package, moving the RC
> script into SYSTEM.
>
> * gnu/packages/hurd.scm (hurd)[inputs]: Remove hurd-rc-script.
> [arguments]: Do not substitute it.  Update "runsystem.sh" to parse
> kernel arguments and exec into --rc-file=RC-FILE.
> (hurd-rc-script): Move to...
> * gnu/services.scm (%hurd-rc-file): ...this new variable.
> (bootable-kernel-arguments): Use it.
> (%hurd-bare-metal-service): New variable.
> * gnu/system.scm (hurd-default-essential-services): Use it.

[…]

> +;; XXX this won't go into SYSTEM (as system-service); the result is fine
> +;; though and it gets picked-up well by --rc-file=%hurd-rc-script
> +(define %hurd-rc-script
> +  ;; The RC script to be started upon boot.
> +  (program-file "rc"
> +                (with-imported-modules '((guix build utils)
> +                                         (gnu build hurd-boot)
> +                                         (guix build syscalls))

Probably use ‘source-module-closure’ to be on the safe side.

> +(define (hurd-rc-entry mrc)
> +  "Return, as a monadic value, an entry for the RC script in the system
> +directory."
> +  (mlet %store-monad ((rc mrc))
> +    (return `(("rc" ,rc)))))
> +
> +(define hurd-startup-service-type
> +  ;; The service that creates the initial RC startup file.
> +  (service-type (name 'startup)
> +                (extensions
> +                 (list (service-extension system-service-type hurd-rc-entry)))
> +                (compose identity)
> +                (extend (const (lower-object %hurd-rc-script)))
> +                (description
> +                 "Produce the operating system's RC script, which is executed
> +by RUNSYSTEM.")))

Is this service really meant to be extensible?  If not, we could just do:

  (service-type (name 'startup)
                (extensions
                 (list (service-extension system-service-type hurd-rc-entry)))
                (default-value %hurd-rc-script))

where:

  (define (hurd-rc-entry rc)
    (mlet %store-monad ((rc (lower-object rc)))
      (return `(("rc" ,rc)))))

> +  (append
> +   (if (hurd-target?)
> +       (list #~(string-append "--rc-file=" #$%hurd-rc-script))
> +       '())
> +   (list (string-append "--root="
> +                        ;; Note: Always use the DCE format because that's what
> +                        ;; (gnu build linux-boot) expects for the '--root'
> +                        ;; kernel command-line option.
> +                        (file-system-device->string root-device
> +                                                    #:uuid-type 'dce))
> +         #~(string-append "--system=" #$system)
> +         #~(string-append "--load=" #$system "/boot"))))

So my suggestion is to avoid --rc-file since you know that SYSTEM/rc
exists.

Ludo’, who jumps in the middle of the discussion.  :-)