-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #122 from AkihiroSuda/a
print warning when preconditions are not satisfied + release v0.9.1
- Loading branch information
Showing
7 changed files
with
218 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// Package mount was forked from /~https://github.com/opencontainers/runc/tree/fc5759cf4fcf3f9c77c5973a24d37188dbcc92ee/libcontainer/mount | ||
package mount | ||
|
||
// GetMounts retrieves a list of mounts for the current running process. | ||
func GetMounts() ([]*Info, error) { | ||
return parseMountTable() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// +build linux | ||
|
||
package mount | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"io" | ||
"os" | ||
"strings" | ||
) | ||
|
||
const ( | ||
/* 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue | ||
(1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11) | ||
(1) mount ID: unique identifier of the mount (may be reused after umount) | ||
(2) parent ID: ID of parent (or of self for the top of the mount tree) | ||
(3) major:minor: value of st_dev for files on filesystem | ||
(4) root: root of the mount within the filesystem | ||
(5) mount point: mount point relative to the process's root | ||
(6) mount options: per mount options | ||
(7) optional fields: zero or more fields of the form "tag[:value]" | ||
(8) separator: marks the end of the optional fields | ||
(9) filesystem type: name of filesystem of the form "type[.subtype]" | ||
(10) mount source: filesystem specific information or "none" | ||
(11) super options: per super block options*/ | ||
mountinfoFormat = "%d %d %d:%d %s %s %s %s" | ||
) | ||
|
||
// Parse /proc/self/mountinfo because comparing Dev and ino does not work from | ||
// bind mounts | ||
func parseMountTable() ([]*Info, error) { | ||
f, err := os.Open("/proc/self/mountinfo") | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer f.Close() | ||
|
||
return parseInfoFile(f) | ||
} | ||
|
||
func parseInfoFile(r io.Reader) ([]*Info, error) { | ||
var ( | ||
s = bufio.NewScanner(r) | ||
out = []*Info{} | ||
) | ||
|
||
for s.Scan() { | ||
if err := s.Err(); err != nil { | ||
return nil, err | ||
} | ||
|
||
var ( | ||
p = &Info{} | ||
text = s.Text() | ||
optionalFields string | ||
) | ||
|
||
if _, err := fmt.Sscanf(text, mountinfoFormat, | ||
&p.ID, &p.Parent, &p.Major, &p.Minor, | ||
&p.Root, &p.Mountpoint, &p.Opts, &optionalFields); err != nil { | ||
return nil, fmt.Errorf("Scanning '%s' failed: %s", text, err) | ||
} | ||
// Safe as mountinfo encodes mountpoints with spaces as \040. | ||
index := strings.Index(text, " - ") | ||
postSeparatorFields := strings.Fields(text[index+3:]) | ||
if len(postSeparatorFields) < 3 { | ||
return nil, fmt.Errorf("Error found less than 3 fields post '-' in %q", text) | ||
} | ||
|
||
if optionalFields != "-" { | ||
p.Optional = optionalFields | ||
} | ||
|
||
p.Fstype = postSeparatorFields[0] | ||
p.Source = postSeparatorFields[1] | ||
p.VfsOpts = strings.Join(postSeparatorFields[2:], " ") | ||
out = append(out, p) | ||
} | ||
return out, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package mount | ||
|
||
// Info reveals information about a particular mounted filesystem. This | ||
// struct is populated from the content in the /proc/<pid>/mountinfo file. | ||
type Info struct { | ||
// ID is a unique identifier of the mount (may be reused after umount). | ||
ID int | ||
|
||
// Parent indicates the ID of the mount parent (or of self for the top of the | ||
// mount tree). | ||
Parent int | ||
|
||
// Major indicates one half of the device ID which identifies the device class. | ||
Major int | ||
|
||
// Minor indicates one half of the device ID which identifies a specific | ||
// instance of device. | ||
Minor int | ||
|
||
// Root of the mount within the filesystem. | ||
Root string | ||
|
||
// Mountpoint indicates the mount point relative to the process's root. | ||
Mountpoint string | ||
|
||
// Opts represents mount-specific options. | ||
Opts string | ||
|
||
// Optional represents optional fields. | ||
Optional string | ||
|
||
// Fstype indicates the type of filesystem, such as EXT3. | ||
Fstype string | ||
|
||
// Source indicates filesystem specific information or "none". | ||
Source string | ||
|
||
// VfsOpts represents per super block options. | ||
VfsOpts string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package parent | ||
|
||
import ( | ||
"io/ioutil" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/sirupsen/logrus" | ||
|
||
"github.com/rootless-containers/rootlesskit/pkg/parent/mount" | ||
) | ||
|
||
func warnPropagation(propagation string) { | ||
mounts, err := mount.GetMounts() | ||
if err != nil { | ||
logrus.WithError(err).Warn("Failed to parse mountinfo") | ||
return | ||
} | ||
var root *mount.Info | ||
for _, m := range mounts { | ||
if m.Root == "/" && m.Mountpoint == "/" { | ||
root = m | ||
} | ||
} | ||
if root == nil { | ||
logrus.Warn("Failed to parse mountinfo of the root filesystem") | ||
return | ||
} | ||
// 1. When running on a "sane" host, root.Optional is like "shared:1". ("shared" in findmnt(8) output) | ||
// 2. When running inside a container, root.Optional is like "master:363". ("private, slave" in findmnt(8) output) | ||
// | ||
// Setting non-private propagation is supported for 1, unsupported for 2. | ||
if !strings.Contains(propagation, "private") && !strings.Contains(root.Optional, "shared") { | ||
logrus.Warnf("The host root filesystem is mounted as %q. Setting child propagation to %q is not supported.", | ||
root.Optional, propagation) | ||
} | ||
} | ||
|
||
// warnSysctl verifies /proc/sys/kernel/unprivileged_userns_clone and /proc/sys/user/max_user_namespaces | ||
func warnSysctl() { | ||
uuc, err := ioutil.ReadFile("/proc/sys/kernel/unprivileged_userns_clone") | ||
// The file exists only on distros with the "add sysctl to disallow unprivileged CLONE_NEWUSER by default" patch. | ||
// (e.g. Debian and Arch) | ||
if err == nil { | ||
s := strings.TrimSpace(string(uuc)) | ||
i, err := strconv.ParseInt(s, 10, 64) | ||
if err != nil { | ||
logrus.WithError(err).Warnf("Failed to parse /proc/sys/kernel/unprivileged_userns_clone (%q)", s) | ||
} else if i == 0 { | ||
logrus.Warn("/proc/sys/kernel/unprivileged_userns_clone needs to be set to 1.") | ||
} | ||
} | ||
|
||
mun, err := ioutil.ReadFile("/proc/sys/user/max_user_namespaces") | ||
if err == nil { | ||
s := strings.TrimSpace(string(mun)) | ||
i, err := strconv.ParseInt(strings.TrimSpace(string(mun)), 10, 64) | ||
if err != nil { | ||
logrus.WithError(err).Warnf("Failed to parse /proc/sys/user/max_user_namespaces (%q)", s) | ||
} else if i == 0 { | ||
logrus.Warn("/proc/sys/user/max_user_namespaces needs to be set to non-zero.") | ||
} else { | ||
threshold := int64(1024) | ||
if i < threshold { | ||
logrus.Warnf("/proc/sys/user/max_user_namespaces=%d may be low. Consider setting to >= %d.", i, threshold) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
package version | ||
|
||
const Version = "0.9.0+dev" | ||
const Version = "0.9.1+dev" |