{"record":{"id":"e300e220e94dfdae","repo":"juicedata/juicefs","slug":"read-cgroup-file","errorCode":null,"errorMessage":"read cgroup file","messagePattern":"read cgroup file","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/fuse/device_linux.go","lineNumber":54,"sourceCode":"\t\t}\n\t}\n}\n\n// grantAccess appends 'c 10:229 rwm' to devices.allow\nfunc grantAccess() error {\n\tpid := os.Getpid()\n\tcgroupPath := fmt.Sprintf(\"/proc/%d/cgroup\", pid)\n\tcgroupFile, err := os.Open(cgroupPath)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"open %s\", cgroupPath)\n\t}\n\tdefer cgroupFile.Close()\n\n\tcgroupScanner := bufio.NewScanner(cgroupFile)\n\tvar deviceCgroup string\n\tfor cgroupScanner.Scan() {\n\t\tif err := cgroupScanner.Err(); err != nil {\n\t\t\treturn errors.Wrap(err, \"read cgroup file\")\n\t\t}\n\t\tvar (\n\t\t\ttext  = cgroupScanner.Text()\n\t\t\tparts = strings.SplitN(text, \":\", 3)\n\t\t)\n\t\tif len(parts) < 3 {\n\t\t\treturn errors.Errorf(\"invalid cgroup entry: %q\", text)\n\t\t}\n\n\t\tif parts[1] == \"devices\" {\n\t\t\tdeviceCgroup = parts[2]\n\t\t}\n\t}\n\n\tif len(deviceCgroup) == 0 {\n\t\treturn errors.Errorf(\"fail to find device cgroup\")\n\t}\n","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/fuse/device_linux.go#L36-L72","documentation":"Wraps bufio.Scanner errors while line-scanning /proc/<pid>/cgroup in grantAccess, which searches for the 'devices' cgroup controller to grant FUSE device access. The scanner error is typically read I/O failure on procfs rather than a parse problem (malformed lines produce the separate 'invalid cgroup entry' error).","triggerScenarios":"Mounting via FUSE in a container where reading /proc/<pid>/cgroup fails mid-scan: procfs read returning EIO due to kernel/security oddities, file larger than the scanner buffer with no token (rare for cgroup files), or kernel errors under heavy cgroup v2 hierarchies.","commonSituations":"gVisor/Kata or other sandboxed runtimes whose procfs emulation errors on reads; unusual kernel instrumentation; very long cgroup v2 paths exceeding the default 64KB bufio.Scanner token limit.","solutions":["Retry the mount — transient procfs read errors often disappear","Verify `cat /proc/self/cgroup` works in the same environment; if not, fix the runtime/security profile","Grant /dev/fuse externally (--device /dev/fuse, privileged mode) so grantAccess is skipped","If cgroup output is unusually large, run in a runtime that exposes standard procfs behavior"],"exampleFix":"// before\n# sandboxed runtime with broken procfs\nkata-runtime run ... juicefs mount redis://... /mnt/jfs\n// after\n# standard runc container with device granted\ndocker run --device /dev/fuse --cap-add SYS_ADMIN juicefs/juicefs mount redis://... /mnt/jfs","handlingStrategy":"fallback","validationCode":"data, err := os.ReadFile(\"/proc/self/cgroup\")\nif err != nil { return fmt.Errorf(\"cannot read cgroup info: %w\", err) }\nif len(data) == 0 || len(data) > 1<<20 { return fmt.Errorf(\"unexpected cgroup file size: %d\", len(data)) }","typeGuard":null,"tryCatchPattern":"if err := mount(...); err != nil {\n\tif strings.Contains(err.Error(), \"read cgroup file\") {\n\t\tlog.Printf(\"procfs read failed in this runtime; pre-grant /dev/fuse or use a standard runtime\")\n\t}\n}","preventionTips":["Use standard runtimes (runc/docker) that expose normal procfs","Pre-grant FUSE device access so cgroup scanning is skipped","Test `cat /proc/self/cgroup` in the target environment before mounting"],"tags":["fuse","cgroup","container","linux","procfs"],"backgroundTag":"file-read-failed","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}