On Sunday 04 August 2013 14:08:54 Dennis Groenen wrote:
> We already had the mount opts from fstab, but didn't do anything with them.
> 
> Check mnt_opts and set g_flags accordingly prior to enabling the swapspace 
> when
> we do_em_all().
> 
> Signed-off-by: Dennis Groenen <tj.groenen at gmail.com>
> ---
>  util-linux/Config.src  |    5 +++--
>  util-linux/swaponoff.c |   13 +++++++++++++
>  2 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/util-linux/Config.src b/util-linux/Config.src
> index 5a8b006..b90873d 100644
> --- a/util-linux/Config.src
> +++ b/util-linux/Config.src
> @@ -600,11 +600,12 @@ config SWAPONOFF
>         option disabled.
> 
>  config FEATURE_SWAPON_PRI
> -     bool "Support priority option -p"
> +     bool "Support priority options"
>       default y
>       depends on SWAPONOFF
>       help
> -       Enable support for setting swap device priority in swapon.
> +       Enable support for setting swap device priority in swapon. Also makes
> +       swapon respect 'pri=n' when enabling all swaps from /etc/fstab.
> 
>  config SWITCH_ROOT
>       bool "switch_root"
> diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c
> index 54867ec..97f668e 100644
> --- a/util-linux/swaponoff.c
> +++ b/util-linux/swaponoff.c
> @@ -95,6 +95,19 @@ static int do_em_all(void)
>                       if (applet_name[5] != 'n'
>                        || hasmntopt(m, MNTOPT_NOAUTO) == NULL
>                       ) {
> +#if ENABLE_FEATURE_SWAPON_PRI /* from util-linux-ng 2.17.2 */
> +                             char *opt, *opts;
> +
> +                             g_flags = 0; /* each swap space might have 
> different flags */
> +                             opts = strdup(m->mnt_opts);
> +                             for (opt = strtok(opts, ","); opt != NULL;
> +                                      opt = strtok(NULL, ",")) {
> +                                     if (strncmp(opt, "pri=", 4) == 0)
> +                                             g_flags = SWAP_FLAG_PREFER |
> +                                                     ((atoi(opt+4) & 
> SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT);
> +                             }
> +                             if (ENABLE_FEATURE_CLEAN_UP) free(opts);
> +#endif
>                               err += swap_enable_disable(m->mnt_fsname);
>                       }
>               }
> 

Hi,
I would suggest to add a little more error checking to to parameters parsed 
from fstab.


--- util-linux/swaponoff.c.original     2013-06-02 13:56:34.000000000 +0200
+++ util-linux/swaponoff.c      2013-08-04 23:42:02.497847999 +0200
@@ -82,6 +82,8 @@ static int do_em_all(void)
        struct mntent *m;
        FILE *f;
        int err;
+       char *p;
+       int swap_prio;
 
        f = setmntent("/etc/fstab", "r");
        if (f == NULL)
@@ -95,6 +97,16 @@ static int do_em_all(void)
                        if (applet_name[5] != 'n'
                         || hasmntopt(m, MNTOPT_NOAUTO) == NULL
                        ) {
+                               g_flags = 0; /* each swap space might have 
different flags */
+                               p = strstr(m->mnt_opts, "pri=");
+                               if (p) {
+                                       /* Max allowed 32767 */
+                                       swap_prio = MIN(bb_strtoull(p + 4 , 
NULL, 10), 32767);
+                                       if (errno != ERANGE) {
+                                               g_flags = SWAP_FLAG_PREFER | 
+                                                               ((swap_prio & 
SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT);
+                                       }
+                               }
                                err += swap_enable_disable(m->mnt_fsname);
                        }
                }



This behaves the same as real swapon -a when:
pri is negative (skipped)
pri is bigger than 32767 (set to 32767)

the only difference is we don't handle

pri=1somechars

which we ignore and real swapon parses to

pri=1


BTW: Denys, due to my limited understanding of  this complex issues i wonder why
         we handle 1111xxxx as an ERANGE error in bb_strtonum.c

static unsigned long long handle_errors(unsigned long long v, char **endp)
{
        char next_ch = **endp;

        /* errno is already set to ERANGE by strtoXXX if value overflowed */
        if (next_ch) {
                /* "1234abcg" or out-of-range? */
                if (isalnum(next_ch) || errno)
                        return ret_ERANGE();
                /* good number, just suspicious terminator */
                errno = EINVAL;
        }
        return v;
}

as the test app in the strtol man page says:

       /* If we got here, strtol() successfully parsed a number */

           printf("strtol() returned %ld\n", val);

           if (*endptr != '\0')        /* Not necessarily an error... */
               printf("Further characters after number: %s\n", endptr);


So if it is not necessarily an error shouldn't we do something like:

static unsigned long long handle_errors(unsigned long long v, char **endp)
{
        char next_ch = **endp;

        /* errno is already set to ERANGE by strtoXXX if value overflowed */
        if (next_ch) {
                /* "1234abcg" or out-of-range? */
                if (isalnum(next_ch) {
                        if (errno == ERANGE) {
                                return ret_ERANGE();
                        } else {
                                errno = EINVAL;
                        }
                }
        }
        return v;
}

Maybe I'm just to tired now.....


Ciao,
Tito


Add priority handling to swapon -a with error checking

Signed-off-by: Tito Ragusa <farmat...@tiscali.it>

--- util-linux/swaponoff.c.original	2013-06-02 13:56:34.000000000 +0200
+++ util-linux/swaponoff.c	2013-08-04 23:42:02.497847999 +0200
@@ -82,6 +82,8 @@ static int do_em_all(void)
 	struct mntent *m;
 	FILE *f;
 	int err;
+	char *p;
+	int swap_prio;
 
 	f = setmntent("/etc/fstab", "r");
 	if (f == NULL)
@@ -95,6 +97,16 @@ static int do_em_all(void)
 			if (applet_name[5] != 'n'
 			 || hasmntopt(m, MNTOPT_NOAUTO) == NULL
 			) {
+				g_flags = 0; /* each swap space might have different flags */
+				p = strstr(m->mnt_opts, "pri=");
+				if (p) {
+					/* Max allowed 32767 */
+					swap_prio = MIN(bb_strtoull(p + 4 , NULL, 10), 32767);
+					if (errno != ERANGE) {
+						g_flags = SWAP_FLAG_PREFER | 
+								((swap_prio & SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT);
+					}
+				}
 				err += swap_enable_disable(m->mnt_fsname);
 			}
 		}
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to