Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtimetest: add mounts order validation #444

Merged
merged 1 commit into from
Aug 30, 2017

Conversation

Mashimiao
Copy link

According to mount orders in /proc/self/mountinfo to validate whether mounts are mounted in order.

Signed-off-by: Ma Shimiao mashimiao.fnst@cn.fujitsu.com

@@ -630,6 +630,54 @@ func validateMountsExist(spec *rspec.Spec) error {
return nil
}

func validateMountsOrder(spec *rspec.Spec) error {
if runtime.GOOS == "windows" {
return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly warn that the check is not implemented (like we currently do here)?

mounts := mountsMap[specMount.Destination]
for _, mount := range mounts {
source := mount.Source
if specMount.Type == "bind" || specMount.Type == "rbind" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(r)bind mounts are still not covered in the spec. My most recent attempt was opencontainers/runtime-spec#771, which I think should be reopened, but there is also an in-flight opencontainers/runtime-spec#878. Making runtime-tools decisions based on in-flight spec changes is dicey, but in both of those PRs the bind-ness of a mounts entry is based on options, not on type. So if you want to land special bind handling at all here, I suggest you look in specMount.Options.

mountsMap[mountInfo.Mountpoint] = append(mountsMap[mountInfo.Mountpoint], m)
}
current := -1
for _, specMount := range spec.Mounts {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a cheap local part of the in-flight #266 you could use configMount instead of specMount for this variable.

@Mashimiao Mashimiao force-pushed the mount-order branch 2 times, most recently from e4a481c to d566fe0 Compare August 18, 2017 01:18
@Mashimiao
Copy link
Author

@wking all updated.

@Mashimiao
Copy link
Author

@opencontainers/runtime-tools-maintainers PTAL

@zhouhao3
Copy link

zhouhao3 commented Aug 18, 2017

LGTM

Approved with PullApprove

source := mount.Source
for _, option := range configMount.Options {
if option == "bind" || option == "rbind" {
source = mount.Root
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big deal, because there are probably not going to be tons of options to iterate over, but you can break here.

}
if source == configMount.Source {
if current > mount.Order {
return fmt.Errorf("%s is not mounted in order", configMount.Source)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could return a more informative message here if current was a*mountOrder.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't understand your comment very well. Can you give an example?

Copy link
Contributor

@wking wking Aug 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give an example?

I haven't compiled the following, but something like:

var current *mountOrder
for i, configMount := range spec.Mounts {
  mounts, ok := mountsMap[configMount.Destination]
  if !ok {
    // this error message could be better too, but I'm following validateMountsExist
    return fmt.Errorf("Expected mount %v does not exist", configMount)
  }
  for j, mount := range mounts {
    source := mount.Source
    for _, option := range configMount.Options {
      if option == "bind" || option == "rbind" {
        source = mount.Root
        break
      }
    }
    if source == configMount.Source {
      if current != nil && current.Order > mount.Order {
        return fmt.Errorf("mounts[%d] %q is mounted before %q", i, configMount.Destination, current.Destination)
      }
      current = &mount
      // in order to deal with dup mount elements
      mountsMap[configMount.Destination] = append(mountsMap[configMount.Destination][:j], mountsMap[configMount.Destination][j+1:]...)
      break
    }
  }
}

I'm also not clear on your dup-handling bit at the end. And we'd probably have better (or at least more consistent) matching if we used mountMatch here too (like we already do here).

Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
@Mashimiao
Copy link
Author

Mashimiao commented Aug 22, 2017 via email

@wking
Copy link
Contributor

wking commented Aug 22, 2017 via email

@Mashimiao
Copy link
Author

Mashimiao commented Aug 23, 2017 via email

@liangchenye
Copy link
Member

liangchenye commented Aug 30, 2017

LGTM

Approved with PullApprove

1 similar comment
@zhouhao3
Copy link

zhouhao3 commented Aug 30, 2017

LGTM

Approved with PullApprove

@zhouhao3 zhouhao3 merged commit bddc043 into opencontainers:master Aug 30, 2017
wking added a commit to wking/ocitools-v2 that referenced this pull request Aug 30, 2017
…Order

Also increase the error message detail and continue through the
remaining mounts instead of breaking on the first missing/misordered
mount.  Based on previous discussion in [1,2].  With this commit,
configuration like:

  "mounts": [
    {
      "destination": "/tmp",
      "type": "tmpfs",
      "source": "none"
    },
    {
      "destination": "/tmp",
      "type": "tmpfs",
      "source": "none"
    },
    {
      "destination": "/dev",
      "type": "devtmpfs",
      "source": "devtmpfs"
    }
  ]

and mountinfo like:

  $ grep -n '/dev \|/tmp ' /proc/self/mountinfo
  2:19 17 0:6 / /dev rw,nosuid,relatime - devtmpfs devtmpfs rw,size=10240k,nr_inodes=2043951,mode=755
  25:41 17 0:38 / /tmp rw,relatime - tmpfs none rw

will generate errors like:

  * mounts[1] {/tmp tmpfs none [nosuid strictatime mode=755 size=65536k]} does not exist
  * mounts[2] {/dev devtmpfs devtmpfs [rw size=10240k nr_inodes=2043951 mode=755]} is system mount 1, while mounts[0] {/tmp tmpfs none [nosuid strictatime mode=755 size=65536k]} is system mount 24

Grep reports 2 and 25 because it's counting from one, and runtimetest
reports 1 and 24 because it's counting from zero.

Before this commit, the error was just:

  * Mounts[1] /tmp is not mounted in order

[1]: opencontainers#444 (comment)
[2]: opencontainers#444 (comment)

Signed-off-by: W. Trevor King <wking@tremily.us>
wking added a commit to wking/ocitools-v2 that referenced this pull request Aug 30, 2017
…Order

Also increase the error message detail and continue through the
remaining mounts instead of breaking on the first missing/misordered
mount.  Based on previous discussion in [1,2].  With this commit,
a configuration like:

  "mounts": [
    {
      "destination": "/tmp",
      "type": "tmpfs",
      "source": "none"
    },
    {
      "destination": "/tmp",
      "type": "tmpfs",
      "source": "none"
    },
    {
      "destination": "/dev",
      "type": "devtmpfs",
      "source": "devtmpfs"
    }
  ]

and mountinfo like:

  $ grep -n '/dev \|/tmp ' /proc/self/mountinfo
  2:19 17 0:6 / /dev rw,nosuid,relatime - devtmpfs devtmpfs rw,size=10240k,nr_inodes=2043951,mode=755
  25:41 17 0:38 / /tmp rw,relatime - tmpfs none rw

will generate errors like:

  * mounts[1] {/tmp tmpfs none [nosuid strictatime mode=755 size=65536k]} does not exist
  * mounts[2] {/dev devtmpfs devtmpfs [rw size=10240k nr_inodes=2043951 mode=755]} is system mount 1, while mounts[0] {/tmp tmpfs none [nosuid strictatime mode=755 size=65536k]} is system mount 24

Grep reports 2 and 25 because it's counting from one, and runtimetest
reports 1 and 24 because it's counting from zero.

Before this commit, the error was just:

  * Mounts[1] /tmp is not mounted in order

[1]: opencontainers#444 (comment)
[2]: opencontainers#444 (comment)

Signed-off-by: W. Trevor King <wking@tremily.us>
wking added a commit to wking/ocitools-v2 that referenced this pull request Aug 30, 2017
…Order

Also increase the error message detail and continue through the
remaining mounts instead of breaking on the first missing/misordered
mount.  Based on previous discussion in [1,2].  With this commit,
a configuration like:

  "mounts": [
    {
      "destination": "/tmp",
      "type": "tmpfs",
      "source": "none"
    },
    {
      "destination": "/tmp",
      "type": "tmpfs",
      "source": "none"
    },
    {
      "destination": "/dev",
      "type": "devtmpfs",
      "source": "devtmpfs"
    }
  ]

and mountinfo like:

  $ grep -n '/dev \|/tmp ' /proc/self/mountinfo
  2:19 17 0:6 / /dev rw,nosuid,relatime - devtmpfs devtmpfs rw,size=10240k,nr_inodes=2043951,mode=755
  25:41 17 0:38 / /tmp rw,relatime - tmpfs none rw

will generate errors like:

  * mounts[1] {/tmp tmpfs none []} does not exist
  * mounts[2] {/dev devtmpfs devtmpfs []} is system mount 1, while mounts[0] {/tmp tmpfs none []} is system mount 24

Grep reports 2 and 25 because it's counting from one, and runtimetest
reports 1 and 24 because it's counting from zero.

Before this commit, the error was just:

  * Mounts[1] /tmp is not mounted in order

[1]: opencontainers#444 (comment)
[2]: opencontainers#444 (comment)

Signed-off-by: W. Trevor King <wking@tremily.us>
wking added a commit to wking/ocitools-v2 that referenced this pull request Aug 31, 2017
…Order

Also increase the error message detail and continue through the
remaining mounts instead of breaking on the first missing/misordered
mount.  Based on previous discussion in [1,2].  With this commit,
a configuration like:

  "mounts": [
    {
      "destination": "/tmp",
      "type": "tmpfs",
      "source": "none"
    },
    {
      "destination": "/tmp",
      "type": "tmpfs",
      "source": "none"
    },
    {
      "destination": "/dev",
      "type": "devtmpfs",
      "source": "devtmpfs"
    }
  ]

and mountinfo like:

  $ grep -n '/dev \|/tmp ' /proc/self/mountinfo
  2:19 17 0:6 / /dev rw,nosuid,relatime - devtmpfs devtmpfs rw,size=10240k,nr_inodes=2043951,mode=755
  25:41 17 0:38 / /tmp rw,relatime - tmpfs none rw

will generate errors like:

  * mounts[1] {/tmp tmpfs none []} does not exist
  * mounts[2] {/dev devtmpfs devtmpfs []} mounted before mounts[0] {/tmp tmpfs none []}

Before this commit, the error was just:

  * Mounts[1] /tmp is not mounted in order

I'd prefer errors like:

  * mounts[1] {/tmp tmpfs none []} does not exist
  * mounts[2] {/dev devtmpfs devtmpfs []} is system mount 1, while mounts[0] {/tmp tmpfs none []} is system mount 24

where grep reports 2 and 25 because it's counting from one, and
runtimetest reports 1 and 24 because it's counting from zero, but Ma
prefers to not mention the system-mount order [3].

[1]: opencontainers#444 (comment)
[2]: opencontainers#444 (comment)
[3]: opencontainers#456 (comment)

Signed-off-by: W. Trevor King <wking@tremily.us>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants