Skip to content

Commit bc9497f

Browse files
authored
Merge pull request #125 from gman0/backport-123
(Backport #123) automount-reconciler: consult only mount table and cvmfs_talk
2 parents d39df5a + 8bf8e18 commit bc9497f

File tree

1 file changed

+25
-25
lines changed

1 file changed

+25
-25
lines changed

internal/cvmfs/automount/reconciler/reconciler.go

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,9 @@ package mountreconcile
1919
import (
2020
"bytes"
2121
"fmt"
22-
"os"
2322
goexec "os/exec"
2423
"path"
2524
"strings"
26-
"syscall"
2725
"time"
2826

2927
"github.com/cvmfs-contrib/cvmfs-csi/internal/exec"
@@ -42,13 +40,29 @@ type Opts struct {
4240
func RunBlocking(o *Opts) error {
4341
t := time.NewTicker(o.Period)
4442

43+
doReconcile := func() {
44+
log.Tracef("Reconciling /cvmfs")
45+
if err := reconcile(); err != nil {
46+
log.Errorf("Failed to reconcile /cvmfs: %v", err)
47+
}
48+
}
49+
50+
// Run at start so that broken mounts after nodeplugin Pod
51+
// restart are cleaned up.
52+
//
53+
// Known issue with CVMFS v2.11.0: first run of cvmfs_talk
54+
// on corrupted mounts sometimes results in the program exiting
55+
// due to SIGABRT, as a result of a failed assertion:
56+
// (num_bytes >= 0)
57+
// && (static_cast<size_t>(num_bytes) == nbyte)
58+
// This does not trigger reconciliation. On the second retry,
59+
// the command runs normally and the mount is cleaned.
60+
doReconcile()
61+
4562
for {
4663
select {
4764
case <-t.C:
48-
log.Tracef("Reconciling /cvmfs")
49-
if err := reconcile(); err != nil {
50-
log.Errorf("Failed to reconcile /cvmfs: %v", err)
51-
}
65+
doReconcile()
5266
}
5367
}
5468
}
@@ -108,28 +122,14 @@ func repoNeedsUnmount(repo string) (bool, error) {
108122
const cvmfsErrConnRefused = "(111 - Connection refused)\x0A"
109123
const cvmfsErrClientNotRunning = "Seems like CernVM-FS is not running"
110124

111-
if bytes.HasSuffix(out, []byte(cvmfsErrConnRefused)) ||
112-
bytes.HasPrefix(out, []byte(cvmfsErrClientNotRunning)) {
113-
// It seems that the CVMFS client exited.
114-
// Use stat syscall to check for ENOTCONN, i.e. the mount is corrupted,
115-
// confirming what cvmfs_talk returned.
116-
117-
_, err := os.Stat(path.Join(mountPathPrefix, repo))
118-
if err != nil {
119-
if err.(*os.PathError).Err == syscall.ENOTCONN {
120-
return true, nil
121-
}
122-
123-
// It's something else.
124-
return false, fmt.Errorf("unexpected error from stat: %v", err)
125-
}
125+
outputHasKnownErr := bytes.HasSuffix(out, []byte(cvmfsErrConnRefused)) ||
126+
bytes.HasPrefix(out, []byte(cvmfsErrClientNotRunning))
126127

127-
// stat should have failed! Fall through and fail.
128+
if !outputHasKnownErr {
129+
return false, fmt.Errorf("failed to talk to CVMFS client (%v): %s", err, out)
128130
}
129131

130-
// If we got here, the error reported by cvmfs_talk
131-
// is something else and we should fail too.
132-
return false, fmt.Errorf("failed to talk to CVMFS client (%v): %s", err, out)
132+
return true, nil
133133
}
134134

135135
func reconcile() error {

0 commit comments

Comments
 (0)