@@ -68,21 +68,45 @@ const (
6868 obdMaxDataAreaMB = 4
6969)
7070
71+ type mountMatcherFunc func (fields []string , separatorIndex int ) bool
72+
7173func (o * snapshotter ) checkOverlaybdInUse (ctx context.Context , dir string ) (bool , error ) {
74+ matcher := func (fields []string , separatorIndex int ) bool {
75+ // ... but in Linux <= 3.9 mounting a cifs with spaces in a share name
76+ // (like "//serv/My Documents") _may_ end up having a space in the last field
77+ // of mountinfo (like "unc=//serv/My Documents"). Since kernel 3.10-rc1, cifs
78+ // option unc= is ignored, so a space should not appear. In here we ignore
79+ // those "extra" fields caused by extra spaces.
80+ fstype := fields [separatorIndex + 1 ]
81+ vfsOpts := fields [separatorIndex + 3 ]
82+ return fstype == "overlay" && strings .Contains (vfsOpts , dir )
83+ }
84+ return o .matchMounts (ctx , matcher )
85+ }
86+
87+ func (o * snapshotter ) isMounted (ctx context.Context , mountpoint string ) (bool , error ) {
88+ matcher := func (fields []string , separatorIndex int ) bool {
89+ mp := fields [4 ]
90+ return path .Clean (mountpoint ) == path .Clean (mp )
91+ }
92+ return o .matchMounts (ctx , matcher )
93+ }
94+
95+ func (o * snapshotter ) matchMounts (ctx context.Context , matcher mountMatcherFunc ) (bool , error ) {
7296 f , err := os .Open ("/proc/self/mountinfo" )
7397 if err != nil {
7498 return false , err
7599 }
76100 defer f .Close ()
77- b , err := o .parseAndCheckMounted (ctx , f , dir )
101+ b , err := o .parseAndCheckMounted (ctx , f , matcher )
78102 if err != nil {
79103 log .G (ctx ).Errorf ("Parsing mounts fields, error: %v" , err )
80104 return false , err
81105 }
82106 return b , nil
83107}
84108
85- func (o * snapshotter ) parseAndCheckMounted (ctx context.Context , r io.Reader , dir string ) (bool , error ) {
109+ func (o * snapshotter ) parseAndCheckMounted (ctx context.Context , r io.Reader , matcher mountMatcherFunc ) (bool , error ) {
86110 s := bufio .NewScanner (r )
87111 for s .Scan () {
88112 if err := s .Err (); err != nil {
@@ -139,21 +163,15 @@ func (o *snapshotter) parseAndCheckMounted(ctx context.Context, r io.Reader, dir
139163 log .G (ctx ).Warnf ("Parsing '%s' failed: not enough fields after a separator" , text )
140164 continue
141165 }
142- // ... but in Linux <= 3.9 mounting a cifs with spaces in a share name
143- // (like "//serv/My Documents") _may_ end up having a space in the last field
144- // of mountinfo (like "unc=//serv/My Documents"). Since kernel 3.10-rc1, cifs
145- // option unc= is ignored, so a space should not appear. In here we ignore
146- // those "extra" fields caused by extra spaces.
147- fstype := fields [i + 1 ]
148- vfsOpts := fields [i + 3 ]
149- if fstype == "overlay" && strings .Contains (vfsOpts , dir ) {
166+
167+ if matcher (fields , i ) {
150168 return true , nil
151169 }
152170 }
153171 return false , nil
154172}
155173
156- // unmountAndDetachBlockDevice
174+ // unmountAndDetachBlockDevice will do nothing if the device is already destroyed
157175func (o * snapshotter ) unmountAndDetachBlockDevice (ctx context.Context , snID string , snKey string ) (err error ) {
158176 devName , err := os .ReadFile (o .overlaybdBackstoreMarkFile (snID ))
159177 if err != nil {
0 commit comments