diff --git a/README.md b/README.md index d01b95d53..c231c5174 100755 --- a/README.md +++ b/README.md @@ -92,11 +92,13 @@ The general format of the Cloudfuse Linux commands is `cloudfuse [command] [argu * `mount all` - Mounts all the containers in an S3 Account or Azure account supported by mount - Example: cloudfuse mount all \ --config-file=\ * `mount list` - Lists all Cloudfuse filesystems. - - cloudfuse mount list + - Example: cloudfuse mount list * `unmount` - Unmounts the Cloudfuse filesystem. - - Example: cloudfuse unmount \ + - Add "--lazy" (or "-z") flag to use lazy unmount (prevents busy errors) + - Example: cloudfuse unmount --lazy \ * `unmount all` - Unmounts all Cloudfuse filesystems. - - Example: cloudfuse unmount all + - Add "--lazy" (or "-z") flag to use lazy unmount (prevents busy errors) + - Example: cloudfuse unmount all --lazy ### Windows: diff --git a/cmd/unmount_all_linux.go b/cmd/unmount_all_linux.go index df2dd8fbc..085e86a73 100644 --- a/cmd/unmount_all_linux.go +++ b/cmd/unmount_all_linux.go @@ -42,19 +42,24 @@ var umntAllCmd = &cobra.Command{ Long: "Unmount all instances of Cloudfuse. Only available on Linux", SuggestFor: []string{"al", "all"}, FlagErrorHandling: cobra.ExitOnError, - RunE: func(_ *cobra.Command, _ []string) error { + RunE: func(cmd *cobra.Command, _ []string) error { lstMnt, err := common.ListMountPoints() if err != nil { return fmt.Errorf("failed to list mount points [%s]", err.Error()) } + lazy, err := cmd.Flags().GetBool("lazy") + if err != nil { + lazy = false + } + mountfound := 0 unmounted := 0 errMsg := "failed to unmount - \n" for _, mntPath := range lstMnt { mountfound += 1 - err := unmountCloudfuse(mntPath) + err := unmountCloudfuse(mntPath, lazy) if err == nil { unmounted += 1 } else { diff --git a/cmd/unmount_linux.go b/cmd/unmount_linux.go index 8430550ed..5cd6247e0 100644 --- a/cmd/unmount_linux.go +++ b/cmd/unmount_linux.go @@ -47,7 +47,11 @@ var unmountCmd = &cobra.Command{ SuggestFor: []string{"unmount", "unmnt"}, Args: cobra.ExactArgs(1), FlagErrorHandling: cobra.ExitOnError, - RunE: func(_ *cobra.Command, args []string) error { + RunE: func(cmd *cobra.Command, args []string) error { + lazy, err := cmd.Flags().GetBool("lazy") + if err != nil { + lazy = false + } if strings.Contains(args[0], "*") { mntPathPrefix := args[0] @@ -55,14 +59,14 @@ var unmountCmd = &cobra.Command{ for _, mntPath := range lstMnt { match, _ := regexp.MatchString(mntPathPrefix, mntPath) if match { - err := unmountCloudfuse(mntPath) + err := unmountCloudfuse(mntPath, lazy) if err != nil { return fmt.Errorf("failed to unmount %s [%s]", mntPath, err.Error()) } } } } else { - err := unmountCloudfuse(args[0]) + err := unmountCloudfuse(args[0], lazy) if err != nil { return err } @@ -80,13 +84,18 @@ var unmountCmd = &cobra.Command{ } // Attempts to unmount the directory and returns true if the operation succeeded -func unmountCloudfuse(mntPath string) error { +func unmountCloudfuse(mntPath string, lazy bool) error { unmountCmd := []string{"fusermount3", "fusermount"} var errb bytes.Buffer var err error for _, umntCmd := range unmountCmd { - cliOut := exec.Command(umntCmd, "-u", mntPath) + var args []string + if lazy { + args = append(args, "-z") + } + args = append(args, "-u", mntPath) + cliOut := exec.Command(umntCmd, args...) cliOut.Stderr = &errb _, err = cliOut.Output() @@ -106,5 +115,6 @@ func unmountCloudfuse(mntPath string) error { func init() { rootCmd.AddCommand(unmountCmd) + unmountCmd.PersistentFlags().BoolP("lazy", "z", false, "Use lazy unmount") unmountCmd.AddCommand(umntAllCmd) } diff --git a/cmd/unmount_linux_test.go b/cmd/unmount_linux_test.go index a04063a39..433d06b4e 100644 --- a/cmd/unmount_linux_test.go +++ b/cmd/unmount_linux_test.go @@ -100,6 +100,40 @@ func (suite *unmountTestSuite) TestUnmountCmd() { suite.assert.Nil(err) } +func (suite *unmountTestSuite) TestUnmountCmdLazy() { + defer suite.cleanupTest() + + lazyFlags := []string{"--lazy", "-z"} + flagBeforePath := false + flagAfterPath := !flagBeforePath + possibleFlagPositions := []bool{flagBeforePath, flagAfterPath} + baseCommand := "unmount" + + for _, lazyFlag := range lazyFlags { + for _, flagPosition := range possibleFlagPositions { + mountDirectory1, _ := os.MkdirTemp("", "TestUnMountTemp") + os.MkdirAll(mountDirectory1, 0777) + defer os.RemoveAll(mountDirectory1) + + cmd := exec.Command("../cloudfuse", "mount", mountDirectory1, fmt.Sprintf("--config-file=%s", confFileUnMntTest)) + _, err := cmd.Output() + suite.assert.Nil(err) + + time.Sleep(time.Second) + + args := []string{baseCommand} + if flagPosition == flagBeforePath { + args = append(args, lazyFlag, mountDirectory1) + } else { + args = append(args, mountDirectory1, lazyFlag) + } + + _, err = executeCommandC(rootCmd, args...) + suite.assert.Nil(err) + } + } +} + func (suite *unmountTestSuite) TestUnmountCmdFail() { defer suite.cleanupTest() diff --git a/gui/mountPrimaryWindow.py b/gui/mountPrimaryWindow.py index fb25c2805..77babd48c 100644 --- a/gui/mountPrimaryWindow.py +++ b/gui/mountPrimaryWindow.py @@ -185,7 +185,7 @@ def unmountBucket(self): else: # Create the mount command to send to subprocess. If shell=True is set and the command is not in one string # the subprocess will interpret the additional arguments as separate commands. - cmd = "./cloudfuse unmount " + directory + cmd = "./cloudfuse unmount --lazy " + directory unmount = subprocess.run([cmd], shell=True, capture_output=True) # Print to the text edit window the results of the unmount