From: Andrew Price <anprice@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] tunegfs2: Fix label/locktable setting code
Date: Thu, 21 Jul 2011 12:00:41 +0100 [thread overview]
Message-ID: <4E2806D9.3000403@redhat.com> (raw)
In-Reply-To: <1311155869.2703.8.camel@menhir>
Hi Steve,
On 20/07/11 10:57, Steven Whitehouse wrote:
>
> This is an updated version of the previously posted patch aimed at
> fixing bz #719135
Looks good to me. Just a couple of minor notes on input validation...
With this patch it's possible to set the locktable to ":" using:
# tunegfs2 -o lockproto=lock_dlm /dev/dm-3
# tunegfs2 -L : /dev/dm-3
And although this rightly fails:
# tunegfs2 -o lockproto=lock_dlm,locktable=foo /dev/dm-3
locktable error: mising colon in the locktable
it is still possible to specify a colon-less locktable name with lock_dlm:
# tunegfs2 -o lockproto=lock_nolock /dev/dm-3
# tunegfs2 -L foo /dev/dm-3
# tunegfs2 -o lockproto=lock_dlm /dev/dm-3
> The differences from the previous patch are that the printing function
> now prints the whole of the label, to match the setting function and
> it also checks the size of the lock protocol string, which was
> previously not done.
>
> The code here seemed a bit confused. I've added a check for the
> format of the locktable/label based on the same code in mkfs.
> In addition we set the lock proto first in order that we use the
> new value of the lock proto when checking the format of
> the lock table.
>
> There is no need to have a separate function for setting the
> label to the locktable, since they are both setting the same
> data.
>
> The on-disk locktable and lockproto always contain trailing
> NULLs and when we read the sb from disk, we now always add NULLs
> at the end of the strings so that we can rely on this later on.
>
> The patch also checks the size of the lock table when it is
> set to ensure that it is not too large.
>
> Signed-off-by: Steven Whitehouse<swhiteho@redhat.com>
> Reported-by: Nathan Straz<nstraz@redhat.com>
>
> diff --git a/gfs2/tune/main.c b/gfs2/tune/main.c
> index 6a0daff..dc9d6a5 100644
> --- a/gfs2/tune/main.c
> +++ b/gfs2/tune/main.c
> @@ -20,13 +20,13 @@ struct tunegfs2 tunegfs2_struct;
> struct tunegfs2 *tfs =&tunegfs2_struct;
>
>
> -void parse_mount_options(char *arg)
> +static void parse_mount_options(char *arg)
> {
> struct opt_map *m;
> char *s, *c;
> int l;
> struct opt_map {
> - char *tag;
> + const char *tag;
> int *flag;
> char **val;
> } map[]= {
> @@ -101,6 +101,12 @@ int main(int argc, char **argv)
> return EX_USAGE;
> }
>
> + if (tfs->opt_label&& tfs->opt_table) {
> + fprintf(stderr, _("The -L and -o locktable= options are mutually exclusive\n"));
> + usage(argv[0]);
> + return EX_USAGE;
> + }
> +
> tfs->devicename = argv[optind];
> tfs->fd = open(tfs->devicename, O_RDWR);
>
> @@ -120,29 +126,26 @@ int main(int argc, char **argv)
> goto out;
> }
>
> - /* Keep label and table together because they are the same field
> - * in the superblock */
> -
> - if (tfs->opt_label) {
> - status = change_label(tfs, tfs->label);
> + if (tfs->opt_proto) {
> + status = change_lockproto(tfs, tfs->proto);
> if (status)
> goto out;
> }
>
> - if (tfs->opt_table) {
> - status = change_locktable(tfs, tfs->table);
> + if (tfs->opt_label) {
> + status = change_locktable(tfs, tfs->label);
> if (status)
> goto out;
> }
>
> - if (tfs->opt_proto) {
> - status = change_lockproto(tfs, tfs->proto);
> + if (tfs->opt_table) {
> + status = change_locktable(tfs, tfs->table);
> if (status)
> goto out;
> }
>
> - if (tfs->opt_label || tfs->opt_uuid ||
> - tfs->opt_table || tfs->opt_proto) {
> + if (tfs->opt_label || tfs->opt_uuid || tfs->opt_table ||
> + tfs->opt_proto) {
> status = write_super(tfs);
> if (status)
> goto out;
> diff --git a/gfs2/tune/super.c b/gfs2/tune/super.c
> index 9d67054..65e8d5b 100644
> --- a/gfs2/tune/super.c
> +++ b/gfs2/tune/super.c
> @@ -104,6 +104,9 @@ int read_super(struct tunegfs2 *tfs)
> fprintf(stderr, _("Not a GFS/GFS2 device\n"));
> return EX_IOERR;
> }
> + /* Ensure that table and proto are NULL terminated */
> + tfs->sb->sb_lockproto[GFS2_LOCKNAME_LEN - 1] = '\0';
> + tfs->sb->sb_locktable[GFS2_LOCKNAME_LEN - 1] = '\0';
> return 0;
> }
>
> @@ -114,17 +117,7 @@ static int is_gfs2(const struct tunegfs2 *tfs)
>
> int print_super(const struct tunegfs2 *tfs)
> {
> - char *fsname = NULL;
> - int table_len = 0, fsname_len = 0;
> -
> - fsname = strchr(tfs->sb->sb_locktable, ':');
> - if (fsname) {
> - table_len = fsname - tfs->sb->sb_locktable;
> - fsname_len = GFS2_LOCKNAME_LEN - table_len - 1;
> - fsname++;
> - }
> -
> - printf(_("Filesystem volume name: %.*s\n"), fsname_len, fsname);
> + printf(_("Filesystem volume name: %s\n"), tfs->sb->sb_locktable);
> if (is_gfs2(tfs))
> printf(_("Filesystem UUID: %s\n"), uuid2str(tfs->sb->sb_uuid));
> printf( _("Filesystem magic number: 0x%X\n"), be32_to_cpu(tfs->sb->sb_header.mh_magic));
> @@ -133,9 +126,8 @@ int print_super(const struct tunegfs2 *tfs)
> printf(_("Root inode: %llu\n"), (unsigned long long)be64_to_cpu(tfs->sb->sb_root_dir.no_addr));
> if (is_gfs2(tfs))
> printf(_("Master inode: %llu\n"), (unsigned long long)be64_to_cpu(tfs->sb->sb_master_dir.no_addr));
> - printf(_("Lock Protocol: %.*s\n"), GFS2_LOCKNAME_LEN,
> - tfs->sb->sb_lockproto);
> - printf(_("Lock table: %.*s\n"), table_len, tfs->sb->sb_locktable);
> + printf(_("Lock Protocol: %s\n"), tfs->sb->sb_lockproto);
> + printf(_("Lock table: %s\n"), tfs->sb->sb_locktable);
>
> return 0;
> }
> @@ -151,26 +143,6 @@ int write_super(const struct tunegfs2 *tfs)
> return 0;
> }
>
> -int change_label(struct tunegfs2 *tfs, const char *fsname)
> -{
> - char *sb_fsname = NULL;
> - int l = strlen(fsname), table_len = 0, fsname_len = 0;
> -
> - sb_fsname = strchr(tfs->sb->sb_locktable, ':');
> - if (sb_fsname) {
> - table_len = sb_fsname - tfs->sb->sb_locktable;
> - fsname_len = GFS2_LOCKNAME_LEN - table_len - 1;
> - sb_fsname++;
> - }
> - if (fsname_len< l) {
> - fprintf(stderr, _("Label too long\n"));
> - return EX_DATAERR;
> - }
> - memset(sb_fsname, '\0', fsname_len);
> - memcpy(sb_fsname, fsname, l);
> - return 0;
> -}
> -
> int change_uuid(struct tunegfs2 *tfs, const char *str)
> {
> char uuid[16];
> @@ -186,12 +158,17 @@ int change_uuid(struct tunegfs2 *tfs, const char *str)
> return status;
> }
>
> -
> int change_lockproto(struct tunegfs2 *tfs, const char *lockproto)
> {
> int l = strlen(lockproto);
> - if (strncmp(lockproto, "lock_dlm", 8)
> - && strncmp(lockproto, "lock_nolock", 11)) {
> +
> + if (l>= GFS2_LOCKNAME_LEN) {
> + fprintf(stderr, _("Lock protocol name too long\n"));
> + return EX_DATAERR;
> + }
> +
> + if (strncmp(lockproto, "lock_dlm", 8)&&
> + strncmp(lockproto, "lock_nolock", 11)) {
> fprintf(stderr, _("Incorrect lock protocol specified\n"));
> return EX_DATAERR;
> }
> @@ -202,30 +179,28 @@ int change_lockproto(struct tunegfs2 *tfs, const char *lockproto)
>
> int change_locktable(struct tunegfs2 *tfs, const char *locktable)
> {
> - char *sb_fsname = NULL;
> - char t_fsname[GFS2_LOCKNAME_LEN];
> - int l = strlen(locktable), table_len = 0, fsname_len = 0;
> -
> - sb_fsname = strchr(tfs->sb->sb_locktable, ':');
> - if (sb_fsname) {
> - table_len = sb_fsname - tfs->sb->sb_locktable;
> - fsname_len = GFS2_LOCKNAME_LEN - table_len - 1;
> - sb_fsname++;
> - }
> - /* Gotta check if the existing fsname will allow us to fit in
> - * the new locktable name */
> - fsname_len = strlen(sb_fsname);
> - if (fsname_len> GFS2_LOCKNAME_LEN - table_len - 1)
> - fsname_len = GFS2_LOCKNAME_LEN - table_len - 1;
> -
> - if (l> GFS2_LOCKNAME_LEN - fsname_len - 1) {
> - fprintf(stderr, _("Lock table name too big\n"));
> + if (strlen(locktable)>= GFS2_LOCKNAME_LEN) {
> + fprintf(stderr, _("Lock table name too long\n"));
> return EX_DATAERR;
> }
> - memset(t_fsname, '\0', GFS2_LOCKNAME_LEN);
> - strncpy(t_fsname, sb_fsname, fsname_len);
> - memset(tfs->sb->sb_locktable, '\0', GFS2_LOCKNAME_LEN);
> - sprintf(tfs->sb->sb_locktable, "%s:%s", locktable, t_fsname);
> +
> + if (strcmp(tfs->sb->sb_lockproto, "lock_dlm") == 0) {
> + char *fsname = strchr(locktable, ':');
> + if (fsname == NULL) {
> + fprintf(stderr, _("locktable error: mising colon in the locktable\n"));
> + return EX_DATAERR;
> + }
> + if (strlen(++fsname)> 16) {
> + fprintf(stderr, _("locktable error: fsname too long\n"));
> + return EX_DATAERR;
> + }
> + if (strchr(fsname, ':')) {
> + fprintf(stderr, _("locktable error: more than one colon present\n"));
> + return EX_DATAERR;
> + }
> + }
> +
> + strcpy(tfs->sb->sb_locktable, locktable);
> return 0;
> }
>
> diff --git a/gfs2/tune/tunegfs2.h b/gfs2/tune/tunegfs2.h
> index 8fe7e07..3b28c58 100644
> --- a/gfs2/tune/tunegfs2.h
> +++ b/gfs2/tune/tunegfs2.h
> @@ -24,7 +24,6 @@ extern int print_super(const struct tunegfs2 *);
> extern int read_super(struct tunegfs2 *);
> extern int write_super(const struct tunegfs2 *);
> extern int change_uuid(struct tunegfs2 *, const char *uuid);
> -extern int change_label(struct tunegfs2 *, const char *label);
> extern int change_lockproto(struct tunegfs2 *, const char *label);
> extern int change_locktable(struct tunegfs2 *, const char *label);
>
>
>
next prev parent reply other threads:[~2011-07-21 11:00 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-07-20 9:57 [Cluster-devel] tunegfs2: Fix label/locktable setting code Steven Whitehouse
2011-07-21 11:00 ` Andrew Price [this message]
2011-07-22 8:34 ` Steven Whitehouse
-- strict thread matches above, loose matches on Subject: below --
2011-07-14 14:20 Steven Whitehouse
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4E2806D9.3000403@redhat.com \
--to=anprice@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).