Skip to content

Commit

Permalink
Windows: add option to startup juicefs as system service. fix #347, l…
Browse files Browse the repository at this point in the history
…ink #1546 (#5643)
  • Loading branch information
chenjie4255 authored Feb 14, 2025
1 parent 61fc5d9 commit 2dd3897
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 2 deletions.
3 changes: 3 additions & 0 deletions cmd/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,9 @@ func mount(c *cli.Context) error {
}
os.Setenv("JFS_SUPERVISOR", strconv.Itoa(os.Getppid()))
return launchMount(mp, vfsConf)
} else if runtime.GOOS == "windows" && c.Bool("background") {
daemonRun(c, addr, vfsConf)
return nil
}
logger.Infof("JuiceFS version %s", version.Version())

Expand Down
8 changes: 6 additions & 2 deletions cmd/mount_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,16 @@ func mountFlags() []cli.Flag {
Name: "delay-close",
Usage: "delay file closing in seconds.",
},
&cli.BoolFlag{
Name: "d",
Aliases: []string{"background"},
Usage: "run in background(Windows: as a system service. support ONLY 1 volume mounting at the same time)",
},
}
}

func makeDaemon(c *cli.Context, conf *vfs.Config) error {
logger.Warnf("Cannot run in background in Windows.")
return nil
return winfsp.RunAsSystemSerivce(conf.Format.Name, c.Args().Get(1))
}

func makeDaemonForSvc(c *cli.Context, m meta.Meta, metaUrl, listenAddr string) error {
Expand Down
69 changes: 69 additions & 0 deletions pkg/winfsp/winfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package winfsp
import (
"fmt"
"os"
"os/exec"
"path"
"runtime"
"strings"
Expand All @@ -35,6 +36,8 @@ import (
"github.com/juicedata/juicefs/pkg/meta"
"github.com/juicedata/juicefs/pkg/utils"
"github.com/juicedata/juicefs/pkg/vfs"

"golang.org/x/sys/windows/registry"
)

var logger = utils.GetLogger("juicefs")
Expand Down Expand Up @@ -669,3 +672,69 @@ func Serve(v *vfs.VFS, fuseOpt string, fileCacheTo float64, asRoot bool, delayCl
logger.Debugf("mount point: %s, options: %s", conf.Meta.MountPoint, options)
_ = host.Mount(conf.Meta.MountPoint, []string{"-o", options})
}

func RunAsSystemSerivce(name string, mountpoint string) error {
// https://winfsp.dev/doc/WinFsp-Service-Architecture/
logger.Info("Running as Windows system service.")

var cmds []string
for _, v := range os.Args[1:] {
if v == "-d" || v == "--background" {
continue
}
cmds = append(cmds, v)
}

cmdLine := strings.Join(cmds, " ")

regKeyPath := "SOFTWARE\\WOW6432Node\\WinFsp\\Services\\juicefs"
k, err := registry.OpenKey(registry.LOCAL_MACHINE, regKeyPath, registry.ALL_ACCESS)
if err != nil {
if err == syscall.ERROR_FILE_NOT_FOUND || err == syscall.ERROR_PATH_NOT_FOUND {
logger.Info("Registry key not found, create it")
k, _, err = registry.CreateKey(registry.LOCAL_MACHINE, regKeyPath, registry.ALL_ACCESS)
if err != nil {
return fmt.Errorf("Failed to create registry key: %s", err)
}
} else {
return fmt.Errorf("Failed to open registry key: %s", err)
}
}
defer k.Close()

err = k.SetStringValue("CommandLine", cmdLine)
if err != nil {
return fmt.Errorf("Failed to set registry key: %s", err)
}

securityDescriptor := "D:P(A;;RPWPLC;;;WD)"
err = k.SetStringValue("Security", securityDescriptor)
if err != nil {
return fmt.Errorf("Failed to set registry key: %s", err)
}

filePath, err := os.Executable()
if err != nil {
return fmt.Errorf("Failed to get current file path: %s", err)
}

err = k.SetStringValue("Executable", filePath)
if err != nil {
return fmt.Errorf("Failed to set registry key: %s", err)
}

err = k.SetDWordValue("JobControl", 1)
if err != nil {
return fmt.Errorf("Failed to set registry key: %s", err)
}

logger.Debug("Starting juicefs service.")
cmd := exec.Command("net", "use", mountpoint, "\\\\juicefs\\"+name)
err = cmd.Run()
if err != nil {
return fmt.Errorf("Failed to mount juicefs: %s", err)
}

logger.Info("Juicefs system service started successfully.")
return nil
}

0 comments on commit 2dd3897

Please sign in to comment.