@@ -231,14 +231,13 @@ func DetachDevice(ctx context.Context, snID string, tenant int) (err error) {
231231}
232232
233233// UnmountAndDetachBlockDevice will do nothing if the device is already destroyed
234- func (o * snapshotter ) UnmountAndDetachBlockDevice (ctx context.Context , snID string ) (err error ) {
234+ func (o * snapshotter ) UnmountAndDetachBlockDevice (ctx context.Context , snID string , key string , upperDirKey string ) (err error ) {
235235 devName , err := os .ReadFile (o .overlaybdBackstoreMarkFile (snID ))
236236 if err != nil {
237237 log .G (ctx ).Errorf ("read device name failed: %s, err: %v" , o .overlaybdBackstoreMarkFile (snID ), err )
238238 }
239239
240240 mountPoint := o .overlaybdMountpoint (snID )
241- log .G (ctx ).Debugf ("check overlaybd mountpoint is in use: %s" , mountPoint )
242241 busy , err := o .checkOverlaybdInUse (ctx , mountPoint )
243242 if err != nil {
244243 return err
@@ -247,6 +246,18 @@ func (o *snapshotter) UnmountAndDetachBlockDevice(ctx context.Context, snID stri
247246 log .G (ctx ).Infof ("device still in use." )
248247 return nil
249248 }
249+
250+ if upperDirKey != "" {
251+ inuse , err := checkIsParent (ctx , key , upperDirKey )
252+ if err != nil {
253+ return fmt .Errorf ("failed to check whether snID %v check key %v err: %v" , snID , key , err )
254+ }
255+ if inuse {
256+ log .G (ctx ).Infof ("device is parent to someone else, ignore umount" )
257+ return nil
258+ }
259+ }
260+
250261 log .G (ctx ).Infof ("umount device, mountpoint: %s" , mountPoint )
251262 if err := mount .UnmountAll (mountPoint , 0 ); err != nil {
252263 return fmt .Errorf ("failed to umount %s: %w" , mountPoint , err )
@@ -257,7 +268,24 @@ func (o *snapshotter) UnmountAndDetachBlockDevice(ctx context.Context, snID stri
257268 }
258269 log .G (ctx ).Infof ("destroy overlaybd device success(sn: %s): %s" , snID , devName )
259270 return nil
271+ }
260272
273+ // checkIsParent checks if the given parent is a parent of any other active snapshot
274+ func checkIsParent (ctx context.Context , key , exclude string ) (bool , error ) {
275+ found := false
276+ if err := storage .WalkInfo (ctx , func (ctx context.Context , info snapshots.Info ) error {
277+ if found {
278+ return nil
279+ }
280+
281+ if info .Name != exclude && info .Parent == key && (info .Kind == snapshots .KindActive || info .Kind == snapshots .KindView ) {
282+ found = true
283+ }
284+ return nil
285+ }); err != nil {
286+ return false , err
287+ }
288+ return found , nil
261289}
262290
263291// IsErofsFilesystem determines whether the block device represented
0 commit comments