From 8a77ae81ad4b5d7e398414676fe2d4111c29fc32 Mon Sep 17 00:00:00 2001 From: Michael Raitza Date: Wed, 24 Jan 2018 13:20:47 +0100 Subject: [PATCH 1/6] openafsClient: rename to openafs --- .../services/network-filesystems/openafs-client/default.nix | 2 +- pkgs/servers/{openafs-client => openafs}/default.nix | 0 pkgs/top-level/all-packages.nix | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename pkgs/servers/{openafs-client => openafs}/default.nix (100%) diff --git a/nixos/modules/services/network-filesystems/openafs-client/default.nix b/nixos/modules/services/network-filesystems/openafs-client/default.nix index 0946e379e796..e5f89a9a0d20 100644 --- a/nixos/modules/services/network-filesystems/openafs-client/default.nix +++ b/nixos/modules/services/network-filesystems/openafs-client/default.nix @@ -17,7 +17,7 @@ let echo "/afs:${cfg.cacheDirectory}:${cfg.cacheSize}" > $out/cacheinfo ''; - openafsPkgs = config.boot.kernelPackages.openafsClient; + openafsPkgs = config.boot.kernelPackages.openafs; in { ###### interface diff --git a/pkgs/servers/openafs-client/default.nix b/pkgs/servers/openafs/default.nix similarity index 100% rename from pkgs/servers/openafs-client/default.nix rename to pkgs/servers/openafs/default.nix diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 0123190fa08a..ff3d87cde0a7 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -13022,7 +13022,7 @@ with pkgs; rtlwifi_new = callPackage ../os-specific/linux/rtlwifi_new { }; - openafsClient = callPackage ../servers/openafs-client { }; + openafs = callPackage ../servers/openafs { }; facetimehd = callPackage ../os-specific/linux/facetimehd { }; From 44a4844744d899ce74b57bca1f25e5a4ee19e63d Mon Sep 17 00:00:00 2001 From: Michael Raitza Date: Tue, 23 Jan 2018 19:48:53 +0100 Subject: [PATCH 2/6] openafs: Break into multiple packages with multiple outputs Two packages: - pkgs.linuxPackages.openafs (only kernel module) - pkgs.openafs (client/server programs, manpages, docs) Disable `ncurses` by default - Only needed for debugging tools Introduce but disable `tsmbac` by default - IBM's on-site backup service called Tivoli Storage Manager Backup Client - Make openafs ready to use tsmbac when supplied via local overlay (needs special patching) - TSM is not in nixpkgs due to unclear/unfree licensing. (Binaries need to be modified to work with nixos) --- pkgs/servers/openafs/default.nix | 70 ++++++++++++++++++++++++------- pkgs/servers/openafs/module.nix | 57 +++++++++++++++++++++++++ pkgs/servers/openafs/srcs.nix | 14 +++++++ pkgs/servers/openafs/tsmbac.patch | 62 +++++++++++++++++++++++++++ pkgs/top-level/all-packages.nix | 3 +- 5 files changed, 189 insertions(+), 17 deletions(-) create mode 100644 pkgs/servers/openafs/module.nix create mode 100644 pkgs/servers/openafs/srcs.nix create mode 100644 pkgs/servers/openafs/tsmbac.patch diff --git a/pkgs/servers/openafs/default.nix b/pkgs/servers/openafs/default.nix index 232fb135bd80..3f92299c2a0a 100644 --- a/pkgs/servers/openafs/default.nix +++ b/pkgs/servers/openafs/default.nix @@ -1,23 +1,24 @@ -{ stdenv, fetchurl, fetchgit, which, autoconf, automake, flex, yacc, - kernel, glibc, ncurses, perl, kerberos, fetchpatch }: +{ stdenv, fetchurl, fetchgit, which, autoconf, automake, flex, yacc +, glibc, perl, kerberos, libxslt, docbook_xsl, docbook_xml_dtd_43 +, ncurses # Extra ncurses utilities. Only needed for debugging. +, tsmbac ? null # Tivoli Storage Manager Backup Client from IBM +}: + +with (import ./srcs.nix { inherit fetchurl; }); stdenv.mkDerivation rec { - name = "openafs-${version}-${kernel.version}"; - version = "1.6.22.1"; + name = "openafs-${version}"; + inherit version srcs; - src = fetchurl { - url = "http://www.openafs.org/dl/openafs/${version}/openafs-${version}-src.tar.bz2"; - sha256 = "19nfbksw7b34jc3mxjk7cbz26zg9k5myhzpv2jf0fnmznr47jqaw"; - }; - - nativeBuildInputs = [ autoconf automake flex yacc perl which ] ++ kernel.moduleBuildDependencies; + nativeBuildInputs = [ autoconf automake flex yacc perl which libxslt ]; buildInputs = [ ncurses ]; - hardeningDisable = [ "pic" ]; + patches = stdenv.lib.optional (tsmbac != null) ./tsmbac.patch; + + outputs = [ "out" "dev" "man" "doc" ]; preConfigure = '' - ln -s "${kernel.dev}/lib/modules/"*/build $TMP/linux patchShebangs . for i in `grep -l -R '/usr/\(include\|src\)' .`; do @@ -27,25 +28,62 @@ stdenv.mkDerivation rec { --replace "/usr/src" "$TMP" done + for i in ./doc/xml/{AdminGuide,QuickStartUnix,UserGuide}/*.xml; do + substituteInPlace "''${i}" --replace "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" \ + "${docbook_xml_dtd_43}/xml/dtd/docbook/docbookx.dtd" + done + ./regen.sh ${stdenv.lib.optionalString (kerberos != null) "export KRB5_CONFIG=${kerberos.dev}/bin/krb5-config"} + export AFS_SYSKVERS=26 + configureFlagsArray=( - "--with-linux-kernel-build=$TMP/linux" ${stdenv.lib.optionalString (kerberos != null) "--with-krb5"} - "--sysconfdir=/etc/static" + "--sysconfdir=/etc" + "--localstatedir=/var" + "--disable-kernel-module" + "--disable-fuse-client" + "--with-html-xsl=${docbook_xsl}/share/xml/docbook-xsl/html/chunk.xsl" + ${stdenv.lib.optionalString (tsmbac != null) "--enable-tivoli-tsm"} + ${stdenv.lib.optionalString (ncurses == null) "--disable-gtx"} "--disable-linux-d_splice-alias-extra-iput" ) + '' + stdenv.lib.optionalString (tsmbac != null) '' + export XBSA_CFLAGS="-Dxbsa -DNEW_XBSA -I${tsmbac}/lib64/sample -DXBSA_TSMLIB=\\\"${tsmbac}/lib64/libApiTSM64.so\\\"" + export XBSA_XLIBS="-ldl" + ''; + + buildFlags = [ "all_nolibafs" ]; + + postBuild = '' + for d in doc/xml/{AdminGuide,QuickStartUnix,UserGuide}; do + make -C "''${d}" html + done + ''; + + postInstall = '' + mkdir -p $doc/share/doc/openafs/{AdminGuide,QuickStartUnix,UserGuide} + cp -r doc/{arch,examples,pdf,protocol,txt} README NEWS $doc/share/doc/openafs + for d in AdminGuide QuickStartUnix UserGuide ; do + cp "doc/xml/''${d}"/*.html "$doc/share/doc/openafs/''${d}" + done + + rm -r $out/lib/{openafs,afs,*.a} + rm $out/bin/kpasswd + rm $out/sbin/{kas,kdb,ka-forwarder,kadb_check} + rm $out/libexec/openafs/kaserver + rm $man/share/man/man{1/kpasswd*,5/kaserver*,8/{ka*,kdb*}} ''; meta = with stdenv.lib; { + outputsToInstall = [ "out" "doc" "man" ]; description = "Open AFS client"; homepage = https://www.openafs.org; license = licenses.ipl10; platforms = platforms.linux; - maintainers = [ maintainers.z77z ]; - broken = versionOlder kernel.version "3.18"; + maintainers = [ maintainers.z77z maintainers.spacefrogg ]; }; } diff --git a/pkgs/servers/openafs/module.nix b/pkgs/servers/openafs/module.nix new file mode 100644 index 000000000000..8cd9287a7772 --- /dev/null +++ b/pkgs/servers/openafs/module.nix @@ -0,0 +1,57 @@ +{ stdenv, fetchurl, which, autoconf, automake, flex, yacc +, kernel, glibc, perl }: + +with (import ./srcs.nix { inherit fetchurl; }); + +let + modDestDir = "$out/lib/modules/${kernel.modDirVersion}/extra/openafs"; + kernelBuildDir = "${kernel.dev}/lib/modules/${kernel.modDirVersion}/build"; + +in stdenv.mkDerivation rec { + name = "openafs-${version}-${kernel.version}"; + inherit version src; + + nativeBuildInputs = [ autoconf automake flex perl yacc which ] ++ kernel.moduleBuildDependencies; + + hardeningDisable = [ "pic" ]; + + configureFlags = [ + "--with-linux-kernel-build=${kernelBuildDir}" + "--sysconfdir=/etc" + "--localstatedir=/var" + "--disable-linux-d_splice-alias-extra-iput" + ]; + + preConfigure = '' + patchShebangs . + for i in `grep -l -R '/usr/\(include\|src\)' .`; do + echo "Patch /usr/include and /usr/src in $i" + substituteInPlace $i \ + --replace "/usr/include" "${glibc.dev}/include" \ + --replace "/usr/src" "${kernelBuildDir}" + done + + ./regen.sh -q + + ''; + + buildPhase = '' + make V=1 only_libafs + ''; + + installPhase = '' + mkdir -p ${modDestDir} + cp src/libafs/MODLOAD-*/libafs-${kernel.version}.* ${modDestDir}/libafs.ko + xz -f ${modDestDir}/libafs.ko + ''; + + meta = with stdenv.lib; { + description = "Open AFS client kernel module"; + homepage = https://www.openafs.org; + license = licenses.ipl10; + platforms = platforms.linux; + maintainers = [ maintainers.z77z maintainers.spacefrogg ]; + broken = versionOlder kernel.version "3.18"; + }; + +} diff --git a/pkgs/servers/openafs/srcs.nix b/pkgs/servers/openafs/srcs.nix new file mode 100644 index 000000000000..4f2bb190f854 --- /dev/null +++ b/pkgs/servers/openafs/srcs.nix @@ -0,0 +1,14 @@ +{ fetchurl }: +rec { + version = "1.6.22.1"; + src = fetchurl { + url = "http://www.openafs.org/dl/openafs/${version}/openafs-${version}-src.tar.bz2"; + sha256 = "19nfbksw7b34jc3mxjk7cbz26zg9k5myhzpv2jf0fnmznr47jqaw"; + }; + + srcs = [ src + (fetchurl { + url = "http://www.openafs.org/dl/openafs/${version}/openafs-${version}-doc.tar.bz2"; + sha256 = "1875hn8rvlxj4icja8k6hprxprvp2k1f3iilb15lsafhmfz1scg3"; + })]; +} diff --git a/pkgs/servers/openafs/tsmbac.patch b/pkgs/servers/openafs/tsmbac.patch new file mode 100644 index 000000000000..412765fe8a5b --- /dev/null +++ b/pkgs/servers/openafs/tsmbac.patch @@ -0,0 +1,62 @@ +diff -ru3 openafs-1.6.18.1/acinclude.m4 openafs-1.6.18.1.new/acinclude.m4 +--- openafs-1.6.18.1/acinclude.m4 2016-06-21 17:13:39.000000000 +0200 ++++ openafs-1.6.18.1.new/acinclude.m4 2016-11-02 18:44:30.423039662 +0100 +@@ -1373,45 +1373,7 @@ + + dnl check for tivoli + AC_MSG_CHECKING(for tivoli tsm butc support) +-XBSA_CFLAGS="" +-if test "$enable_tivoli_tsm" = "yes"; then +- XBSADIR1=/usr/tivoli/tsm/client/api/bin/xopen +- XBSADIR2=/opt/tivoli/tsm/client/api/bin/xopen +- XBSADIR3=/usr/tivoli/tsm/client/api/bin/sample +- XBSADIR4=/opt/tivoli/tsm/client/api/bin/sample +- XBSADIR5=/usr/tivoli/tsm/client/api/bin64/sample +- XBSADIR6=/opt/tivoli/tsm/client/api/bin64/sample +- +- if test -r "$XBSADIR3/dsmapifp.h"; then +- XBSA_CFLAGS="-Dxbsa -DNEW_XBSA -I$XBSADIR3" +- XBSA_XLIBS="-ldl" +- AC_MSG_RESULT([yes, $XBSA_CFLAGS]) +- elif test -r "$XBSADIR4/dsmapifp.h"; then +- XBSA_CFLAGS="-Dxbsa -DNEW_XBSA -I$XBSADIR4" +- XBSA_XLIBS="-ldl" +- AC_MSG_RESULT([yes, $XBSA_CFLAGS]) +- elif test -r "$XBSADIR5/dsmapifp.h"; then +- XBSA_CFLAGS="-Dxbsa -DNEW_XBSA -I$XBSADIR5" +- XBSA_XLIBS="-ldl" +- AC_MSG_RESULT([yes, $XBSA_CFLAGS]) +- elif test -r "$XBSADIR6/dsmapifp.h"; then +- XBSA_CFLAGS="-Dxbsa -DNEW_XBSA -I$XBSADIR6" +- XBSA_XLIBS="-ldl" +- AC_MSG_RESULT([yes, $XBSA_CFLAGS]) +- elif test -r "$XBSADIR1/xbsa.h"; then +- XBSA_CFLAGS="-Dxbsa -I$XBSADIR1" +- XBSA_XLIBS="" +- AC_MSG_RESULT([yes, $XBSA_CFLAGS]) +- elif test -r "$XBSADIR2/xbsa.h"; then +- XBSA_CFLAGS="-Dxbsa -I$XBSADIR2" +- XBSA_XLIBS="" +- AC_MSG_RESULT([yes, $XBSA_CFLAGS]) +- else +- AC_MSG_RESULT([no, missing xbsa.h and dsmapifp.h header files]) +- fi +-else +- AC_MSG_RESULT([no]) +-fi ++AC_MSG_RESULT([yes]) + AC_SUBST(XBSA_CFLAGS) + AC_SUBST(XBSA_XLIBS) + +diff -ru3 openafs-1.6.18.1/src/butc/afsxbsa.c openafs-1.6.18.1.new/src/butc/afsxbsa.c +--- openafs-1.6.18.1/src/butc/afsxbsa.c 2016-06-21 17:13:39.000000000 +0200 ++++ openafs-1.6.18.1.new/src/butc/afsxbsa.c 2016-11-02 18:45:10.734662987 +0100 +@@ -651,7 +651,7 @@ + #if defined(AFS_AIX_ENV) + dynlib = dlopen("/usr/lib/libApiDS.a(dsmapish.o)", RTLD_NOW | RTLD_LOCAL | RTLD_MEMBER); + #elif defined (AFS_AMD64_LINUX26_ENV) +- dynlib = dlopen("/usr/lib64/libApiTSM64.so", RTLD_NOW | RTLD_LOCAL); ++ dynlib = dlopen(XBSA_TSMLIB, RTLD_NOW | RTLD_LOCAL); + #elif defined(AFS_SUN5_ENV) || defined(AFS_LINUX26_ENV) + dynlib = dlopen("/usr/lib/libApiDS.so", RTLD_NOW | RTLD_LOCAL); + #else diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index ff3d87cde0a7..94902610c04e 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -12055,6 +12055,7 @@ with pkgs; oauth2_proxy = callPackage ../servers/oauth2_proxy { }; + openafs = callPackage ../servers/openafs { tsmbac = null; ncurses = null; }; openpts = callPackage ../servers/openpts { }; openresty = callPackage ../servers/http/openresty { }; @@ -13022,7 +13023,7 @@ with pkgs; rtlwifi_new = callPackage ../os-specific/linux/rtlwifi_new { }; - openafs = callPackage ../servers/openafs { }; + openafs = callPackage ../servers/openafs/module.nix { }; facetimehd = callPackage ../os-specific/linux/facetimehd { }; From c389d705f3b50d88ec46ad6dccf028efa660edad Mon Sep 17 00:00:00 2001 From: Michael Raitza Date: Wed, 24 Jan 2018 15:09:28 +0100 Subject: [PATCH 3/6] nixos/openafsClient: relocate nixos module --- nixos/modules/module-list.nix | 2 +- .../{openafs-client/default.nix => openafs/client.nix} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename nixos/modules/services/network-filesystems/{openafs-client/default.nix => openafs/client.nix} (100%) diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index e512881765e0..f23b5873b527 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -415,7 +415,7 @@ ./services/network-filesystems/ipfs.nix ./services/network-filesystems/netatalk.nix ./services/network-filesystems/nfsd.nix - ./services/network-filesystems/openafs-client/default.nix + ./services/network-filesystems/openafs/client.nix ./services/network-filesystems/rsyncd.nix ./services/network-filesystems/samba.nix ./services/network-filesystems/tahoe.nix diff --git a/nixos/modules/services/network-filesystems/openafs-client/default.nix b/nixos/modules/services/network-filesystems/openafs/client.nix similarity index 100% rename from nixos/modules/services/network-filesystems/openafs-client/default.nix rename to nixos/modules/services/network-filesystems/openafs/client.nix From ce74e1cc3681b1607822ba84184cde84b057ab32 Mon Sep 17 00:00:00 2001 From: Michael Raitza Date: Wed, 24 Jan 2018 17:28:31 +0100 Subject: [PATCH 4/6] nixos/openafsClient: Extend client service functionality Add a lot of options to the client to make it more usable and compatible with the OpenAFS server module. --- .../network-filesystems/openafs/client.nix | 192 +++++++++++++++--- .../network-filesystems/openafs/lib.nix | 28 +++ 2 files changed, 194 insertions(+), 26 deletions(-) create mode 100644 nixos/modules/services/network-filesystems/openafs/lib.nix diff --git a/nixos/modules/services/network-filesystems/openafs/client.nix b/nixos/modules/services/network-filesystems/openafs/client.nix index e5f89a9a0d20..3826fe3edfd0 100644 --- a/nixos/modules/services/network-filesystems/openafs/client.nix +++ b/nixos/modules/services/network-filesystems/openafs/client.nix @@ -1,7 +1,9 @@ { config, pkgs, lib, ... }: +with import ./lib.nix { inherit lib; }; + let - inherit (lib) mkOption mkIf; + inherit (lib) getBin mkOption mkIf optionalString singleton types; cfg = config.services.openafsClient; @@ -10,14 +12,17 @@ let sha256 = "1197z6c5xrijgf66rhaymnm5cvyg2yiy1i20y4ah4mrzmjx0m7sc"; }; + clientServDB = pkgs.writeText "client-cellServDB-${cfg.cellName}" (mkCellServDB cfg.cellName cfg.cellServDB); + afsConfig = pkgs.runCommand "afsconfig" {} '' mkdir -p $out echo ${cfg.cellName} > $out/ThisCell - cp ${cellServDB} $out/CellServDB - echo "/afs:${cfg.cacheDirectory}:${cfg.cacheSize}" > $out/cacheinfo + cat ${cellServDB} ${clientServDB} > $out/CellServDB + echo "${cfg.mountPoint}:${cfg.cache.directory}:${toString cfg.cache.blocks}" > $out/cacheinfo ''; - openafsPkgs = config.boot.kernelPackages.openafs; + openafsMod = config.boot.kernelPackages.openafs; + openafsBin = lib.getBin pkgs.openafs; in { ###### interface @@ -28,34 +33,136 @@ in enable = mkOption { default = false; + type = types.bool; description = "Whether to enable the OpenAFS client."; }; + afsdb = mkOption { + default = true; + type = types.bool; + description = "Resolve cells via AFSDB DNS records."; + }; + cellName = mkOption { - default = "grand.central.org"; + default = ""; + type = types.str; description = "Cell name."; + example = "grand.central.org"; }; - cacheSize = mkOption { - default = "100000"; - description = "Cache size."; + cellServDB = mkOption { + default = []; + type = with types; listOf (submodule { options = cellServDBConfig; }); + description = '' + This cell's database server records, added to the global + CellServDB. See CellServDB(5) man page for syntax. Ignored when + afsdb is set to true. + ''; + example = '' + [ { ip = "1.2.3.4"; dnsname = "first.afsdb.server.dns.fqdn.org"; } + { ip = "2.3.4.5"; dnsname = "second.afsdb.server.dns.fqdn.org"; } + ] + ''; }; - cacheDirectory = mkOption { - default = "/var/cache/openafs"; - description = "Cache directory."; + cache = { + blocks = mkOption { + default = 100000; + type = types.int; + description = "Cache size in 1KB blocks."; + }; + + chunksize = mkOption { + default = 0; + type = types.ints.between 0 30; + description = '' + Size of each cache chunk given in powers of + 2. 0 resets the chunk size to its default + values (13 (8 KB) for memcache, 18-20 (256 KB to 1 MB) for + diskcache). Maximum value is 30. Important performance + parameter. Set to higher values when dealing with large files. + ''; + }; + + directory = mkOption { + default = "/var/cache/openafs"; + type = types.str; + description = "Cache directory."; + }; + + diskless = mkOption { + default = false; + type = types.bool; + description = '' + Use in-memory cache for diskless machines. Has no real + performance benefit anymore. + ''; + }; }; crypt = mkOption { - default = false; + default = true; + type = types.bool; description = "Whether to enable (weak) protocol encryption."; }; - sparse = mkOption { + daemons = mkOption { + default = 2; + type = types.int; + description = '' + Number of daemons to serve user requests. Numbers higher than 6 + usually do no increase performance. Default is sufficient for up + to five concurrent users. + ''; + }; + + fakestat = mkOption { default = false; + type = types.bool; + description = '' + Return fake data on stat() calls. If true, + always do so. If false, only do so for + cross-cell mounts (as these are potentially expensive). + ''; + }; + + inumcalc = mkOption { + default = "compat"; + type = types.strMatching "compat|md5"; + description = '' + Inode calculation method. compat is + computationally less expensive, but md5 greatly + reduces the likelihood of inode collisions in larger scenarios + involving multiple cells mounted into one AFS space. + ''; + }; + + mountPoint = mkOption { + default = "/afs"; + type = types.str; + description = '' + Mountpoint of the AFS file tree, conventionally + /afs. When set to a different value, only + cross-cells that use the same value can be accessed. + ''; + }; + + sparse = mkOption { + default = true; + type = types.bool; description = "Minimal cell list in /afs."; }; + startDisconnected = mkOption { + default = false; + type = types.bool; + description = '' + Start up in disconnected mode. You need to execute + fs disco online (as root) to switch to + connected mode. Useful for roaming devices. + ''; + }; + }; }; @@ -64,26 +171,58 @@ in config = mkIf cfg.enable { - environment.systemPackages = [ openafsPkgs ]; - - environment.etc = [ - { source = afsConfig; - target = "openafs"; + assertions = [ + { assertion = cfg.afsdb || cfg.cellServDB != []; + message = "You should specify all cell-local database servers in config.services.openafsClient.cellServDB or set config.services.openafsClient.afsdb."; + } + { assertion = cfg.cellName != ""; + message = "You must specify the local cell name in config.services.openafsClient.cellName."; } ]; + environment.systemPackages = [ pkgs.openafs ]; + + environment.etc = { + clientCellServDB = { + source = pkgs.runCommand "CellServDB" {} '' + cat ${cellServDB} ${clientServDB} > $out + ''; + target = "openafs/CellServDB"; + mode = "0644"; + }; + clientCell = { + text = '' + ${cfg.cellName} + ''; + target = "openafs/ThisCell"; + mode = "0644"; + }; + }; + systemd.services.afsd = { description = "AFS client"; wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; + after = singleton (if cfg.startDisconnected then "network.target" else "network-online.target"); serviceConfig = { RemainAfterExit = true; }; + restartIfChanged = false; preStart = '' - mkdir -p -m 0755 /afs - mkdir -m 0700 -p ${cfg.cacheDirectory} - ${pkgs.kmod}/bin/insmod ${openafsPkgs}/lib/openafs/libafs-*.ko || true - ${openafsPkgs}/sbin/afsd -confdir ${afsConfig} -cachedir ${cfg.cacheDirectory} ${if cfg.sparse then "-dynroot-sparse" else "-dynroot"} -fakestat -afsdb - ${openafsPkgs}/bin/fs setcrypt ${if cfg.crypt then "on" else "off"} + mkdir -p -m 0755 ${cfg.mountPoint} + mkdir -m 0700 -p ${cfg.cache.directory} + ${pkgs.kmod}/bin/insmod ${openafsMod}/lib/modules/*/extra/openafs/libafs.ko.xz + ${openafsBin}/sbin/afsd \ + -mountdir ${cfg.mountPoint} \ + -confdir ${afsConfig} \ + ${optionalString (!cfg.cache.diskless) "-cachedir ${cfg.cache.directory}"} \ + -blocks ${toString cfg.cache.blocks} \ + -chunksize ${toString cfg.cache.chunksize} \ + ${optionalString cfg.cache.diskless "-memcache"} \ + -inumcalc ${cfg.inumcalc} \ + ${if cfg.fakestat then "-fakestat-all" else "-fakestat"} \ + ${if cfg.sparse then "-dynroot-sparse" else "-dynroot"} \ + ${optionalString cfg.afsdb "-afsdb"} + ${openafsBin}/bin/fs setcrypt ${if cfg.crypt then "on" else "off"} + ${optionalString cfg.startDisconnected "${openafsBin}/bin/fs discon offline"} ''; # Doing this in preStop, because after these commands AFS is basically @@ -91,8 +230,9 @@ in # postStop, then we get a hang + kernel oops, because AFS can't be # stopped simply by sending signals to processes. preStop = '' - ${pkgs.utillinux}/bin/umount /afs - ${openafsPkgs}/sbin/afsd -shutdown + ${pkgs.utillinux}/bin/umount ${cfg.mountPoint} + ${openafsBin}/sbin/afsd -shutdown + ${pkgs.kmod}/sbin/rmmod libafs ''; }; }; diff --git a/nixos/modules/services/network-filesystems/openafs/lib.nix b/nixos/modules/services/network-filesystems/openafs/lib.nix new file mode 100644 index 000000000000..ecfc72d2eaf9 --- /dev/null +++ b/nixos/modules/services/network-filesystems/openafs/lib.nix @@ -0,0 +1,28 @@ +{ lib, ...}: + +let + inherit (lib) concatStringsSep mkOption types; + +in rec { + + mkCellServDB = cellName: db: '' + >${cellName} + '' + (concatStringsSep "\n" (map (dbm: if (dbm.ip != "" && dbm.dnsname != "") then dbm.ip + " #" + dbm.dnsname else "") + db)); + + # CellServDB configuration type + cellServDBConfig = { + ip = mkOption { + type = types.str; + default = ""; + example = "1.2.3.4"; + description = "IP Address of a database server"; + }; + dnsname = mkOption { + type = types.str; + default = ""; + example = "afs.example.org"; + description = "DNS full-qualified domain name of a database server"; + }; + }; +} From d0ebdbd3085973daf45185a226ce9072092862c1 Mon Sep 17 00:00:00 2001 From: Michael Raitza Date: Wed, 24 Jan 2018 18:32:33 +0100 Subject: [PATCH 5/6] nixos/openafsServer: OpenAFS server nixos module --- nixos/modules/module-list.nix | 1 + .../network-filesystems/openafs/server.nix | 260 ++++++++++++++++++ 2 files changed, 261 insertions(+) create mode 100644 nixos/modules/services/network-filesystems/openafs/server.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index f23b5873b527..3c55952b0b22 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -416,6 +416,7 @@ ./services/network-filesystems/netatalk.nix ./services/network-filesystems/nfsd.nix ./services/network-filesystems/openafs/client.nix + ./services/network-filesystems/openafs/server.nix ./services/network-filesystems/rsyncd.nix ./services/network-filesystems/samba.nix ./services/network-filesystems/tahoe.nix diff --git a/nixos/modules/services/network-filesystems/openafs/server.nix b/nixos/modules/services/network-filesystems/openafs/server.nix new file mode 100644 index 000000000000..429eb945ac9e --- /dev/null +++ b/nixos/modules/services/network-filesystems/openafs/server.nix @@ -0,0 +1,260 @@ +{ config, pkgs, lib, ... }: + +with import ./lib.nix { inherit lib; }; + +let + inherit (lib) concatStringsSep intersperse mapAttrsToList mkForce mkIf mkMerge mkOption optionalString types; + + bosConfig = pkgs.writeText "BosConfig" ('' + restrictmode 1 + restarttime 16 0 0 0 0 + checkbintime 3 0 5 0 0 + '' + (optionalString cfg.roles.database.enable '' + bnode simple vlserver 1 + parm ${openafsBin}/libexec/openafs/vlserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} ${cfg.roles.database.vlserverArgs} + end + bnode simple ptserver 1 + parm ${openafsBin}/libexec/openafs/ptserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} ${cfg.roles.database.ptserverArgs} + end + '') + (optionalString cfg.roles.fileserver.enable '' + bnode dafs dafs 1 + parm ${openafsBin}/libexec/openafs/dafileserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} -udpsize ${udpSizeStr} ${cfg.roles.fileserver.fileserverArgs} + parm ${openafsBin}/libexec/openafs/davolserver ${optionalString cfg.dottedPrincipals "-allow-dotted-principals"} -udpsize ${udpSizeStr} ${cfg.roles.fileserver.volserverArgs} + parm ${openafsBin}/libexec/openafs/salvageserver ${cfg.roles.fileserver.salvageserverArgs} + parm ${openafsBin}/libexec/openafs/dasalvager ${cfg.roles.fileserver.salvagerArgs} + end + '') + (optionalString (cfg.roles.database.enable && cfg.roles.backup.enable) '' + bnode simple buserver 1 + parm ${openafsBin}/libexec/openafs/buserver ${cfg.roles.backup.buserverArgs} ${optionalString (cfg.roles.backup.cellServDB != []) "-cellservdb /etc/openafs/backup/"} + end + '')); + + netInfo = if (cfg.advertisedAddresses != []) then + pkgs.writeText "NetInfo" ((concatStringsSep "\nf " cfg.advertisedAddresses) + "\n") + else null; + + buCellServDB = pkgs.writeText "backup-cellServDB-${cfg.cellName}" (mkCellServDB cfg.cellName cfg.roles.backup.cellServDB); + + cfg = config.services.openafsServer; + + udpSizeStr = toString cfg.udpPacketSize; + + openafsBin = lib.getBin pkgs.openafs; + +in { + + options = { + + services.openafsServer = { + + enable = mkOption { + default = false; + type = types.bool; + description = '' + Whether to enable the OpenAFS server. An OpenAFS server needs a + complex setup. So, be aware that enabling this service and setting + some options does not give you a turn-key-ready solution. You need + at least a running Kerberos 5 setup, as OpenAFS relies on it for + authentication. See the Guide "QuickStartUnix" coming with + pkgs.openafs.doc for complete setup + instructions. + ''; + }; + + advertisedAddresses = mkOption { + default = []; + description = "List of IP addresses this server is advertised under. See NetInfo(5)"; + }; + + cellName = mkOption { + default = ""; + type = types.str; + description = "Cell name, this server will serve."; + example = "grand.central.org"; + }; + + cellServDB = mkOption { + default = []; + type = with types; listOf (submodule [ { options = cellServDBConfig;} ]); + description = "Definition of all cell-local database server machines."; + }; + + roles = { + fileserver = { + enable = mkOption { + default = true; + type = types.bool; + description = "Fileserver role, serves files and volumes from its local storage."; + }; + + fileserverArgs = mkOption { + default = "-vattachpar 128 -vhashsize 11 -L -rxpck 400 -cb 1000000"; + type = types.str; + description = "Arguments to the dafileserver process. See its man page."; + }; + + volserverArgs = mkOption { + default = ""; + type = types.str; + description = "Arguments to the davolserver process. See its man page."; + example = "-sync never"; + }; + + salvageserverArgs = mkOption { + default = ""; + type = types.str; + description = "Arguments to the salvageserver process. See its man page."; + example = "-showlog"; + }; + + salvagerArgs = mkOption { + default = ""; + type = types.str; + description = "Arguments to the dasalvager process. See its man page."; + example = "-showlog -showmounts"; + }; + }; + + database = { + enable = mkOption { + default = true; + type = types.bool; + description = '' + Database server role, maintains the Volume Location Database, + Protection Database (and Backup Database, see + backup role). There can be multiple + servers in the database role for replication, which then need + reliable network connection to each other. + + Servers in this role appear in AFSDB DNS records or the + CellServDB. + ''; + }; + + vlserverArgs = mkOption { + default = ""; + type = types.str; + description = "Arguments to the vlserver process. See its man page."; + example = "-rxbind"; + }; + + ptserverArgs = mkOption { + default = ""; + type = types.str; + description = "Arguments to the ptserver process. See its man page."; + example = "-restricted -default_access S---- S-M---"; + }; + }; + + backup = { + enable = mkOption { + default = false; + type = types.bool; + description = '' + Backup server role. Use in conjunction with the + database role to maintain the Backup + Database. Normally only used in conjunction with tape storage + or IBM's Tivoli Storage Manager. + ''; + }; + + buserverArgs = mkOption { + default = ""; + type = types.str; + description = "Arguments to the buserver process. See its man page."; + example = "-p 8"; + }; + + cellServDB = mkOption { + default = []; + type = with types; listOf (submodule [ { options = cellServDBConfig;} ]); + description = '' + Definition of all cell-local backup database server machines. + Use this when your cell uses less backup database servers than + other database server machines. + ''; + }; + }; + }; + + dottedPrincipals= mkOption { + default = false; + type = types.bool; + description = '' + If enabled, allow principal names containing (.) dots. Enabling + this has security implications! + ''; + }; + + udpPacketSize = mkOption { + default = 1310720; + type = types.int; + description = '' + UDP packet size to use in Bytes. Higher values can speed up + communications. The default of 1 MB is a sufficient in most + cases. Make sure to increase the kernel's UDP buffer size + accordingly via net.core(w|r|opt)mem_max + sysctl. + ''; + }; + + }; + + }; + + config = mkIf cfg.enable { + + assertions = [ + { assertion = cfg.cellServDB != []; + message = "You must specify all cell-local database servers in config.services.openafsServer.cellServDB."; + } + { assertion = cfg.cellName != ""; + message = "You must specify the local cell name in config.services.openafsServer.cellName."; + } + ]; + + environment.systemPackages = [ pkgs.openafs ]; + + environment.etc = { + bosConfig = { + source = bosConfig; + target = "openafs/BosConfig"; + mode = "0644"; + }; + cellServDB = { + text = mkCellServDB cfg.cellName cfg.cellServDB; + target = "openafs/server/CellServDB"; + mode = "0644"; + }; + thisCell = { + text = cfg.cellName; + target = "openafs/server/ThisCell"; + mode = "0644"; + }; + buCellServDB = { + enable = (cfg.roles.backup.cellServDB != []); + text = mkCellServDB cfg.cellName cfg.roles.backup.cellServDB; + target = "openafs/backup/CellServDB"; + }; + }; + + systemd.services = { + openafs-server = { + description = "OpenAFS server"; + after = [ "syslog.target" "network.target" ]; + wantedBy = [ "multi-user.target" ]; + restartIfChanged = false; + unitConfig.ConditionPathExists = [ "/etc/openafs/server/rxkad.keytab" ]; + preStart = '' + mkdir -m 0755 -p /var/openafs + ${optionalString (netInfo != null) "cp ${netInfo} /var/openafs/netInfo"} + ${optionalString (cfg.roles.backup.cellServDB != []) "cp ${buCellServDB}"} + ''; + serviceConfig = { + ExecStart = "${openafsBin}/bin/bosserver -nofork"; + ExecStop = "${openafsBin}/bin/bos shutdown localhost -wait -localauth"; + }; + }; + }; + }; +} From eca3e88e6343a8a0ac69652e9dcb10ac0cbd6690 Mon Sep 17 00:00:00 2001 From: Michael Raitza Date: Tue, 6 Feb 2018 14:12:36 +0100 Subject: [PATCH 6/6] openafs: 1.6.22.1 -> 1.6.22.2 Minor update. Adds support for linux kernel up to 4.15. --- pkgs/servers/openafs/srcs.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/servers/openafs/srcs.nix b/pkgs/servers/openafs/srcs.nix index 4f2bb190f854..9e9ff623e5cd 100644 --- a/pkgs/servers/openafs/srcs.nix +++ b/pkgs/servers/openafs/srcs.nix @@ -1,14 +1,14 @@ { fetchurl }: rec { - version = "1.6.22.1"; + version = "1.6.22.2"; src = fetchurl { url = "http://www.openafs.org/dl/openafs/${version}/openafs-${version}-src.tar.bz2"; - sha256 = "19nfbksw7b34jc3mxjk7cbz26zg9k5myhzpv2jf0fnmznr47jqaw"; + sha256 = "15j17igignsfzv5jb47ryczsrz3zsmiqwnj38dx9gzz95807rkyf"; }; srcs = [ src (fetchurl { url = "http://www.openafs.org/dl/openafs/${version}/openafs-${version}-doc.tar.bz2"; - sha256 = "1875hn8rvlxj4icja8k6hprxprvp2k1f3iilb15lsafhmfz1scg3"; + sha256 = "1lpydca95nx5pmqvplb9n3akmxbzvhhypswh0s589ywxpv3zynxm"; })]; }