Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/3.3/mindi-busybox/util-linux/swaponoff.c

    r3232 r3621  
    99
    1010//usage:#define swapon_trivial_usage
    11 //usage:       "[-a]" IF_FEATURE_SWAPON_PRI(" [-p PRI]") " [DEVICE]"
     11//usage:       "[-a] [-e]" IF_FEATURE_SWAPON_DISCARD(" [-d[POL]]") IF_FEATURE_SWAPON_PRI(" [-p PRI]") " [DEVICE]"
    1212//usage:#define swapon_full_usage "\n\n"
    1313//usage:       "Start swapping on DEVICE\n"
    1414//usage:     "\n    -a  Start swapping on all swap devices"
     15//usage:    IF_FEATURE_SWAPON_DISCARD(
     16//usage:     "\n    -d[POL] Discard blocks at swapon (POL=once),"
     17//usage:     "\n        as freed (POL=pages), or both (POL omitted)"
     18//usage:    )
     19//usage:     "\n    -e  Silently skip devices that do not exist"
    1520//usage:    IF_FEATURE_SWAPON_PRI(
    1621//usage:     "\n    -p PRI  Set swap device priority"
     
    2429
    2530#include "libbb.h"
     31#include "common_bufsiz.h"
    2632#include <mntent.h>
    2733#ifndef __BIONIC__
     
    3945#endif
    4046
    41 #if ENABLE_FEATURE_SWAPON_PRI
     47#if ENABLE_FEATURE_SWAPON_DISCARD
     48#ifndef SWAP_FLAG_DISCARD
     49#define SWAP_FLAG_DISCARD 0x10000
     50#endif
     51#ifndef SWAP_FLAG_DISCARD_ONCE
     52#define SWAP_FLAG_DISCARD_ONCE 0x20000
     53#endif
     54#ifndef SWAP_FLAG_DISCARD_PAGES
     55#define SWAP_FLAG_DISCARD_PAGES 0x40000
     56#endif
     57#define SWAP_FLAG_DISCARD_MASK \
     58    (SWAP_FLAG_DISCARD | SWAP_FLAG_DISCARD_ONCE | SWAP_FLAG_DISCARD_PAGES)
     59#endif
     60
     61
     62#if ENABLE_FEATURE_SWAPON_DISCARD || ENABLE_FEATURE_SWAPON_PRI
    4263struct globals {
    4364    int flags;
    4465} FIX_ALIASING;
    45 #define G (*(struct globals*)&bb_common_bufsiz1)
     66#define G (*(struct globals*)bb_common_bufsiz1)
    4667#define g_flags (G.flags)
     68#define save_g_flags()    int save_g_flags = g_flags
     69#define restore_g_flags() g_flags = save_g_flags
    4770#else
    4871#define g_flags 0
    49 #endif
    50 #define INIT_G() do { } while (0)
     72#define save_g_flags()    ((void)0)
     73#define restore_g_flags() ((void)0)
     74#endif
     75#define INIT_G() do { setup_common_bufsiz(); } while (0)
     76
     77#define do_swapoff   (applet_name[5] == 'f')
     78
     79/* Command line options */
     80enum {
     81    OPTBIT_a,                              /* -a all      */
     82    OPTBIT_e,                              /* -e ifexists */
     83    IF_FEATURE_SWAPON_DISCARD( OPTBIT_d ,) /* -d discard  */
     84    IF_FEATURE_SWAPON_PRI    ( OPTBIT_p ,) /* -p priority */
     85    OPT_a = 1 << OPTBIT_a,
     86    OPT_e = 1 << OPTBIT_e,
     87    OPT_d = IF_FEATURE_SWAPON_DISCARD((1 << OPTBIT_d)) + 0,
     88    OPT_p = IF_FEATURE_SWAPON_PRI    ((1 << OPTBIT_p)) + 0,
     89};
     90
     91#define OPT_ALL      (option_mask32 & OPT_a)
     92#define OPT_DISCARD  (option_mask32 & OPT_d)
     93#define OPT_IFEXISTS (option_mask32 & OPT_e)
     94#define OPT_PRIO     (option_mask32 & OPT_p)
    5195
    5296static int swap_enable_disable(char *device)
    5397{
    54     int status;
    55     struct stat st;
     98    int err = 0;
     99    int quiet = 0;
    56100
    57101    resolve_mount_spec(&device);
    58     xstat(device, &st);
    59 
    60 #if ENABLE_DESKTOP
    61     /* test for holes */
    62     if (S_ISREG(st.st_mode))
    63         if (st.st_blocks * (off_t)512 < st.st_size)
    64             bb_error_msg("warning: swap file has holes");
    65 #endif
    66 
    67     if (applet_name[5] == 'n')
    68         status = swapon(device, g_flags);
    69     else
    70         status = swapoff(device);
    71 
    72     if (status != 0) {
     102
     103    if (do_swapoff) {
     104        err = swapoff(device);
     105        /* Don't complain on OPT_ALL if not a swap device or if it doesn't exist */
     106        quiet = (OPT_ALL && (errno == EINVAL || errno == ENOENT));
     107    } else {
     108        /* swapon */
     109        struct stat st;
     110        err = stat(device, &st);
     111        if (!err) {
     112            if (ENABLE_DESKTOP && S_ISREG(st.st_mode)) {
     113                if (st.st_blocks * (off_t)512 < st.st_size) {
     114                    bb_error_msg("%s: file has holes", device);
     115                    return 1;
     116                }
     117            }
     118            err = swapon(device, g_flags);
     119            /* Don't complain on swapon -a if device is already in use */
     120            quiet = (OPT_ALL && errno == EBUSY);
     121        }
     122        /* Don't complain if file does not exist with -e option */
     123        if (err && OPT_IFEXISTS && errno == ENOENT)
     124            err = 0;
     125    }
     126
     127    if (err && !quiet) {
    73128        bb_simple_perror_msg(device);
    74129        return 1;
    75130    }
    76 
    77131    return 0;
    78132}
    79133
    80 static int do_em_all(void)
     134#if ENABLE_FEATURE_SWAPON_DISCARD
     135static void set_discard_flag(char *s)
     136{
     137    /* Unset the flag first to allow fstab options to override */
     138    /* options set on the command line */
     139    g_flags = (g_flags & ~SWAP_FLAG_DISCARD_MASK) | SWAP_FLAG_DISCARD;
     140
     141    if (!s) /* No optional policy value on the commandline */
     142        return;
     143    /* Skip prepended '=' */
     144    if (*s == '=')
     145        s++;
     146    /* For fstab parsing: remove other appended options */
     147    *strchrnul(s, ',') = '\0';
     148
     149    if (strcmp(s, "once") == 0)
     150        g_flags |= SWAP_FLAG_DISCARD_ONCE;
     151    if  (strcmp(s, "pages") == 0)
     152        g_flags |= SWAP_FLAG_DISCARD_PAGES;
     153}
     154#else
     155#define set_discard_flag(s) ((void)0)
     156#endif
     157
     158#if ENABLE_FEATURE_SWAPON_PRI
     159static void set_priority_flag(char *s)
     160{
     161    unsigned prio;
     162
     163    /* For fstab parsing: remove other appended options */
     164    *strchrnul(s, ',') = '\0';
     165    /* Max allowed 32767 (== SWAP_FLAG_PRIO_MASK) */
     166    prio = bb_strtou(s, NULL, 10);
     167    if (!errno) {
     168        /* Unset the flag first to allow fstab options to override */
     169        /* options set on the command line */
     170        g_flags = (g_flags & ~SWAP_FLAG_PRIO_MASK) | SWAP_FLAG_PREFER |
     171                    MIN(prio, SWAP_FLAG_PRIO_MASK);
     172    }
     173}
     174#else
     175#define set_priority_flag(s) ((void)0)
     176#endif
     177
     178static int do_em_all_in_fstab(void)
    81179{
    82180    struct mntent *m;
    83     FILE *f;
    84     int err;
    85 
    86     f = setmntent("/etc/fstab", "r");
    87     if (f == NULL)
    88         bb_perror_msg_and_die("/etc/fstab");
    89 
    90     err = 0;
     181    int err = 0;
     182    FILE *f = xfopen_for_read("/etc/fstab");
     183
    91184    while ((m = getmntent(f)) != NULL) {
    92185        if (strcmp(m->mnt_type, MNTTYPE_SWAP) == 0) {
    93186            /* swapon -a should ignore entries with noauto,
    94              * but swapoff -a should process them */
    95             if (applet_name[5] != 'n'
    96              || hasmntopt(m, MNTOPT_NOAUTO) == NULL
    97             ) {
    98                 err += swap_enable_disable(m->mnt_fsname);
     187             * but swapoff -a should process them
     188             */
     189            if (do_swapoff || hasmntopt(m, MNTOPT_NOAUTO) == NULL) {
     190                /* each swap space might have different flags */
     191                /* save global flags for the next round */
     192                save_g_flags();
     193                if (ENABLE_FEATURE_SWAPON_DISCARD) {
     194                    char *p = hasmntopt(m, "discard");
     195                    if (p) {
     196                        /* move to '=' or to end of string */
     197                        p += 7;
     198                        set_discard_flag(p);
     199                    }
     200                }
     201                if (ENABLE_FEATURE_SWAPON_PRI) {
     202                    char *p = hasmntopt(m, "pri");
     203                    if (p) {
     204                        set_priority_flag(p + 4);
     205                    }
     206                }
     207                err |= swap_enable_disable(m->mnt_fsname);
     208                restore_g_flags();
    99209            }
    100210        }
     
    107217}
    108218
     219static int do_all_in_proc_swaps(void)
     220{
     221    char *line;
     222    int err = 0;
     223    FILE *f = fopen_for_read("/proc/swaps");
     224    /* Don't complain if missing */
     225    if (f) {
     226        while ((line = xmalloc_fgetline(f)) != NULL) {
     227            if (line[0] == '/') {
     228                *strchrnul(line, ' ') = '\0';
     229                err |= swap_enable_disable(line);
     230            }
     231            free(line);
     232        }
     233        if (ENABLE_FEATURE_CLEAN_UP)
     234            fclose(f);
     235    }
     236
     237    return err;
     238}
     239
     240#define OPTSTR_SWAPON "ae" \
     241    IF_FEATURE_SWAPON_DISCARD("d::") \
     242    IF_FEATURE_SWAPON_PRI("p:")
     243
    109244int swap_on_off_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    110245int swap_on_off_main(int argc UNUSED_PARAM, char **argv)
    111246{
    112     int ret;
     247    IF_FEATURE_SWAPON_PRI(char *prio;)
     248    IF_FEATURE_SWAPON_DISCARD(char *discard = NULL;)
     249    int ret = 0;
    113250
    114251    INIT_G();
    115252
    116 #if !ENABLE_FEATURE_SWAPON_PRI
    117     ret = getopt32(argv, "a");
    118 #else
    119     if (applet_name[5] == 'n')
    120         opt_complementary = "p+";
    121     ret = getopt32(argv, (applet_name[5] == 'n') ? "ap:" : "a", &g_flags);
    122 
    123     if (ret & 2) { // -p
    124         g_flags = SWAP_FLAG_PREFER |
    125             ((g_flags & SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT);
    126         ret &= 1;
    127     }
    128 #endif
    129 
    130     if (ret /* & 1: not needed */) // -a
    131         return do_em_all();
     253    getopt32(argv, do_swapoff ? "ae" : OPTSTR_SWAPON
     254            IF_FEATURE_SWAPON_DISCARD(, &discard)
     255            IF_FEATURE_SWAPON_PRI(, &prio)
     256    );
    132257
    133258    argv += optind;
    134     if (!*argv)
     259
     260    if (OPT_DISCARD) {
     261        set_discard_flag(discard);
     262    }
     263    if (OPT_PRIO) {
     264        set_priority_flag(prio);
     265    }
     266
     267    if (OPT_ALL) {
     268        /* swapoff -a does also /proc/swaps */
     269        if (do_swapoff)
     270            ret = do_all_in_proc_swaps();
     271        ret |= do_em_all_in_fstab();
     272    } else if (!*argv) {
     273        /* if not -a we need at least one arg */
    135274        bb_show_usage();
    136 
    137     /* ret = 0; redundant */
    138     do {
    139         ret += swap_enable_disable(*argv);
    140     } while (*++argv);
    141 
     275    }
     276    /* Unset -a now to allow for more messages in swap_enable_disable */
     277    option_mask32 = option_mask32 & ~OPT_a;
     278    /* Now process devices on the commandline if any */
     279    while (*argv) {
     280        ret |= swap_enable_disable(*argv++);
     281    }
    142282    return ret;
    143283}
Note: See TracChangeset for help on using the changeset viewer.