Skip to content

Commit 67ed8aa

Browse files
committed
Refactor: pull out mounting logic into separated function on podcvd
1 parent 88275bf commit 67ed8aa

1 file changed

Lines changed: 69 additions & 60 deletions

File tree

  • container/src/podcvd/internal

container/src/podcvd/internal/host.go

Lines changed: 69 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,56 @@ func cvdDataHome() (string, error) {
130130
}
131131
return "", fmt.Errorf("failed to find cvd data home dir")
132132
}
133+
134+
func resolveHostPath(path string) string {
135+
if strings.TrimSpace(path) == "" {
136+
return ""
137+
}
138+
absPath, err := filepath.Abs(path)
139+
if err != nil {
140+
return ""
141+
}
142+
if _, err := os.Stat(absPath); err != nil {
143+
return ""
144+
}
145+
if strings.HasPrefix(absPath, "/dev/") || strings.HasPrefix(absPath, "/sys/") || strings.HasPrefix(absPath, "/proc/") {
146+
return ""
147+
}
148+
return absPath
149+
}
150+
151+
func collectMountSpecs(pathsToMount []string, hostOut, productOut, cvdDataHome, podcvdHomeDir string) []string {
152+
bindMap := make(map[string]string)
153+
bindMap["/host_out"] = fmt.Sprintf("%s:/host_out:O", hostOut)
154+
bindMap["/product_out"] = fmt.Sprintf("%s:/product_out:O", productOut)
155+
bindMap["/root/.local/share/cvd"] = fmt.Sprintf("%s:/root/.local/share/cvd:ro", cvdDataHome)
156+
bindMap["/podcvd_home"] = fmt.Sprintf("%s:/podcvd_home:rw", podcvdHomeDir)
157+
for _, p := range pathsToMount {
158+
if spec, ok := bindMap[p]; ok {
159+
host := strings.SplitN(spec, ":", 2)[0]
160+
if host != p {
161+
log.Printf("warning: container path %q is already mounted to %q, cannot mount %q\n", p, host, p)
162+
}
163+
continue
164+
}
165+
pInfo, err := os.Stat(p)
166+
if err != nil {
167+
log.Printf("warning: failed to stat path %q to mount: %v\n", p, err)
168+
continue
169+
}
170+
opt := "ro"
171+
if pInfo.IsDir() {
172+
opt = "O"
173+
}
174+
bindMap[p] = fmt.Sprintf("%s:%s:%s", p, p, opt)
175+
}
176+
var specs []string
177+
for _, spec := range bindMap {
178+
specs = append(specs, spec)
179+
}
180+
return specs
181+
}
182+
133183
func appendPortFlags(flags []string, hostIP string, protocol string, portStart int, portEnd int) []string {
134184
for port := portStart; port <= portEnd; port++ {
135185
flags = append(flags, "-p", fmt.Sprintf("%s:%d:%d/%s", hostIP, port, port, protocol))
@@ -219,6 +269,22 @@ func createAndStartContainer(ccm CuttlefishContainerManager, cvdArgs *CvdArgs) (
219269
if err := os.MkdirAll(podcvdHomeDir, 0755); err != nil {
220270
return "", fmt.Errorf("failed to create podcvd home dir: %w", err)
221271
}
272+
var pathsToMount []string
273+
for _, arg := range cvdArgs.SubCommandArgs {
274+
path := arg
275+
if strings.Contains(arg, "=") {
276+
path = strings.SplitN(arg, "=", 2)[1]
277+
}
278+
absPath := resolveHostPath(path)
279+
if absPath == "" {
280+
continue
281+
}
282+
pathsToMount = append(pathsToMount, absPath)
283+
if realPath, err := filepath.EvalSymlinks(absPath); err == nil && realPath != absPath {
284+
pathsToMount = append(pathsToMount, realPath)
285+
}
286+
}
287+
mountSpecs := collectMountSpecs(pathsToMount, hostOut, productOut, cvdDataHome, podcvdHomeDir)
222288

223289
extraFlags := []string{
224290
"-e", "ANDROID_HOST_OUT=/host_out",
@@ -230,71 +296,14 @@ func createAndStartContainer(ccm CuttlefishContainerManager, cvdArgs *CvdArgs) (
230296
"--cap-add", "NET_RAW",
231297
"--pids-limit", "8192",
232298
}
299+
for _, spec := range mountSpecs {
300+
extraFlags = append(extraFlags, "-v", spec)
301+
}
233302
clientID := os.Getenv(envClientID)
234303
if clientID != "" {
235304
extraFlags = append(extraFlags, "--label", fmt.Sprintf("%s=%s", labelClientID, clientID))
236305
}
237306

238-
bindMap := make(map[string]string)
239-
bindMap["/host_out"] = fmt.Sprintf("%s:/host_out:O", hostOut)
240-
bindMap["/product_out"] = fmt.Sprintf("%s:/product_out:O", productOut)
241-
bindMap["/root/.local/share/cvd"] = fmt.Sprintf("%s:/root/.local/share/cvd:ro", cvdDataHome)
242-
bindMap["/podcvd_home"] = fmt.Sprintf("%s:/podcvd_home:rw", podcvdHomeDir)
243-
for _, arg := range cvdArgs.SubCommandArgs {
244-
path := arg
245-
if strings.Contains(arg, "=") {
246-
path = strings.SplitN(arg, "=", 2)[1]
247-
}
248-
249-
// 1. Filter out empty strings which would incorrectly mount the CWD
250-
if strings.TrimSpace(path) == "" {
251-
continue
252-
}
253-
254-
absPath, err := filepath.Abs(path)
255-
if err != nil {
256-
continue
257-
}
258-
if _, err := os.Stat(absPath); err != nil {
259-
continue
260-
}
261-
// Prevent mounting critical system directories
262-
if strings.HasPrefix(absPath, "/dev/") || strings.HasPrefix(absPath, "/sys/") || strings.HasPrefix(absPath, "/proc/") {
263-
continue
264-
}
265-
266-
pathsToMount := []string{absPath}
267-
268-
// 2. Resolve symlinks and track the target file to ensure it's accessible inside
269-
if realPath, err := filepath.EvalSymlinks(absPath); err == nil && realPath != absPath {
270-
pathsToMount = append(pathsToMount, realPath)
271-
}
272-
273-
// 3. Add to mount configuration while preventing duplicates
274-
for _, p := range pathsToMount {
275-
if spec, ok := bindMap[p]; ok {
276-
host := strings.SplitN(spec, ":", 2)[0]
277-
if host != p {
278-
log.Printf("warning: container path %q is already mounted to %q, cannot mount %q\n", p, host, p)
279-
}
280-
continue
281-
}
282-
pInfo, err := os.Stat(p)
283-
if err != nil {
284-
log.Printf("warning: failed to stat path %q to mount: %v\n", p, err)
285-
continue
286-
}
287-
opt := "ro"
288-
if pInfo.IsDir() {
289-
opt = "O"
290-
}
291-
bindMap[p] = fmt.Sprintf("%s:%s:%s", p, p, opt)
292-
}
293-
}
294-
for _, mountSpec := range bindMap {
295-
extraFlags = append(extraFlags, "-v", mountSpec)
296-
}
297-
298307
var lastErr error
299308
for retryCount := 0; retryCount < 10; retryCount++ {
300309
groupNameIpAddrMap, err := Ipv4AddressesByGroupNames(ccm, true)

0 commit comments

Comments
 (0)