(tmpDir string, lowerDirs []string, usernsFd int)
| 250 | } |
| 251 | |
| 252 | func doPrepareIDMappedOverlay(tmpDir string, lowerDirs []string, usernsFd int) (_ []string, _ func(), retErr error) { |
| 253 | commonDir, err := getCommonDirectory(lowerDirs) |
| 254 | if err != nil { |
| 255 | return nil, nil, fmt.Errorf("failed to determine common parent: %w", err) |
| 256 | } |
| 257 | |
| 258 | tempRemountsLocation, err := os.MkdirTemp(tmpDir, "ovl-idmapped") |
| 259 | if err != nil { |
| 260 | return nil, nil, fmt.Errorf("failed to create temporary overlay lowerdir mount location: %w", err) |
| 261 | } |
| 262 | cleanDir := func() { |
| 263 | if err := os.Remove(tempRemountsLocation); err != nil { |
| 264 | log.L.WithError(err).Infof("failed to remove idmapped directory") |
| 265 | } |
| 266 | } |
| 267 | defer func() { |
| 268 | if retErr != nil { |
| 269 | cleanDir() |
| 270 | } |
| 271 | }() |
| 272 | |
| 273 | // IDMapMount the directory containing all the layers |
| 274 | if err := IDMapMountWithAttrs(commonDir, tempRemountsLocation, usernsFd, unix.MOUNT_ATTR_RDONLY, 0); err != nil { |
| 275 | return nil, nil, err |
| 276 | } |
| 277 | |
| 278 | cleanMount := func() { |
| 279 | // Use the Unmount helper that does retries because there can be easily an open fd |
| 280 | // to the idmapped directory and when containerd forks to create a userns fd (maybe |
| 281 | // for another container), it will make the mount busy for a few ms. |
| 282 | err := UnmountRecursive(tempRemountsLocation, 0) |
| 283 | if err != nil { |
| 284 | log.L.WithError(err).Warnf("failed to unmount idmapped directory %s: %v", tempRemountsLocation, err) |
| 285 | } |
| 286 | } |
| 287 | defer func() { |
| 288 | if retErr != nil { |
| 289 | cleanMount() |
| 290 | } |
| 291 | }() |
| 292 | |
| 293 | // Build new lower dir paths through the idmapped directory |
| 294 | tmpLowerDirs := buildIDMappedPaths(lowerDirs, commonDir, tempRemountsLocation) |
| 295 | |
| 296 | cleanup := func() { |
| 297 | cleanMount() |
| 298 | cleanDir() |
| 299 | } |
| 300 | return tmpLowerDirs, cleanup, nil |
| 301 | } |
| 302 | |
| 303 | // getCommonDirectory finds the common directory among the lowerDirs passed in. |
| 304 | // "/" and "." are considered invalid common directories and are treated as error |
searching dependent graphs…