about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gn/deploy/octopus.scm51
-rw-r--r--gn/packages/file-systems.scm18
-rw-r--r--gn/services/file-systems.scm653
3 files changed, 707 insertions, 15 deletions
diff --git a/gn/deploy/octopus.scm b/gn/deploy/octopus.scm
index bb539e9..d3a0a6a 100644
--- a/gn/deploy/octopus.scm
+++ b/gn/deploy/octopus.scm
@@ -1,13 +1,14 @@
 (define-module (gn deploy octopus))
 
 (use-modules (gnu)
+             (gn services file-systems)
              (gn services science)
              (srfi srfi-26))
 (use-service-modules networking ssh web)
 (use-package-modules parallel shells)
 
 (define %efraimf-ssh-pubkey
-  (plain-file "id_rsa.pub"
+  (plain-file "efraim-id_rsa.pub"
               "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUCDY8ZKFF/ln0yzDt3CNmKz3cT4wzNv9bzCKvOBXcL0O7JtPWwqgLlZgmMHfzhzgReAkHcrt+Gdsyduzm/s9Y8c6QpyfaH6uoDwjfoOs6GrAjZaOXmAdncf+9HZEAy/IrygQ1YFRu6BvYogsdhhtN+O6IXBuvQQDRzldHs53Y53DK06Nrs19vAPwELXcDxcx1FvO+/L9nT8RHkI1Z0ucgTS+F/BWXl8+mh89r4j+4IRpZXOuCD0DrW5rgEE1EygF2dVdWZQESi23gU5Mt6vnmysXzwixB7j6I+xTih8LH4pz7hewEx6754e/cs9Gm7ZtfXKfXUt6+GtsBSBF3ULKl efraimf@octopus01"))
 
 
@@ -36,13 +37,17 @@
               ;  (flags '(no-exec no-dev no-atime))
               ;  (options "rw,nodiratime,largeio,inode64")
               ;  (create-mount-point? #t))
-              ;(file-system
-              ;  (device "octopus01:/home")
-              ;  (mount-point "/home")
-              ;  (type "nfs")
-              ;  (mount? #f)    ; is this necessary?
-              ;  (check? #f))
-              )
+              (file-system
+                (device "octopus01:/export")
+                (mount-point "/export")
+                (type "nfs")
+                (mount? #f)    ; VM can't find octopus01
+                (check? #f))(file-system
+                (device "octopus01:/home")
+                (mount-point "/home")
+                (type "nfs")
+                (mount? #f)    ; VM can't find octopus01
+                (check? #f)))
               %base-file-systems))
 
   (swap-devices '("/dev/sda2"))
@@ -114,13 +119,37 @@
                          (cgroup-extra-content
                            (string-append
                              "CgroupAutomount=yes     # default no\n"
-                             "ConstrainCores=yes      # default no"))
+                             "ConstrainCores=yes      # default no\n"
+                             "MaxRAMPercent=95        # default 100"))
                          (slurmdbd-extra-content
                            (string-append
-                             "LogFile=/var/log/slurmdbd.log       # default none, syslog"))
+                             "LogFile=/var/log/slurmdbd.log   # default none, syslog"))
                          (run-slurmdbd? #t)
                          (run-slurmctld? #t)))
 
+              (service lizardfs-service-type
+                       (lizardfs-configuration
+                         (mfsmetalogger-config
+                           (lizardfs-mfsmetalogger-config-file
+                             (master-host "octopus")))
+                         (mfschunkserver-config
+                           (lizardfs-mfschunkserver-config-file
+                             (master-host "octopus")))
+                         (mfshdd-config
+                           (lizardfs-mfshdd-config-file
+                             (disks-to-use (list "/mnt"))))
+                         (mfsmaster-config
+                           (lizardfs-mfsmaster-config-file
+                             (personality "master")
+                             (master-host "octopus")))
+                         (mfsexports-config
+                           (plain-file "mfsexports.cfg"
+                                       "* / rw\n"))
+                         (run-mfsmetalogger-service? #t)
+                         ))
+
               (service dhcp-client-service-type)
               (service openntpd-service-type))
-            %base-services)))
+            %base-services))
+
+  (name-service-switch %mdns-host-lookup-nss))
diff --git a/gn/packages/file-systems.scm b/gn/packages/file-systems.scm
index 0e874c2..f5fb2fb 100644
--- a/gn/packages/file-systems.scm
+++ b/gn/packages/file-systems.scm
@@ -36,17 +36,27 @@
              "-DENABLE_STATIC=NO"
              "-DENABLE_VERBOSE_ASCIIDOC=YES"
              "-DENABLE_TCMALLOC=NO"
+             ;"-DLIB_SUBDIR=lib" ; no 64 suffix
              ;; Some directories need to be changed
-             "-DRUN_SUBDIR=/var/run/lizardfs"
-             "-DDATA_SUBDIR=/var/lib/lizardfs"
+             ;"-DRUN_SUBDIR=/var/run/lizardfs"
+             ;"-DDATA_SUBDIR=/var/lib/lizardfs"
+             ;"-DETC_SUBDIR=/etc/lizardfs"
              "-DENABLE_UTILS=YES")
        #:tests? #f  ; Tests fail to build.
        #:phases
        (modify-phases %standard-phases
-         (add-after 'unpack 'dont-use-lib64
+         (add-after 'unpack 'configure-through-cmakelists.txt
            (lambda _
+             ;; For some reason some configure flags don't work.
              (substitute* "CMakeLists.txt"
-               (("\"64\"") "\"\""))
+               (("\"64\"") "\"\"")
+               (("var/run/mfs") "/var/run/lizardfs")
+               (("var/lib/mfs") "/var/lib/lizardfs")
+               (("etc/mfs") "/etc/lizardfs"))
+             ;; Then adjust the install directories back.
+             (substitute* "src/data/CMakeLists.txt"
+               (("\\$\\{ETC_SUBDIR\\}") "etc/lizardfs")
+               (("\\$\\{DATA_SUBDIR\\}") "var/lib/lizardfs"))
              #t))
          (add-after 'unpack 'use-system-libraries
            (lambda* (#:key inputs #:allow-other-keys)
diff --git a/gn/services/file-systems.scm b/gn/services/file-systems.scm
new file mode 100644
index 0000000..386f2ac
--- /dev/null
+++ b/gn/services/file-systems.scm
@@ -0,0 +1,653 @@
+(define-module (gn services file-systems)
+  #:use-module (guix gexp)
+  #:use-module (guix records)
+  #:use-module (gnu services)
+  #:use-module (gnu services shepherd)
+  #:use-module (gnu system accounts)
+  #:use-module (gnu system shadow)
+  #:use-module (gnu packages admin)
+  #:use-module (gnu packages linux)
+  #:use-module (gn packages file-systems)
+  #:use-module (ice-9 match)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-9)
+
+  #:export (lizardfs-configuration
+            lizardfs-configuration?
+            lizardfs-service-type
+
+            lizardfs-mfschunkserver-config-file
+            lizardfs-mfschunkserver-config-file?
+            lizardfs-mfshdd-config-file
+            lizardfs-mfshdd-config-file?
+            lizardfs-mfsmaster-config-file
+            lizardfs-mfsmaster-config-file?
+            lizardfs-mfsmetalogger-config-file
+            lizardfs-mfsmetalogger-config-file?))
+
+
+(define %lizardfs-accounts
+  (list (user-group
+          (name "lizardfs")
+          (system? #t))
+        (user-account
+          (name "lizardfs")
+          (group "lizardfs")
+          (system? #t)
+          (comment "Lizardfs User")
+          (home-directory "/var/lib/lizardfs")
+          (shell (file-append shadow "/sbin/nologin")))))
+
+(define-record-type* <lizardfs-mfsmetalogger-config-file>
+  lizardfs-mfsmetalogger-config-file
+  make-lizardfs-mfsmetalogger-config-file
+  lizardfs-mfsmetalogger-config-file?
+  (working-user     lizardfs-mfsmetalogger-config-file-working-user
+                    (default "lizardfs"))
+  (working-group    lizardfs-mfsmetalogger-config-file-working-group
+                    (default "lizardfs"))
+  (syslog-identifier lizardfs-mfsmetalogger-config-file-syslog-identifier
+                     (default "mfsmetalogger"))
+  (lock-memory      lizardfs-mfsmetalogger-config-file-lock-memory
+                    (default #f))   ; 0 or 1
+  (nice-level       lizardfs-mfsmetalogger-config-file-nice-level
+                    (default -19))
+  (data-path        lizardfs-mfsmetalogger-config-file-data-path
+                    (default "/var/lib/lizardfs"))
+  (back-logs        lizardfs-mfsmetalogger-config-file-back-logs
+                    (default 50))
+  (back-meta-keep-previous  lizardfs-mfsmetalogger-config-file-back-meta-keep-previous
+                            (default 3))
+  (meta-download-frequency  lizardfs-mfsmetalogger-config-file-meta-download-frequency
+                            (default 24))
+  (master-reconnection-delay    lizardfs-mfsmetalogger-config-file-master-reconnection-delay
+                                (default 5))
+  (master-host      lizardfs-mfsmetalogger-config-file-master-host
+                    (default "mfsmaster"))
+  (master-port      lizardfs-mfsmetalogger-config-file-master-port
+                    (default 9419))
+  (master-timeout   lizardfs-mfsmetalogger-config-file-master-timeout
+                    (default 60)))
+
+(define-gexp-compiler (lizardfs-mfsmetalogger-config-file-compiler
+                        (file <lizardfs-mfsmetalogger-config-file>) system target)
+  (match file
+         (($ <lizardfs-mfsmetalogger-config-file> working-user working-group syslog-identifier lock-memory nice-level data-path back-logs back-meta-keep-previous meta-download-frequency master-reconnection-delay master-host master-port master-timeout)
+          (gexp->derivation
+            "mfsmetalogger.cfg"
+            #~(call-with-output-file #$output
+                (lambda (port)
+                  (display
+                    (string-append
+                      "# This file generated by GNU Guix\n\n"
+                      (ungexp-splicing
+                        `(,@`("WORKING_USER = " ,working-user "\n")
+                          ,@`("WORKING_GROUP = " ,working-group "\n")
+                          ,@`("SYSLOG_IDENT = " ,syslog-identifier "\n")
+                          ,@(if lock-memory
+                              `("LOCK_MEMORY = 1\n")
+                              `("LOCK_MEMORY = 0\n"))
+                          ,@`("NICE_LEVEL = " ,(number->string nice-level) "\n")
+                          ,@`("DATA_PATH = " ,data-path "\n")
+                          ,@`("BACK_LOGS = " ,(number->string back-logs) "\n")
+                          ,@`("BACK_META_KEEP_PREVIOUS = " ,(number->string back-meta-keep-previous) "\n")
+                          ,@`("META_DOWNLOAD_FREQ = " ,(number->string meta-download-frequency) "\n")
+                          ,@`("MASTER_RECONNECTION_DELAY = " ,(number->string master-reconnection-delay) "\n")
+                          ,@`("MASTER_HOST = " ,master-host "\n")
+                          ,@`("MASTER_PORT = " ,(number->string master-port) "\n")
+                          ,@`("MASTER_TIMEOUT = " ,(number->string master-timeout) "\n"))))
+                    port)))
+            #:local-build? #t))))
+
+(define-record-type* <lizardfs-mfschunkserver-config-file>
+  lizardfs-mfschunkserver-config-file
+  make-lizardfs-mfschunkserver-config-file
+  lizardfs-mfschunkserver-config-file?
+  (label            lizardfs-mfschunkserver-label
+                    (default "_"))
+  (working-user     lizardfs-mfschunkserver-config-file-working-user
+                    (default "lizardfs"))
+  (working-group    lizardfs-mfschunkserver-config-file-working-group
+                    (default "lizardfs"))
+  (syslog-identifier lizardfs-mfschunkserver-config-file-syslog-identifier
+                     (default "mfschunkserver"))
+  (lock-memory      lizardfs-mfschunkserver-config-file-lock-memory
+                    (default #f))   ; 0 or 1
+  (nice-level       lizardfs-mfschunkserver-config-file-nice-level
+                    (default -19))
+  (data-path        lizardfs-mfschunkserver-config-file-data-path
+                    (default "/var/lib/lizardfs"))
+  (master-reconnection-delay    lizardfs-mfschunkserver-config-file-master-reconnection-delay
+                                (default 5))
+  (bind-host        lizardfs-mfschunkserver-bind-host
+                    (default "*"))
+  (master-host      lizardfs-mfschunkserver-config-file-master-host
+                    (default "mfsmaster"))
+  (master-port      lizardfs-mfschunkserver-config-file-master-port
+                    (default 9420))
+  (master-timeout   lizardfs-mfschunkserver-config-file-master-timeout
+                    (default 60))
+  (csserv-listen-host       lizardfs-mfschunkserver-config-csserv-listen-host
+                            (default "*"))
+  (csserv-listen-port       lizardfs-mfschunkserver-config-csserv-listen-port
+                            (default 9422))
+  (hdd-conf-filename        lizardfs-mfschunkserver-config-hdd-conf-filename
+                            (default "/etc/lizardfs/mfshdd.cfg"))      ; This should be our generated one
+  (hdd-leave-space-default  lizardfs-mfschunkserver-config-hdd-leave-space-default
+                            (default "4GiB"))
+  (hdd-test-freq        lizardfs-mfschunkserver-config-hdd-test-freq
+                        (default 10))
+  (hdd-advise-no-cache  lizardfs-mfschunkserver-config-hdd-advise-no-cache
+                        (default #t))   ; 0 or 1
+  (hdd-punch-holes      lizardfs-mfschunkserver-config-hdd-punch-holes
+                        (default #t))   ; 0 or 1
+  (enable-load-factor   lizardfrs-mfschunkserver-config-enable-load-factor
+                        (default #f))   ; 0 or 1
+  (replication-bandwidth-limit-kbps
+                        lizardfs-mfschunkserver-config-replication-bandwidth-limit-kbps
+                        (default 8192))
+  (nr-of-network-workers    lizardfs-mfschunkserver-config-nr-of-network-workers
+                            (default 1))
+  (nr-of-hdd-workers-per-network-worker
+                        lizardfs-mfschunkerver-config-nr-of-hdd-workers-per-network-pworker
+                        (default 20))
+  (read-ahead-kb        lizardfs-mfschunkserver-config-read-ahead-kb
+                        (default 0))
+  (max-read-behind-kb   lizardfs-mfschunkserver-config-max-read-behind-kb
+                        (default 0))
+  (create-new-chunks-in-moosefs-format
+                        lizardfs-mfschunkserver-config-crate-new-chunks-in-moosefs-format
+                        (default #t))   ; 0 or 1
+  (perform-fsync        lizardfs-mfschunkserver-config-perform-fsync
+                        (default #t))   ; 0 or 1
+  )
+
+(define-gexp-compiler (lizardfs-mfschunkserver-config-file-compiler
+                        (file <lizardfs-mfschunkserver-config-file>) system target)
+  (match file
+         (($ <lizardfs-mfschunkserver-config-file> label working-user working-group syslog-identifier lock-memory nice-level data-path master-reconnection-delay bind-host master-host master-port master-timeout csserv-listen-host csserv-listen-port hdd-conf-filename hdd-leave-space-default hdd-test-freq hdd-advise-no-cache hdd-punch-holes enable-load-factor replication-bandwidth-limit-kbps nr-of-network-workers nr-of-hdd-workers-per-network-worker read-ahead-kb max-read-behind-kb create-new-chunks-in-moosefs-format perform-fsync)
+          (gexp->derivation
+            "mfschunkserver.cfg"
+            #~(call-with-output-file #$output
+                (lambda (port)
+                  (display
+                    (string-append
+                      "# This file generated by GNU Guix\n\n"
+                      (ungexp-splicing
+                        `(,@`("LABEL = " ,label "\n")
+                          ,@`("WORKING_USER = " ,working-user "\n")
+                          ,@`("WORKING_GROUP = " ,working-group "\n")
+                          ,@`("SYSLOG_IDENT = " ,syslog-identifier "\n")
+                          ,@(if lock-memory
+                              `("LOCK_MEMORY = 1\n")
+                              `("LOCK_MEMORY = 0\n"))
+                          ,@`("NICE_LEVEL = " ,(number->string nice-level) "\n")
+                          ,@`("DATA_PATH = " ,data-path "\n")
+                          ,@`("MASTER_RECONNECTION_DELAY = " ,(number->string master-reconnection-delay) "\n")
+                          ,@`("MASTER_HOST = " ,master-host "\n")
+                          ,@`("MASTER_PORT = " ,(number->string master-port) "\n")
+                          ,@`("MASTER_TIMEOUT = " ,(number->string master-timeout) "\n")
+                          ,@`("CSSERV_LISTEN_HOST = " ,csserv-listen-host "\n")
+                          ,@`("CSSERV_LISTEN_PORT = " ,(number->string csserv-listen-port) "\n")
+                          ,@`("HDD_CONF_FILENAME = " ,hdd-conf-filename "\n")
+                          ,@`("HDD_LEAVE_SPACE_DEFAULT = " ,hdd-leave-space-default "\n")
+                          ,@`("HDD_TEST_FREQ = " ,(number->string hdd-test-freq) "\n")
+                          ,@(if hdd-advise-no-cache
+                              `("HDD_ADVISE_NO_CACHE = 1\n")
+                              `("HDD_ADVISE_NO_CACHE = 0\n"))
+                          ,@(if hdd-punch-holes
+                              `("HDD_PUNCH_HOLES = 1\n")
+                              `("HDD_PUNCH_HOLES = 0\n"))
+                          ,@(if enable-load-factor
+                              `("ENABLE_LOAD_FACTOR = 1\n")
+                              `("ENABLE_LOAD_FACTOR = 0\n"))
+                          ,@`("REPLICATION_BANDWIDTH_LIMIT_KBPS = " ,(number->string replication-bandwidth-limit-kbps) "\n")
+                          ,@`("NR_OF_NETWORK_WORKERS = " ,(number->string nr-of-network-workers) "\n")
+                          ,@`("NR_OF_HDD_WORKERS_PER_NETWORK_WORKER = " ,(number->string nr-of-hdd-workers-per-network-worker) "\n")
+                          ,@`("READ_AHEAD_KB = " ,(number->string read-ahead-kb) "\n")
+                          ,@`("MAX_READ_BEHIND_KB = " ,(number->string max-read-behind-kb) "\n")
+                          ,@(if create-new-chunks-in-moosefs-format
+                              `("CREATE_NEW_CHUNKS_IN_MOOSEFS_FORMAT = 1\n")
+                              `("CREATE_NEW_CHUNKS_IN_MOOSEFS_FORMAT = 0\n"))
+                          ,@(if perform-fsync
+                              `("PERFORM_FSYNC = 1\n")
+                              `("PERFORM_FSYNC = 0\n")))))
+                    port)))
+            #:local-build? #t))))
+
+(define-record-type* <lizardfs-mfshdd-config-file>
+  lizardfs-mfshdd-config-file
+  make-lizardfs-mfshdd-config-file
+  lizardfs-mfshdd-config-file?
+  (disks-to-use     lizardfs-mfshdd-config-file-disks-to-use
+                    (default '()))
+  (disks-to-remove  lizardfs-mfshdd-config-file-disks-to-remove
+                    (default '())))
+
+(define-gexp-compiler (lizardfs-mfshdd-config-file-compiler
+                        (file <lizardfs-mfshdd-config-file>) system target)
+  (match file
+         (($ <lizardfs-mfshdd-config-file> disks-to-use disks-to-remove)
+          (gexp->derivation
+            "mfshdd.cfg"
+            #~(call-with-output-file #$output
+                (lambda (port)
+                  (display
+                    (string-append
+                      "# This file generated by GNU Guix\n\n"
+                      (ungexp-splicing
+                        `(,@(append-map
+                              (lambda (disk)
+                                `(,disk "\n"))
+                              disks-to-use)
+                          ,@(append-map
+                              (lambda (disk)
+                                `("*" ,disk "\n"))
+                              disks-to-remove))))
+                    port)))
+            #:local-build? #t))))
+
+(define-record-type* <lizardfs-mfsmaster-config-file>
+  lizardfs-mfsmaster-config-file
+  make-lizardfs-mfsmaster-config-file
+  lizardfs-mfsmaster-config-file?
+  (personality      lizardsf-mfsmaster-config-personality
+                    (default ""))
+  (admin-password   lizardfs-mfsmaster-config-admin-password
+                    (default ""))
+  (working-user     lizardfs-mfsmaster-config-working-user
+                    (default "lizardfs"))
+  (working-group    lizardfs-mfsmaster-config-working-group
+                    (default "lizardfs"))
+  (syslog-ident     lizardfs-mfsmaster-config-syslog-ident
+                    (default "mfsmaster"))
+  (lock-memory      lizardfs-mfsmaster-config-lock-memory
+                    (default #f))   ; 0 or 1
+  (nice-level       lizardfs-mfsmaster-config-nice-level
+                    (default -19))
+  (exports-filename lizardfs-mfsmaster-config-exports-filename
+                    (default "/etc/lizardfs/mfsexports.cfg"))   ; our created one?
+  (topology-filename    lizardfs-mfsmaster-config-topology-filename
+                        (default "/etc/lizardfs/mfstopology.cfg"))   ; our created one?
+  (custom-goals-filename    lizardfs-mfsmaster-config-custom-goals-filename
+                            (default "/etc/lizardfs/mfsgoals.cfg"))  ; our created one?
+  (data-path        lizardfs-mfsmaster-config-data-path
+                    (default "/var/lib/lizardfs"))
+  (prefer-local-chunkserver lizardfs-mfsmaster-prefer-local-chunkserver
+                            (default #t))    ; 0 or 1
+  (auto-recovery    lizardfs-mfsmaster-config-auto-recovery
+                    (default #f))       ; 0 or 1
+  (back-logs        lizardfs-mfsmaster-config-back-logs
+                    (default 50))
+  (back-meta-keep-previous  lizardfs-mfsmaster-config-back-meta-keep-previous
+                            (default 1))
+  (operations-delay-init    lizardfs-mfsmaster-config-operations-delay-init
+                            (default 300))
+  (operations-delay-disconnect  lizardfs-mfsmaster-config-operations-delay-disconnect
+                                (default 3600))
+  (matoml-listen-host   lizardfs-mfsmaster-config-matoml-listen-host
+                        (default "*"))
+  (matoml-listen-port   lizardfs-mfsmaster-config-matoml-listen-port
+                        (default 9419))
+  (matoml-log-preserve-seconds  lizardfs-mfsmaster-config-matoml-log-preserve-seconds
+                                (default 600))
+  (matocs-listen-host   lizardfs-mfsmaster-config-matocs-listen-host
+                        (default "*"))
+  (matocs-listen-port   lizardfs-mfsmaster-config-matocs-listen-port
+                        (default 9420))
+  (matocl-listen-host   lizardfs-mfsmaster-config-matocl-listen-host
+                        (default "*"))
+  (matocl-listen-port   lizardfs-mfsmaster-config-matocl-listen-port
+                        (default 9421))
+  (matots-listen-host   lizardfs-mfsmaster-config-matots-listen-host
+                        (default "*"))
+  (matots-listen-port   lizardfs-mfsmaster-config-matots-listen-port
+                        (default 9424))
+  (chunks-loop-max-cps  lizardfs-mfsmaster-config-chunks-loop-max-cps
+                        (default 100000))
+  (chunks-loop-min-time lizardfs-mfsmaster-config-chunks-loop-min-time
+                        (default 300))
+  (chunks-loop-peroid   lizardfs-mfsmaster-config-chunks-loop-period
+                        (default 1000))
+  (chunks-loop-max-cpu  lizardfs-mfsmaster-config-chunks-loop-max-cpu
+                        (default 60))
+  (chunks-soft-del-limit    lizardfs-mfsmaster-config-chunks-soft-del-limit
+                            (default 10))
+  (chunks-hard-del-limit    lizardfs-mfsmaster-config-chunks-hard-del-limit
+                            (default 25))
+  (chunks-write-rep-limit   lizardfs-mfsmaster-config-chunks-write-rep-limit
+                            (default 2))
+  (chunks-read-rep-limit    lizardfs-mfsmaster-config-chunks-read-rep-limit
+                            (default 10))
+  (endangered-chunks-priority   lizardfs-mfsmaster-config-endangered-chunks-priority
+                                (default 0))
+  (endangered-chunks-max-capacity   lizardfs-mfsmaster-config-endangered-chunks-max-capacity
+                                    (default "1Mi"))
+  (acceptable-difference    lizardfs-mfsmaster-config-acceptable-difference
+                            (default 0.1))
+  (chunks-rebalancing-between-labels    lizardfs-mfsmaster-config-chunks-rebalancing-between-labels
+                                        (default 0))
+  (free-inodes-period   lizardfs-mfsmaster-config-free-inodes-period
+                        (default 60))
+  (no-atime             lizardfs-mfsmaster-config-no-atime
+                        (default #f))       ; 0 or 1
+  (session-sustain-time lizardfs-mfsmaster-config-session-sustain-time
+                        (default 86400))
+  (reject-old-client    lizardfs-mfsmaster-config-reject-old-clients
+                        (default #f))       ; 0 or 1
+  (globaliolimits-filename  lizardfs-mfsmaster-config-globaliolimits-filename
+                            (default "/etc/lizardfs/globaliolimits.cfg"))   ; our generated one?
+  (globaliolimits-renegotiation-period-settings
+                        lizardfs-mfsmaster-config-globaliolmits-renegotiation-period-settings
+                        (default 0.1))
+  (globaliolimits-accumulate-ms lizardfs-mfsmaster-config-globaliolimits-accumulate-ms
+                                (default 250))
+  (mfsmetarestore-path  lizardfs-mfsmaster-config-mfsmeaterestore-path
+                        (default (file-append lizardfs "/sbin/mfsmetarestore")))
+  (master-reconnection-delay    lizardfs-mfsmaster-config-master-reconnection-delay
+                                (default 5))
+  (master-host      lizardfs-mfsmaster-config-master-host
+                    (default "mfsmaster"))
+  (master-port      lizardfs-mfsmaster-config-master-port
+                    (default 9419))
+  (master-timeout   lizardfs-mfsmaster-config-master-timeout
+                    (default 60))
+  (metadata-checksum-interval   lizardfs-mfsmaster-config-metadata-checksum-interval
+                                (default 50))
+  (metadata-checksum-recalculation-speed    lizardfs-mfsmaster-config-metadata-recalculation-speed
+                                            (default 100))
+  (disable-metadata-checksum-verification   lizardfs-mfsmaster-config-disable-metadata-checksum-verification
+                                            (default #f))   ; 0 or 1
+  (metadata-save-request-min-period     lizardfs-mfsmaster-config-metadata-save-request-min-period
+                                        (default 1800))
+  (use-bdb-for-name-storage     lizardfs-mfsmaster-config-use-bdb-for-name-storage
+                                (default #t))       ; 0 or 1
+  (bdb-name-storage-cache       lizardfs-mfsmaster-config-bdb-name-storage-cache
+                                (default 10))
+  (avoid-same-ip-chunkservers   lizardfs-mfsmaster-config-avoid-same-ip-chunkservers
+                                (default #f))       ; 0 or 1
+  (load-factor-penalty      lizardfs-mfsmaster-config-load-factor-penalty
+                            (default 0))        ; between 0, 0.5, inclusive
+  (redundancy-level         lizardfs-mfsmaster-config-redundancy-level
+                            (default 0))
+  (snapshot-initial-batch-size-limit    lizardfs-mfsmaster-config-snapshot-initial-batch-size-limit
+                                        (default 10000))
+  (file-test-loop-min-time  lizardfs-mfsmaster-config-file-test-loop-min-time
+                            (default 3600)))
+
+
+(define-gexp-compiler (lizardfs-mfsmaster-config-file-compiler
+                        (file <lizardfs-mfsmaster-config-file>) system target)
+  (match file
+         (($ <lizardfs-mfsmaster-config-file> personality admin-password working-user working-group syslog-ident lock-memory nice-level exports-filename topology-filename custom-goals-filename data-path prefer-local-chunkserver auto-recovery back-logs back-meta-keep-previous operations-delay-init operations-delay-disconnect matoml-listen-host matoml-listen-port matoml-log-preserve-seconds matocs-listen-host matocs-listen-port matocl-listen-host matocl-listen-port matots-listen-host matots-listen-port chunks-loop-max-cps chunks-loop-min-time chunks-loop-period chunks-loop-max-cpu chunks-soft-del-limit chunks-hard-del-limit chunks-write-rep-limit chunks-read-rep-limit endangered-chunks-priority endangered-chunks-max-capacity acceptable-difference chunks-rebalancing-between-labels free-inodes-period no-atime session-sustain-time reject-old-client globaliolimits-filename globaliolimits-renegotiation-period-settings globaliolimits-accumulate-ms mfsmetarestore-path master-reconnection-delay master-host master-port master-timeout metadata-checksum-interval metadata-checksum-recalculation-speed disable-metadata-checksum-verification metadata-save-request-min-period use-bdb-for-name-storage bdb-name-storage-cache avoid-same-ip-chunkservers load-factor-penalty redundancy-level snapshot-initial-batch-size-limit file-test-loop-min-time)
+          (gexp->derivation
+            "mfsmaster.cfg"
+            #~(call-with-output-file #$output
+                (lambda (port)
+                  (display
+                    (string-append
+                      "# This file generated by GNU Guix\n\n"
+                      (ungexp-splicing
+                        `(,@`("PERSONALITY = " ,personality "\n")
+                          ,@`("ADMIN_PASSWORD = \"" ,admin-password "\"\n")
+                          ,@`("WORKING_USER = " ,working-user "\n")
+                          ,@`("WORKING_GROUP = " ,working-group "\n")
+                          ,@`("SYSLOG_IDENT = " ,syslog-ident "\n")
+                          ,@(if lock-memory
+                              `("LOCK_MEMORY = 1\n")
+                              `("LOCK_MEMORY = 0\n"))
+                          ,@`("NICE_LEVEL = " ,(number->string nice-level) "\n")
+                          ,@`("EXPORTS_FILENAME = " ,exports-filename "\n")
+                          ,@`("TOPOLOGY_FILENAME = " ,topology-filename "\n")
+                          ,@`("CUSTOM_GOALS_FILENAME = " ,custom-goals-filename "\n")
+                          ,@`("DATA_PATH = " ,data-path "\n")
+                          ,@(if prefer-local-chunkserver
+                              `("PREFER_LOCAL_CHUNKSERVER = 1\n")
+                              `("PREFER_LOCAL_CHUNKSERVER = 0\n"))
+                          ,@(if auto-recovery
+                              `("AUTO_RECOVERY = 1\n")
+                              `("AUTO_RECOVERY = 0\n"))
+                          ,@`("BACK_LOGS = " ,(number->string back-logs) "\n")
+                          ,@`("BACK_META_KEEP_PREVIOUS = " ,(number->string back-meta-keep-previous) "\n")
+                          ,@`("OPERATIONS_DELAY_INIT = " ,(number->string operations-delay-init) "\n")
+                          ,@`("OPERATIONS_DELAY_DISCONNECT = " ,(number->string operations-delay-disconnect) "\n")
+                          ,@`("MATOML_LISTEN_HOST = " ,matoml-listen-host "\n")
+                          ,@`("MATOML_LISTEN_PORT = " ,(number->string matoml-listen-port) "\n")
+                          ,@`("MATOML_LOG_PRESERVE_SECONDS = " ,(number->string matoml-log-preserve-seconds) "\n")
+                          ,@`("MATOCS_LISTEN_HOST = " ,matocs-listen-host "\n")
+                          ,@`("MATOCS_LISTEN_PORT = " ,(number->string matocs-listen-port) "\n")
+                          ,@`("MATOCL_LISTEN_HOST = " ,matocl-listen-host "\n")
+                          ,@`("MATOCL_LISTEN_PORT = " ,(number->string matocl-listen-port) "\n")
+                          ,@`("MATOTS_LISTEN_HOST = " ,matots-listen-host "\n")
+                          ,@`("MATOTS_LISTEN_PORT = " ,(number->string matots-listen-port) "\n")
+                          ,@`("CHUNKS_LOOP_MAX_CPS = " ,(number->string chunks-loop-max-cps) "\n")
+                          ,@`("CHUNKS_LOOP_MIN_TIME = " ,(number->string chunks-loop-min-time) "\n")
+                          ,@`("CHUNKS_LOOP_PERIOD = " ,(number->string chunks-loop-period) "\n")
+                          ,@`("CHUNKS_LOOP_MAX_CPU = " ,(number->string chunks-loop-max-cpu) "\n")
+                          ,@`("CHUNKS_SOFT_DEL_LIMIT = " ,(number->string chunks-soft-del-limit) "\n")
+                          ,@`("CHUNKS_HARD_DEL_LIMIT = " ,(number->string chunks-hard-del-limit) "\n")
+                          ,@`("CHUNKS_WRITE_REP_LIMIT = " ,(number->string chunks-write-rep-limit) "\n")
+                          ,@`("CHUNKS_READ_REP_LIMIT = " ,(number->string chunks-read-rep-limit) "\n")
+                          ,@`("ENDANGERED_CHUNKS_PRIORITY = " ,(number->string endangered-chunks-priority) "\n")
+                          ,@`("ENDANGERED_CHUNKS_MAX_CAPACITY = " ,endangered-chunks-max-capacity "\n")
+                          ,@`("ACCEPTABLE_DIFFERENCE = " ,(number->string acceptable-difference) "\n")
+                          ,@`("CHUNKS_REBALANCING_BETWEEN_LABELS = " ,(number->string chunks-rebalancing-between-labels) "\n")
+                          ,@`("FREE_INODES_PERIOD = " ,(number->string free-inodes-period) "\n")
+                          ,@(if no-atime
+                              `("NO_ATIME = 1\n")
+                              `("NO_ATIME = 0\n"))
+                          ,@`("SESSION_SUSTAIN_TIME = " ,(number->string session-sustain-time) "\n")
+                          ,@(if reject-old-client
+                              `("REJECT_OLD_CLIENT = 1\n")
+                              `("REJECT_OLD_CLIENT = 0\n"))
+                          ,@`("GLOBALIOLIMITS_FILENAME = " ,globaliolimits-filename "\n")
+                          ,@`("GLOBALIOLIMITS_RENEGOTIATION_PERIOD_SETTINGS = " ,(number->string globaliolimits-renegotiation-period-settings) "\n")
+                          ,@`("GLOBALIOLIMITS_ACCUMULATE_MS = " ,(number->string globaliolimits-accumulate-ms) "\n")
+                          ,@`("MFSMETARESTORE_PATH = " ,mfsmetarestore-path "\n")
+                          ,@`("MASTER_RECONNECTION_DELAY = " ,(number->string master-reconnection-delay) "\n")
+                          ,@`("MASTER_HOST = " ,master-host "\n")
+                          ,@`("MASTER_PORT = " ,(number->string master-port) "\n")
+                          ,@`("MASTER_TIMEOUT = " ,(number->string master-timeout) "\n")
+                          ,@`("METADATA_CHECKSUM_INTERVAL = " ,(number->string metadata-checksum-interval) "\n")
+                          ,@`("METADATA_CHECKSUM_RECALCULATION_SPEED = " ,(number->string metadata-checksum-recalculation-speed) "\n")
+                          ,@(if disable-metadata-checksum-verification
+                              `("DISABLE_METADATA_CHECKSUM_VERIFICATION = 1\n")
+                              `("DISABLE_METADATA_CHECKSUM_VERIFICATION = 0\n"))
+                          ,@`("METADATA_SAVE_REQUEST_MIN_PERIOD = " ,(number->string metadata-save-request-min-period) "\n")
+                          ,@(if use-bdb-for-name-storage
+                              `("USE_BDB_FOR_NAME_STORAGE = 1\n")
+                              `("USE_BDB_FOR_NAME_STORAGE = 0\n"))
+                          ,@`("BDB_NAME_STORAGE_CACHE = " ,(number->string bdb-name-storage-cache) "\n")
+                          ,@(if avoid-same-ip-chunkservers
+                              `("AVOID_SAME_IP_CHUNKSERVERS = 1\n")
+                              `("AVOID_SAME_IP_CHUNKSERVERS = 0\n"))
+                          ,@`("LOAD_FACTOR_PENALTY = " ,(number->string load-factor-penalty) "\n")
+                          ,@`("REDUNDANCY_LEVEL = " ,(number->string redundancy-level) "\n")
+                          ,@`("SNAPSHOT_INITIAL_BATCH_SIZE_LIMIT = " ,(number->string snapshot-initial-batch-size-limit) "\n")
+                          ,@`("FILE_TEST_LOOP_MIN_TIME = " ,(number->string file-test-loop-min-time) "\n"))))
+                    port)))
+            #:local-build? #t))))
+
+(define-record-type* <lizardfs-configuration>
+  lizardfs-configuration
+  make-lizardfs-configuration
+  lizardfs-configuration?
+  (package                  lizardfs-configuration-package
+                            (default lizardfs))
+  (mfsmetalogger-config     lizardfs-configuration-mfsmetalogger-config
+                            (default (lizardfs-mfsmetalogger-config-file)))
+  (mfschunkserver-config    lizardfs-configuration-mfschunkserver-config
+                            (default (lizardfs-mfschunkserver-config-file)))
+  (mfshdd-config            lizardfs-configuration-mfshdd-config
+                            (default (lizardfs-mfshdd-config-file)))
+  (mfsmaster-config         lizardfs-configuration-mfsmaster-config
+                            (default (lizardfs-mfsmaster-config-file)))
+  (run-mfsmetalogger-service? lizardfs-configuration-run-mfsmetalogger-service
+                            (default #f))
+  (mfsgoals-config          lizardfs-configuration-mfsgoals-config
+                            (default (plain-file "mfsgoals.cfg"
+                                                 (string-append
+                                                   "1 1_copy : _\n"
+                                                   "2 2_copies : _ _\n"
+                                                   "3 3_copies : _ _ _\n"))))
+  (mfsmount-config          lizardfs-configuration-mfsmount-config
+                            (default (plain-file "mfsmount.cfg"
+                                                 "")))
+  (mfsexports-config        lizardfs-configuration-mfsexports-config
+                            (default (plain-file "mfsexports.cfg"
+                                                 "")))
+  (mfstopology-config       lizardfs-configuration-mfstopology-config
+                            (default (plain-file "mfstopology.cfg"
+                                                 "")))
+  (globaliolimits-config    lizardfs-configuration-globaliolimits-config
+                            (default (plain-file "globaliolimits.cfg"
+                                                 "")))
+  (iolimits-config          lizardfs-configuration-iolimits-config
+                            (default (plain-file "iolimits.cfg"
+                                                 ""))))
+
+(define lizardfs-shepherd-service
+  (match-lambda
+    (($ <lizardfs-configuration> package)
+     (list
+       (shepherd-service
+         (documentation "Lizardfs mfsmaster server")
+         (provision '(lizardfs))
+         (requirement '(loopback))
+         (start #~(make-forkexec-constructor
+                    (list #$(file-append package "/sbin/mfsmaster")
+                          "-c" "/etc/lizardfs/mfsmaster.cfg"
+                          "-d" "start")
+                    #:log-file "/var/log/mfsmaster.log"))
+         (stop #~(make-system-destructor
+                   #$(file-append package "/sbin/mfsmaster")
+                   " -c /etc/lizardfs/mfsmaster.cfg"
+                   " stop"))
+         (respawn? #f)
+         (auto-start? #f)
+         )))))
+
+(define lizardfs-mfsmetalogger-shepherd-service
+  (match-lambda
+    (($ <lizardfs-configuration> package)
+     (list
+       (shepherd-service
+         (documentation "Lizardfs mfsmetalogger server")
+         (provision '(lizardfs-mfsmetalogger))
+         (requirement '(loopback lizardfs))
+         (start #~(make-forkexec-constructor
+                    (list #$(file-append package "/sbin/mfsmetalogger")
+                          "-c" "/etc/lizardfs/mfsmetalogger.cfg"
+                          "-d" "start")
+                    #:log-file "/var/log/mfsmetalogger.log"))
+         (stop #~(make-system-destructor
+                   #$(file-append package "/sbin/mfsmetalogger")
+                   " -c /etc/lizardfs/mfsmetalogger.cfg"
+                   " stop"))
+         (auto-start? #f)
+         )))))
+
+(define lizardfs-mfschunkserver-shepherd-service
+  (match-lambda
+    (($ <lizardfs-configuration> package)
+     (list
+       (shepherd-service
+         (documentation "Lizardfs mfschunkserver server")
+         (provision '(lizardfs-mfschunkserver))
+         (requirement '(loopback lizardfs))
+         (start #~(make-forkexec-constructor
+                    (list #$(file-append package "/sbin/mfschunkserver")
+                          "-c" "/etc/lizardfs/mfschunkserver.cfg"
+                          "-d" "start")
+                    #:log-file "/var/log/mfschunkserver.log"))
+         (stop #~(make-system-destructor
+                   #$(file-append package "/sbin/mfschunkserver")
+                   " -c /etc/lizardfs/mfschunkserver.cfg"
+                   " stop"))
+         (auto-start? #f)
+         )))))
+
+(define lizardfs-mfsmount-shepherd-service
+  (match-lambda
+    (($ <lizardfs-configuration> package)
+     (list
+       (shepherd-service
+         (documentation "Mount Lizardfs filesystems")
+         (provision '(lizardfs-mounts))
+         (requirement '(loopback))
+         (start #~(make-forkexec-constructor
+                    (list #$(file-append package "/bin/mfsmount")
+                          ;#$mountpoint
+                          "-o" "mfsdelayedinit")
+                    ))
+         ;(stop #~(make-system-destructor #$(file-append fuse "/bin/fusermount") " -u " #$mountpoint))
+         (stop #~(make-kill-destructor))
+         (auto-start? #f)
+         )))))
+
+(define (lizardfs-etc-service config)
+  `(("lizardfs/globaliolimits.cfg"
+     ,(lizardfs-configuration-globaliolimits-config config))
+    ("lizardfs/iolimits.cfg"
+     ,(lizardfs-configuration-iolimits-config config))
+    ("lizardfs/mfschunkserver.cfg"
+     ,(lizardfs-configuration-mfschunkserver-config config))
+    ("lizardfs/mfsexports.cfg"
+     ,(lizardfs-configuration-mfsexports-config config))
+    ("lizardfs/mfsgoals.cfg"
+     ,(lizardfs-configuration-mfsgoals-config config))
+    ("lizardfs/mfshdd.cfg"
+     ,(lizardfs-configuration-mfshdd-config config))
+    ("lizardfs/mfsmaster.cfg"
+     ,(lizardfs-configuration-mfsmaster-config config))
+    ("lizardfs/mfsmetalogger.cfg"
+     ,(lizardfs-configuration-mfsmetalogger-config config))
+    ("lizardfs/mfsmount.cfg"
+     ,(lizardfs-configuration-mfsmount-config config))
+    ("lizardfs/mfstopology.cfg"
+     ,(lizardfs-configuration-mfstopology-config config))))
+
+(define (lizardfs-activation config)
+  #~(begin
+      (unless (and (file-exists? "/var/lib/lizardfs/metadata.mfs")
+                   (lizardfs-configuration-run-mfsmetalogger-service config))
+        ;; First run "service".
+        (with-output-to-file "/var/lib/lizardfs/metadata.mfs"
+          (lambda ()
+            (format #t "MFSM NEW"))))
+      #$(plain-file? (lizardfs-configuration-globaliolimits-config config))
+      #$(plain-file? (lizardfs-configuration-iolimits-config config))
+      #$(plain-file? (lizardfs-configuration-mfschunkserver-config config))
+      #$(plain-file? (lizardfs-configuration-mfsexports-config config))
+      #$(plain-file? (lizardfs-configuration-mfsgoals-config config))
+      #$(plain-file? (lizardfs-configuration-mfshdd-config config))
+      #$(plain-file? (lizardfs-configuration-mfsmaster-config config))
+      #$(plain-file? (lizardfs-configuration-mfsmetalogger-config config))
+      #$(plain-file? (lizardfs-configuration-mfsmount-config config))
+      #$(plain-file? (lizardfs-configuration-mfstopology-config config))
+      #t))
+
+(define (lizardfs-services-to-run config)
+  (append (lizardfs-shepherd-service config)
+          (lizardfs-mfschunkserver-shepherd-service config)
+          (if (lizardfs-configuration-run-mfsmetalogger-service config)
+            (lizardfs-mfsmetalogger-shepherd-service config)
+            '())))
+
+(define lizardfs-service-type
+  (service-type
+    (name 'lizardfs)
+    (extensions
+      (list
+        (service-extension shepherd-root-service-type
+                           lizardfs-services-to-run)
+        (service-extension activation-service-type
+                           lizardfs-activation)
+        (service-extension etc-service-type
+                           lizardfs-etc-service)
+        (service-extension account-service-type
+                           (const %lizardfs-accounts))
+        (service-extension profile-service-type
+                           (compose list lizardfs-configuration-package))))
+    (default-value (lizardfs-configuration))
+    (description "")))