cmd: add helpers for working with mount/umount commands #2814

Merged
merged 14 commits into from Feb 9, 2017

Conversation

Projects
None yet
2 participants
Contributor

zyga commented Feb 8, 2017

This patch adds two new functions that describe mount/umount system call arguments in terms
of option passed to an equivalent mount and umount commands. They are mainly intended for
debugging but can be also used to cut the amount of boilerplate code.

This branch also includes a small new string routine, sc_string_init, because appending is
only sensible given a well-defined initial state.

Signed-off-by: Zygmunt Krynicki zygmunt.krynicki@canonical.com

zyga added some commits Jan 18, 2017

cmd/libsnap: add sc_umount_cmd
This patch adds a function that constructs debug message for what a
umount2 system call does in terms of the umount system command. It is
intended to be used in debugging and error messages instead of
hand-crafted messages that may be silently stale or incorrect.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
cmd/libsnap: correct stale comment
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
cmd/libsnap: add sc_mount_cmd
This patch adds a function that constructs debug message for what a
mount system call does in terms of the mount system command. It is
intended to be used in debugging and error messages instead of
hand-crafted messages that may be silently stale or incorrect.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
cmd/libsnap: remove redundant test_ prefix from test names
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
cmd/libsnap: add sc_string_init
This patch adds a complementary function to sc_string_append.
Before one can append the destination buffer must hold a valid
string. The new function can safely initialize the buffer to hold
an empty string.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
cmd/libsnap: use sc_string_init in a few places
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
cmd/libsnap-confine-private/mount-opt.c
+const char *sc_mount_cmd(char *buf, size_t buf_size, const char *source, const char
+ *target, const char *filesystemtype,
+ unsigned long mountflags, const
+ void *data)
@jdstrand

jdstrand Feb 8, 2017

Contributor

filesystemtype is a bit combersome. How about fs_type?

@zyga

zyga Feb 8, 2017

Contributor

This just follows the manual page but if you prefer I can tweak it.

@jdstrand

jdstrand Feb 8, 2017

Contributor

It's fine how it is if that's how you prefer it.

cmd/libsnap-confine-private/mount-opt.c
+ sc_string_append(buf, buf_size, "mount");
+
+ // Add filesysystem type if it's there and doesn't have the special value "none"
+ if (filesystemtype != NULL && strcmp(filesystemtype, "none") != 0) {
@jdstrand

jdstrand Feb 8, 2017

Contributor

You are checking for filesystemtype != NULL here which implies you don't know its contents are a proper C string. strncmp(filesystemtype, "none", 4) may be somewhat better since there aren't any filesystems that start with 'none'.

@zyga

zyga Feb 8, 2017

Contributor

Nice idea, will do

cmd/libsnap-confine-private/mount-opt.c
+ } else {
+ sc_string_append(buf, buf_size, " --bind");
+ }
+ used_special_flags |= MS_BIND | MS_REC;
@jdstrand

jdstrand Feb 8, 2017

Contributor

Shouldn't MS_REC only be set if mountflags & MS_REC? Same for with MS_SHARED, MS_SLAVE, MS_PRIVATE and MS_UNBINDABLE in the next sections.

@zyga

zyga Feb 8, 2017

Contributor

This is done so that we don't redundantly display rec in the generic -o section below. The idea is that since this only makes sense with one of the places that already handle MS_REC we don't display it in the generic section.

@jdstrand

jdstrand Feb 8, 2017

Contributor

Since used_special_flags is being used to track what was already added to the buf, even if for the case of MS_REC it doesn't matter, it seems that being precise is better for future-proofing (eg, if the conditional changes, etc) and it makes it a whole lot easier to understand. As such, I'd prefer to see this:

if (mountflags & MS_BIND) {
	if (mountflags & MS_REC) {
		sc_string_append(buf, buf_size, " --rbind");
		used_special_flags |= MS_REC;
	} else {
		sc_string_append(buf, buf_size, " --bind");
	}
	used_special_flags |= MS_BIND;
}
cmd/libsnap-confine-private/mount-opt.c
+ size_t used = strnlen(buf, buf_size);
+ // NOTE: the option are written directly to the buffer we are working with.
+ sc_mount_opt2str(buf + used, buf_size - used,
+ mountflags & ~used_special_flags);
@jdstrand

jdstrand Feb 8, 2017

Contributor

This is non-obvious. It appears you are trying to tack on the mount flags to the end of buf based on what is left in buf, and then sc_mount_opt2str() calls sc_string_init() in the middle of the string (probably why you used *buf = 0 in sc_string_init() now that I see this). I think this needs to be rewritten in a manner that is easier to follow. Perhaps create a new string to pass to sc_mount_opt2str() then sc_string_append(buf, buf_size, this_new_string).

@zyga

zyga Feb 8, 2017

Contributor

Ha, I had that exact code but then I wanted to just use one buffer. I can easily restore that code.

cmd/libsnap-confine-private/mount-opt.c
+ mountflags & ~used_special_flags);
+ }
+ // Add source and target locations
+ if (source != NULL && strcmp(source, "none") != 0) {
@jdstrand

jdstrand Feb 8, 2017

Contributor

Same comment here as for filesystemtype. A strncmp(source, "none", 4) could be better since source shouldn't ever start with 'none'.

cmd/libsnap-confine-private/mount-opt.c
+ sc_string_append(buf, buf_size, " ");
+ sc_string_append(buf, buf_size, source);
+ }
+ if (target != NULL && strcmp(target, "none") != 0) {
@jdstrand

jdstrand Feb 8, 2017

Contributor

Same comment here. A strncmp(target, "none", 4) could be better since target shouldn't ever start with 'none'.

+ if (buf_size == 0) {
+ die("cannot initialize string, buffer is too small");
+ }
+ *buf = 0;
@jdstrand

jdstrand Feb 8, 2017

Contributor

For consistency style, please use (but see my comments regarding sc_mount_cmd inline):

buf[0] = '\0';
@@ -50,4 +50,9 @@ int sc_must_snprintf(char *str, size_t size, const char *format, ...);
**/
size_t sc_string_append(char *dst, size_t dst_size, const char *str);
+/**
+ * Initialize a string (make it empty).
@jdstrand

jdstrand Feb 8, 2017

Contributor

Can you adjust this to be: "Initialize a string as empty, ensuring dst is non-NULL and dst_size is > 0"

zyga added some commits Feb 8, 2017

cmd/libsnap: use strncmp to compare to "none"
The filesystem type, source and destination name are unknown so we
should be careful about comparing them.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
cmd/libsnap: abbreviate filesystemtype to fs_type
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
cmd/libsnap: tweak style without semantic change
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
cmd/libsnap: expand documentation of sc_string_init
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
cmd/libsnap: rewrite buffer management for simplicity
This patch changes the way sc_mount_cmd() formats the remaining mount
option for the "-o ..." part of the command.

It used to use the existing buffer, carefully crafting the new message
at the end of the used space. This was correct but non-obvious without
checking how those functions currently operate. The new code simply
creates the "-o ..." string in a a separate buffer and appends that
extra buffer to the main buffer with sc_string_append.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

Looks fine with a couple of small requests.

cmd/libsnap-confine-private/mount-opt.c
+ }
+ // Check for some special, dedicated syntax. Collect the flags that were
+ // displayed this way so that they are not repeated with -o foo syntax.
+ int used_special_flags = 0;
@jdstrand

jdstrand Feb 8, 2017

Contributor

How this variable works is a bit subtle. Can we adjust the comments to be:

// Check for some special, dedicated options that aren't represented with mount
// command line arguments by collecting those options that we will display as
// command line arguments in used_special_flags so it may be used to filter out
// these arguments from mount_flags when calling sc_mount_opt2str() later.

Wordsmith that however you like. :)

@zyga

zyga Feb 9, 2017

Contributor

I think you just convinced me to write my own text editor. It shall be called wordsmith 🗡

cmd/libsnap-confine-private/mount-opt.c
+ } else {
+ sc_string_append(buf, buf_size, " --bind");
+ }
+ used_special_flags |= MS_BIND | MS_REC;
@jdstrand

jdstrand Feb 8, 2017

Contributor

Shouldn't MS_REC only be set if mountflags & MS_REC? Same for with MS_SHARED, MS_SLAVE, MS_PRIVATE and MS_UNBINDABLE in the next sections.

@zyga

zyga Feb 8, 2017

Contributor

This is done so that we don't redundantly display rec in the generic -o section below. The idea is that since this only makes sense with one of the places that already handle MS_REC we don't display it in the generic section.

@jdstrand

jdstrand Feb 8, 2017

Contributor

Since used_special_flags is being used to track what was already added to the buf, even if for the case of MS_REC it doesn't matter, it seems that being precise is better for future-proofing (eg, if the conditional changes, etc) and it makes it a whole lot easier to understand. As such, I'd prefer to see this:

if (mountflags & MS_BIND) {
	if (mountflags & MS_REC) {
		sc_string_append(buf, buf_size, " --rbind");
		used_special_flags |= MS_REC;
	} else {
		sc_string_append(buf, buf_size, " --bind");
	}
	used_special_flags |= MS_BIND;
}
+ // If regular option syntax exists then use it.
+ if (mountflags & ~used_special_flags) {
+ char opts_buf[1000];
+ sc_mount_opt2str(opts_buf, sizeof opts_buf, mountflags &
@jdstrand

jdstrand Feb 8, 2017

Contributor

Nitpick: sizeof(opts_buf) for style consistency.

@zyga

zyga Feb 9, 2017

Contributor

Aww, I really like the bare sizeof :-(

zyga added some commits Feb 9, 2017

cmd/libsnap: precisely collect used_special_flags
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
cmd/libsnap: document used_special_flags better
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Contributor

zyga commented Feb 9, 2017

@jdstrand please have a final look

cmd/libsnap-confine-private/mount-opt.c
+ // Check for some special, dedicated options, that aren't represented with
+ // the generic mount option argument (mount -o ...), by collecting those
+ // options that we will display as command line arguments in
+ // used_special_flags so. This is used below to filter out these arguments
@jdstrand

jdstrand Feb 9, 2017

Contributor

s/ so//

@zyga

zyga Feb 9, 2017

Contributor

Fixed, thank you

cmd/libsnap: fix typo
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

@zyga zyga merged commit 999b6a7 into snapcore:master Feb 9, 2017

6 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
xenial-amd64 autopkgtest finished (success)
Details
xenial-i386 autopkgtest finished (success)
Details
xenial-ppc64el autopkgtest finished (success)
Details
yakkety-amd64 autopkgtest finished (success)
Details
zesty-amd64 autopkgtest finished (success)
Details

@zyga zyga deleted the zyga:mount-cmd-helpers branch Feb 9, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment