Repository: kubernetes-sigs/alibaba-cloud-csi-driver
Pull request #1357: Add cnfs-nas-daemon support in mount-proxy
Author: login: tydra-wang
Labels: name: kind/feature
description: Categorizes issue or PR as related to a new feature.
name: lgtm
description: "Looks good to me", indicates that a PR is ready to be merged.
name: approved
description: Indicates a PR has been approved by an approver from all required OWNERS files.
name: size/L
description: Denotes a PR that changes 100-499 lines, ignoring generated files.
name: cncf-cla: yes
description: Indicates the PR's author has signed the CNCF CLA.
Created: 2025-04-03T01:41:46Z | Merged: 2025-04-11T05:54:41Z

<!--  Thanks for sending a pull request!  Here are some tips for you:

1. If this is your first time, please read our contributor guidelines: https://git.k8s.io/community/contributors/guide/first-contribution.md#your-first-contribution and developer guide https://git.k8s.io/community/contributors/devel/development.md#development-guide
2. Please label this pull request according to what type of issue you are addressing, especially if this is a release targeted pull request. For reference on required PR/issue labels, read here:
https://git.k8s.io/community/contributors/devel/sig-release/release.md#issuepr-kind-label
3. Ensure you have added or ran the appropriate tests for your PR: https://git.k8s.io/community/contributors/devel/sig-testing/testing.md
4. If you want *faster* PR reviews, read how: https://git.k8s.io/community/contributors/guide/pull-requests.md#best-practices-for-faster-reviews
5. If the PR is unfinished, see how to mark it: https://git.k8s.io/community/contributors/guide/pull-requests.md#marking-unfinished-pull-requests
-->

#### What type of PR is this?

<!--
Add one of the following kinds:
/kind bug
/kind cleanup
/kind documentation
/kind feature
/kind design

Optionally add one or more of the following kinds if applicable:
/kind api-change
/kind deprecation
/kind failing-test
/kind flake
/kind regression
-->
/kind feature

#### What this PR does / why we need it:


#### Which issue(s) this PR fixes:
<!--
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
_If PR is about `failing-tests or flakes`, please post the related issues/tests in a comment and do not use `Fixes`_*
-->
Fixes #

#### Special notes for your reviewer:

#### Does this PR introduce a user-facing change?
<!--
If no, just write "NONE" in the release-note block below.
If yes, a release note is required:
Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".

For more information on release notes see: https://git.k8s.io/community/contributors/guide/release-notes.md
-->
```release-note

```

#### Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:

<!--
This section can be blank if this pull request does not require a release note.

When adding links which point to resources within git repositories, like
KEPs or supporting documentation, please reference a specific commit and avoid
linking directly to the master branch. This ensures that links reference a
specific point in time, rather than a document that may change over time.

See here for guidance on getting permanent links to files: https://help.github.com/en/articles/getting-permanent-links-to-files

Please use the following format for linking documentation:
- [KEP]: <link>
- [Usage]: <link>
- [Other doc]: <link>
-->
```docs

```



Diff:
diff --git a/build/mount-proxy/Dockerfile b/build/mount-proxy/Dockerfile
index b132339f9..4ec0757d9 100644
--- a/build/mount-proxy/Dockerfile
+++ b/build/mount-proxy/Dockerfile
@@ -9,6 +9,8 @@ RUN --mount=type=bind,target=. \
     go build -o /out/csi-mount-proxy-server ./cmd/mount-proxy-server && \
     go build -o /out/csi-mount-proxy-client ./cmd/mount-proxy-client
 
+#################### OSSFS 1.91 MOUNT-PROXY IMAGE ####################
+
 FROM registry-cn-hangzhou.ack.aliyuncs.com/dev/alinux:3-update as oss
 ARG TARGETPLATFORM
 ARG OSSFS_VERSION=v1.91.5.ack.1
@@ -30,6 +32,10 @@ RUN ln -s /host/etc/mime.types /etc/mime.types
 COPY --link --from=builder /out/csi-mount-proxy* /usr/local/bin/
 ENTRYPOINT ["csi-mount-proxy-server"]
 
+#################### OSSFS 1.91 MOUNT-PROXY IMAGE ####################
+
+#################### OSSFS 1.88 MOUNT-PROXY IMAGE ####################
+
 FROM registry-cn-hangzhou.ack.aliyuncs.com/dev/alinux:3-update as oss-1.88
 ARG TARGETPLATFORM
 
@@ -60,3 +66,31 @@ RUN ln -s /host/etc/mime.types /etc/mime.types
 COPY --link --from=builder /out/csi-mount-proxy* /usr/local/bin/
 ENTRYPOINT ["csi-mount-proxy-server", "--driver=ossfs"]
 
+#################### OSSFS 1.88 MOUNT-PROXY IMAGE ####################
+
+#################### ALINAS MOUNT-PROXY IMAGE ####################
+
+FROM registry-cn-hangzhou.ack.aliyuncs.com/dev/alinux:3-update as alinas
+
+ARG TARGETPLATFORM
+ARG ALINAS_UTILS_VERSION=1.8-0.20250410201011.30aa55.al7
+ARG EFC_VERSION=1.8-20250226151552.7151bf.release
+RUN set -ex; \
+    case "${TARGETPLATFORM}" in \
+        linux/amd64) ARCH="x86_64" ;; \
+        # linux/arm64) ARCH="aarch_64" ;; \
+        *) echo "unsupported platform"; exit 1 ;; \
+    esac; \
+    yum install -y util-linux procps tini; \
+    yum install -y https://aliyun-alinas-eac.oss-cn-beijing.aliyuncs.com/aliyun-alinas-utils-${ALINAS_UTILS_VERSION}.noarch.rpm; \
+    yum install -y https://aliyun-alinas-eac.oss-cn-beijing.aliyuncs.com/alinas-efc-${EFC_VERSION}.${ARCH}.rpm; \
+    yum clean all
+# alinas-utils generates some dynamic configuration files (such as TLS keys, etc.) under /etc/aliyun/{alinas,cpfs}.
+# So we will mount a hostPath to prevent the loss of these files when the container restarts.
+# On the first launch, /etc/aliyun-defaults will be used to initialize the configurations under /etc/aliyun/{alinas,cpfs}.
+RUN cp -r /etc/aliyun /etc/aliyun-defaults
+
+COPY --link --from=builder /out/csi-mount-proxy* /usr/local/bin/
+ENTRYPOINT [ "tini", "--", "csi-mount-proxy-server", "--driver=alinas" ]
+
+#################### ALINAS MOUNT-PROXY IMAGE ####################
diff --git a/deploy/chart/templates/plugin.yaml b/deploy/chart/templates/plugin.yaml
index d9cc2dc00..8bb38e831 100644
--- a/deploy/chart/templates/plugin.yaml
+++ b/deploy/chart/templates/plugin.yaml
@@ -205,6 +205,8 @@ spec:
 {{- end }}
             - mountPath: /host/run/csi-tool
               name: run-csi
+            - mountPath: /run/cnfs
+              name: run-cnfs
             - mountPath: /host/sys/fs/cgroup
               name: cgroup
               mountPropagation: "HostToContainer"
@@ -316,6 +318,10 @@ spec:
           hostPath:
             path: /run/csi-tool
             type: DirectoryOrCreate
+        - name: run-cnfs
+          hostPath:
+            path: /run/cnfs
+            type: DirectoryOrCreate
 {{- if $nodePool.csi.local.enabled }}
         - name: tls-token-dir
           secret:
diff --git a/pkg/mounter/proxy/server/alinas/driver.go b/pkg/mounter/proxy/server/alinas/driver.go
index 49896f0d5..ee7a84eff 100644
--- a/pkg/mounter/proxy/server/alinas/driver.go
+++ b/pkg/mounter/proxy/server/alinas/driver.go
@@ -2,9 +2,16 @@ package alinas
 
 import (
 	"context"
+	"io"
+	"io/fs"
+	"os"
 	"os/exec"
+	"path/filepath"
+	"strings"
+	"syscall"
 	"time"
 
+	"github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pkg/mounter"
 	"github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pkg/mounter/proxy"
 	"github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pkg/mounter/proxy/server"
 	"k8s.io/apimachinery/pkg/util/wait"
@@ -37,14 +44,18 @@ func (h *Driver) Mount(ctx context.Context, req *proxy.MountRequest) error {
 	klog.InfoS("Mounting", "fstype", req.Fstype, "source", req.Source, "target", req.Target, "options", req.Options)
 	options := append(req.Options, "no_start_watchdog")
 	if req.Fstype == fstypeAlinas {
-		options = append(options, "no_atomic_move", "auto_fallback_nfs")
+		// options = append(options, "no_atomic_move", "auto_fallback_nfs")
+		options = append(options, "no_atomic_move")
+		options = addAutoFallbackNFSMountOptions(options)
 	}
+
 	return h.mounter.Mount(req.Source, req.Target, req.Fstype, options)
 }
 
 func (h *Driver) Init() {
 	go runCommandForever("aliyun-alinas-mount-watchdog")
 	go runCommandForever("aliyun-cpfs-mount-watchdog")
+	setupDefaultConfigs()
 }
 
 func (h *Driver) Terminate() {}
@@ -53,9 +64,89 @@ func runCommandForever(command string, args ...string) {
 	wait.Forever(func() {
 		klog.InfoS("Starting", "command", command)
 		cmd := exec.Command(command, args...)
+		cmd.SysProcAttr = &syscall.SysProcAttr{
+			Setpgid: true,
+		}
 		err := cmd.Run()
 		if err != nil {
 			klog.ErrorS(err, "Exited", "command", command)
 		}
 	}, time.Second)
 }
+
+// addAutoFallbackNFSMountOptions adds auto_fallback_nfs mount option when using efc
+func addAutoFallbackNFSMountOptions(mountOptions []string) []string {
+	for _, options := range mountOptions {
+		for _, option := range mounter.SplitMountOptions(options) {
+			if option == "" {
+				continue
+			}
+			key, _, _ := strings.Cut(option, "=")
+			if key == "efc" {
+				return append(mountOptions, "auto_fallback_nfs")
+			}
+		}
+	}
+	return mountOptions
+}
+
+const (
+	defaultConfigDir = "/etc/aliyun-defaults"
+	configDir        = "/etc/aliyun"
+)
+
+func setupDefaultConfigs() {
+	for _, name := range []string{"cpfs", "alinas"} {
+		srcDir := filepath.Join(defaultConfigDir, name)
+		dstDir := filepath.Join(configDir, name)
+		if err := filepath.WalkDir(srcDir, func(path string, d fs.DirEntry, err error) error {
+			if err != nil {
+				return err
+			}
+
+			if d.IsDir() {
+				return nil
+			}
+
+			relPath, err := filepath.Rel(srcDir, path)
+			if err != nil {
+				return err
+			}
+
+			dstPath := filepath.Join(dstDir, relPath)
+
+			if _, err := os.Stat(dstPath); err == nil {
+				// File already exists, skip
+				return nil
+			} else if !os.IsNotExist(err) {
+				return err
+			}
+
+			klog.InfoS("Copying default config file", "path", dstPath)
+			return copyFile(path, dstPath)
+		}); err != nil {
+			panic(err)
+		}
+	}
+}
+
+func copyFile(src, dst string) error {
+	srcFile, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer srcFile.Close()
+
+	dstFile, err := os.Create(dst)
+	if err != nil {
+		return err
+	}
+	defer dstFile.Close()
+
+	_, err = io.Copy(dstFile, srcFile)
+	if err != nil {
+		return err
+	}
+
+	return dstFile.Sync()
+}


Reviews:
user: login: mowangdk
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T09:13:33Z
user: login: tydra-wang
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-11T03:53:25Z
user: login: tydra-wang
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-11T03:54:23Z

Review comments:
diff_hunk: @@ -60,3 +66,28 @@ RUN ln -s /host/etc/mime.types /etc/mime.types
 COPY --link --from=builder /out/csi-mount-proxy* /usr/local/bin/
 ENTRYPOINT ["csi-mount-proxy-server", "--driver=ossfs"]
 
+#################### OSSFS 1.88 MOUNT-PROXY IMAGE ####################
+
+#################### ALINAS MOUNT-PROXY IMAGE ####################
+
+FROM registry-cn-hangzhou.ack.aliyuncs.com/dev/alinux:3-update as alinas
+
+ARG TARGETPLATFORM
+ARG ALINAS_UTILS_VERSION=1.8-0.20250228140224.8879f0.al7
+ARG EFC_VERSION=1.8-20250226151552.7151bf.release
+RUN set -ex; \
+    case "${TARGETPLATFORM}" in \
+        linux/amd64) ARCH="x86_64" ;; \
+        # linux/arm64) ARCH="aarch_64" ;; \
+        *) echo "unsupported platform"; exit 1 ;; \
+    esac; \
+    yum install -y util-linux procps tini; \
+    yum install -y https://aliyun-alinas-eac.oss-cn-beijing.aliyuncs.com/aliyun-alinas-utils-${ALINAS_UTILS_VERSION}.noarch.rpm; \
+    yum install -y https://aliyun-alinas-eac.oss-cn-beijing.aliyuncs.com/alinas-efc-${EFC_VERSION}.${ARCH}.rpm; \
+    yum clean all
+RUN cp -r /etc/aliyun /etc/aliyun-defaults
path: build/mount-proxy/Dockerfile
user: login: mowangdk
body: What is the purpose of copying the binary?
created_at: 2025-04-10T09:00:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -205,6 +205,8 @@ spec:
 {{- end }}
             - mountPath: /host/run/csi-tool
               name: run-csi
+            - mountPath: /run/cnfs
path: deploy/chart/templates/plugin.yaml
user: login: mowangdk
body: Adding host prefix path(/host) to  align with other host paths.
created_at: 2025-04-10T09:02:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -60,3 +66,28 @@ RUN ln -s /host/etc/mime.types /etc/mime.types
 COPY --link --from=builder /out/csi-mount-proxy* /usr/local/bin/
 ENTRYPOINT ["csi-mount-proxy-server", "--driver=ossfs"]
 
+#################### OSSFS 1.88 MOUNT-PROXY IMAGE ####################
+
+#################### ALINAS MOUNT-PROXY IMAGE ####################
+
+FROM registry-cn-hangzhou.ack.aliyuncs.com/dev/alinux:3-update as alinas
+
+ARG TARGETPLATFORM
+ARG ALINAS_UTILS_VERSION=1.8-0.20250228140224.8879f0.al7
+ARG EFC_VERSION=1.8-20250226151552.7151bf.release
+RUN set -ex; \
+    case "${TARGETPLATFORM}" in \
+        linux/amd64) ARCH="x86_64" ;; \
+        # linux/arm64) ARCH="aarch_64" ;; \
+        *) echo "unsupported platform"; exit 1 ;; \
+    esac; \
+    yum install -y util-linux procps tini; \
+    yum install -y https://aliyun-alinas-eac.oss-cn-beijing.aliyuncs.com/aliyun-alinas-utils-${ALINAS_UTILS_VERSION}.noarch.rpm; \
+    yum install -y https://aliyun-alinas-eac.oss-cn-beijing.aliyuncs.com/alinas-efc-${EFC_VERSION}.${ARCH}.rpm; \
+    yum clean all
+RUN cp -r /etc/aliyun /etc/aliyun-defaults
path: build/mount-proxy/Dockerfile
user: login: mowangdk
body: Add some explaination
created_at: 2025-04-10T09:13:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -205,6 +205,8 @@ spec:
 {{- end }}
             - mountPath: /host/run/csi-tool
               name: run-csi
+            - mountPath: /run/cnfs
path: deploy/chart/templates/plugin.yaml
user: login: tydra-wang
body: You can think of it as similar to /var/lib/kubelet, and it won’t cause conflicts.

If we change this, we’ll also need to update the constant `defaultAlinasMountProxySocket = "/run/cnfs/alinas-mounter.sock"` in the Go code.
created_at: 2025-04-11T03:53:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -60,3 +66,28 @@ RUN ln -s /host/etc/mime.types /etc/mime.types
 COPY --link --from=builder /out/csi-mount-proxy* /usr/local/bin/
 ENTRYPOINT ["csi-mount-proxy-server", "--driver=ossfs"]
 
+#################### OSSFS 1.88 MOUNT-PROXY IMAGE ####################
+
+#################### ALINAS MOUNT-PROXY IMAGE ####################
+
+FROM registry-cn-hangzhou.ack.aliyuncs.com/dev/alinux:3-update as alinas
+
+ARG TARGETPLATFORM
+ARG ALINAS_UTILS_VERSION=1.8-0.20250228140224.8879f0.al7
+ARG EFC_VERSION=1.8-20250226151552.7151bf.release
+RUN set -ex; \
+    case "${TARGETPLATFORM}" in \
+        linux/amd64) ARCH="x86_64" ;; \
+        # linux/arm64) ARCH="aarch_64" ;; \
+        *) echo "unsupported platform"; exit 1 ;; \
+    esac; \
+    yum install -y util-linux procps tini; \
+    yum install -y https://aliyun-alinas-eac.oss-cn-beijing.aliyuncs.com/aliyun-alinas-utils-${ALINAS_UTILS_VERSION}.noarch.rpm; \
+    yum install -y https://aliyun-alinas-eac.oss-cn-beijing.aliyuncs.com/alinas-efc-${EFC_VERSION}.${ARCH}.rpm; \
+    yum clean all
+RUN cp -r /etc/aliyun /etc/aliyun-defaults
path: build/mount-proxy/Dockerfile
user: login: tydra-wang
body: Added to comments
created_at: 2025-04-11T03:54:23Z
author_association: CONTRIBUTOR

PR comments:
user: login: mowangdk
created_at: 2025-04-11T05:53:09Z
body: /lgtm
/approve
author_association: CONTRIBUTOR
user: login: k8s-ci-robot
created_at: 2025-04-11T05:53:15Z
body: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pull/1357#issuecomment-2795899984" title="Approved">mowangdk</a>*, *<a href="https://github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pull/1357#" title="Author self-approved">tydra-wang</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Falibaba-cloud-csi-driver).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes-sigs/alibaba-cloud-csi-driver/blob/master/OWNERS)~~ [mowangdk]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
author_association: CONTRIBUTOR