1 { config, lib, pkgs, ...} :
3 cfg = config.services.orangefs.server;
5 aliases = lib.mapAttrsToList (alias: url: alias) cfg.servers;
7 # Maximum handle number is 2^63
8 maxHandle = 9223372036854775806;
10 # One range of handles for each meta/data instance
11 handleStep = maxHandle / (lib.length aliases) / 2;
13 fileSystems = lib.mapAttrsToList (name: fs: ''
17 RootHandle ${toString fs.rootHandle}
22 ${lib.concatStringsSep "\n" (
25 begin = i * handleStep + 3;
26 end = begin + handleStep - 1;
27 in "Range ${alias} ${toString begin}-${toString end}") aliases
32 ${lib.concatStringsSep "\n" (
35 begin = i * handleStep + 3 + (lib.length aliases) * handleStep;
36 end = begin + handleStep - 1;
37 in "Range ${alias} ${toString begin}-${toString end}") aliases
42 TroveSyncMeta ${if fs.troveSyncMeta then "yes" else "no"}
43 TroveSyncData ${if fs.troveSyncData then "yes" else "no"}
44 ${fs.extraStorageHints}
52 LogType ${cfg.logType}
53 DataStorageSpace ${cfg.dataStorageSpace}
54 MetaDataStorageSpace ${cfg.metadataStorageSpace}
56 BMIModules ${lib.concatStringsSep "," cfg.BMIModules}
63 ${lib.concatStringsSep "\n" (lib.mapAttrsToList (alias: url: "Alias ${alias} ${url}") cfg.servers)}
66 ${lib.concatStringsSep "\n" fileSystems}
73 services.orangefs.server = {
74 enable = lib.mkEnableOption "OrangeFS server";
76 logType = lib.mkOption {
77 type = with lib.types; enum [ "file" "syslog" ];
79 description = "Destination for log messages.";
82 dataStorageSpace = lib.mkOption {
83 type = lib.types.nullOr lib.types.str;
85 example = "/data/storage";
86 description = "Directory for data storage.";
89 metadataStorageSpace = lib.mkOption {
90 type = lib.types.nullOr lib.types.str;
92 example = "/data/meta";
93 description = "Directory for meta data storage.";
96 BMIModules = lib.mkOption {
97 type = with lib.types; listOf str;
98 default = [ "bmi_tcp" ];
99 example = [ "bmi_tcp" "bmi_ib"];
100 description = "List of BMI modules to load.";
103 extraDefaults = lib.mkOption {
104 type = lib.types.lines;
106 description = "Extra config for `<Defaults>` section.";
109 extraConfig = lib.mkOption {
110 type = lib.types.lines;
112 description = "Extra config for the global section.";
115 servers = lib.mkOption {
116 type = with lib.types; attrsOf lib.types.str;
119 node1 = "tcp://node1:3334";
120 node2 = "tcp://node2:3334";
122 description = "URLs for storage server including port. The attribute names define the server alias.";
125 fileSystems = lib.mkOption {
127 These options will create the `<FileSystem>` sections of config file.
129 default = { orangefs = {}; };
130 example = lib.literalExpression ''
141 type = with lib.types; attrsOf (submodule ({ ... } : {
144 type = lib.types.int;
146 description = "File system ID (must be unique within configuration).";
149 rootHandle = lib.mkOption {
150 type = lib.types.int;
152 description = "File system root ID.";
155 extraConfig = lib.mkOption {
156 type = lib.types.lines;
158 description = "Extra config for `<FileSystem>` section.";
161 troveSyncMeta = lib.mkOption {
162 type = lib.types.bool;
164 description = "Sync meta data.";
167 troveSyncData = lib.mkOption {
168 type = lib.types.bool;
170 description = "Sync data.";
173 extraStorageHints = lib.mkOption {
174 type = lib.types.lines;
176 description = "Extra config for `<StorageHints>` section.";
184 ###### implementation
186 config = lib.mkIf cfg.enable {
187 environment.systemPackages = [ pkgs.orangefs ];
189 # orangefs daemon will run as user
190 users.users.orangefs = {
194 users.groups.orangefs = {};
196 # To format the file system the config file is needed.
197 environment.etc."orangefs/server.conf" = {
203 systemd.services.orangefs-server = {
204 wantedBy = [ "multi-user.target" ];
205 requires = [ "network-online.target" ];
206 after = [ "network-online.target" ];
209 # Run as "simple" in foreground mode.
210 # This is more reliable
212 ${pkgs.orangefs}/bin/pvfs2-server -d \
213 /etc/orangefs/server.conf
215 TimeoutStopSec = "120";