@@ -162,43 +162,106 @@ func (d *zfs) Info() Info {
162
162
// Accepts warnOnExistingPolicyApplyError argument, if true will warn rather than fail if applying current policy
163
163
// to an existing dataset fails.
164
164
func (d zfs ) ensureInitialDatasets (warnOnExistingPolicyApplyError bool ) error {
165
- args := make ([]string , 0 , len (zfsDefaultSettings ))
165
+ // Build the list of datasets to query.
166
+ datasets := []string {d .config ["zfs.pool_name" ]}
167
+ for _ , entry := range d .initialDatasets () {
168
+ datasets = append (datasets , filepath .Join (d .config ["zfs.pool_name" ], entry ))
169
+ }
170
+
171
+ // Build the list of properties to check.
172
+ props := []string {"name" , "mountpoint" , "volmode" }
173
+ for k := range zfsDefaultSettings {
174
+ props = append (props , k )
175
+ }
176
+
177
+ // Get current state.
178
+ args := append ([]string {"get" , "-H" , "-p" , "-o" , "name,property,value" , strings .Join (props , "," )}, datasets ... )
179
+ output , _ := subprocess .RunCommand ("zfs" , args ... )
180
+
181
+ currentConfig := map [string ]map [string ]string {}
182
+ for _ , entry := range strings .Split (output , "\n " ) {
183
+ if entry == "" {
184
+ continue
185
+ }
186
+
187
+ fields := strings .Fields (entry )
188
+ if len (fields ) != 3 {
189
+ continue
190
+ }
191
+
192
+ if currentConfig [fields [0 ]] == nil {
193
+ currentConfig [fields [0 ]] = map [string ]string {}
194
+ }
195
+
196
+ currentConfig [fields [0 ]][fields [1 ]] = fields [2 ]
197
+ }
198
+
199
+ // Check that the root dataset is correctly configured.
200
+ args = []string {}
166
201
for k , v := range zfsDefaultSettings {
202
+ current := currentConfig [d .config ["zfs.pool_name" ]][k ]
203
+ if current == v {
204
+ continue
205
+ }
206
+
207
+ // Workaround for values having been renamed over time.
208
+ if k == "acltype" && current == "posix" {
209
+ continue
210
+ }
211
+
212
+ if k == "xattr" && current == "on" {
213
+ continue
214
+ }
215
+
167
216
args = append (args , fmt .Sprintf ("%s=%s" , k , v ))
168
217
}
169
218
170
- err := d .setDatasetProperties (d .config ["zfs.pool_name" ], args ... )
171
- if err != nil {
172
- if warnOnExistingPolicyApplyError {
219
+ if len (args ) > 0 {
220
+ err := d .setDatasetProperties (d .config ["zfs.pool_name" ], args ... )
221
+ if err != nil {
222
+ if ! warnOnExistingPolicyApplyError {
223
+ return fmt .Errorf ("Failed applying policy to existing dataset %q: %w" , d .config ["zfs.pool_name" ], err )
224
+ }
225
+
173
226
d .logger .Warn ("Failed applying policy to existing dataset" , logger.Ctx {"dataset" : d .config ["zfs.pool_name" ], "err" : err })
174
- } else {
175
- return fmt .Errorf ("Failed applying policy to existing dataset %q: %w" , d .config ["zfs.pool_name" ], err )
176
227
}
177
228
}
178
229
230
+ // Check the initial datasets.
179
231
for _ , dataset := range d .initialDatasets () {
180
- properties := [ ]string {"mountpoint= legacy" }
232
+ properties := map [ string ]string {"mountpoint" : " legacy" }
181
233
if slices .Contains ([]string {"virtual-machines" , "deleted/virtual-machines" }, dataset ) {
182
- properties = append ( properties , "volmode= none")
234
+ properties [ "volmode" ] = " none"
183
235
}
184
236
185
237
datasetPath := filepath .Join (d .config ["zfs.pool_name" ], dataset )
186
- exists , err := d .datasetExists (datasetPath )
187
- if err != nil {
188
- return err
189
- }
238
+ if currentConfig [datasetPath ] != nil {
239
+ args := []string {}
240
+ for k , v := range properties {
241
+ if currentConfig [datasetPath ][k ] == v {
242
+ continue
243
+ }
244
+
245
+ args = append (args , fmt .Sprintf ("%s=%s" , k , v ))
246
+ }
247
+
248
+ if len (args ) > 0 {
249
+ err := d .setDatasetProperties (datasetPath , args ... )
250
+ if err != nil {
251
+ if ! warnOnExistingPolicyApplyError {
252
+ return fmt .Errorf ("Failed applying policy to existing dataset %q: %w" , datasetPath , err )
253
+ }
190
254
191
- if exists {
192
- err = d .setDatasetProperties (datasetPath , properties ... )
193
- if err != nil {
194
- if warnOnExistingPolicyApplyError {
195
255
d .logger .Warn ("Failed applying policy to existing dataset" , logger.Ctx {"dataset" : datasetPath , "err" : err })
196
- } else {
197
- return fmt .Errorf ("Failed applying policy to existing dataset %q: %w" , datasetPath , err )
198
256
}
199
257
}
200
258
} else {
201
- err = d .createDataset (datasetPath , properties ... )
259
+ args := []string {}
260
+ for k , v := range properties {
261
+ args = append (args , fmt .Sprintf ("%s=%s" , k , v ))
262
+ }
263
+
264
+ err := d .createDataset (datasetPath , args ... )
202
265
if err != nil {
203
266
return fmt .Errorf ("Failed creating dataset %q: %w" , datasetPath , err )
204
267
}
0 commit comments