busybox/util-linux/swaponoff.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Mini swapon/swapoff implementation for busybox
   4 *
   5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
   6 *
   7 * Licensed under GPLv2, see file LICENSE in this source tree.
   8 */
   9
  10//usage:#define swapon_trivial_usage
  11//usage:       "[-a]" IF_FEATURE_SWAPON_PRI(" [-p PRI]") " [DEVICE]"
  12//usage:#define swapon_full_usage "\n\n"
  13//usage:       "Start swapping on DEVICE\n"
  14//usage:     "\n        -a      Start swapping on all swap devices"
  15//usage:        IF_FEATURE_SWAPON_PRI(
  16//usage:     "\n        -p PRI  Set swap device priority"
  17//usage:        )
  18//usage:
  19//usage:#define swapoff_trivial_usage
  20//usage:       "[-a] [DEVICE]"
  21//usage:#define swapoff_full_usage "\n\n"
  22//usage:       "Stop swapping on DEVICE\n"
  23//usage:     "\n        -a      Stop swapping on all swap devices"
  24
  25#include "libbb.h"
  26#include <mntent.h>
  27#include <sys/swap.h>
  28#ifndef __BIONIC__
  29# include <sys/swap.h>
  30#endif
  31
  32#if ENABLE_FEATURE_MOUNT_LABEL
  33# include "volume_id.h"
  34#else
  35# define resolve_mount_spec(fsname) ((void)0)
  36#endif
  37
  38#ifndef MNTTYPE_SWAP
  39# define MNTTYPE_SWAP "swap"
  40#endif
  41
  42#if ENABLE_FEATURE_SWAPON_PRI
  43struct globals {
  44        int flags;
  45} FIX_ALIASING;
  46#define G (*(struct globals*)&bb_common_bufsiz1)
  47#define g_flags (G.flags)
  48#else
  49#define g_flags 0
  50#endif
  51
  52static int swap_enable_disable(char *device)
  53{
  54        int status;
  55        struct stat st;
  56
  57        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) {
  73                bb_simple_perror_msg(device);
  74                return 1;
  75        }
  76
  77        return 0;
  78}
  79
  80static int do_em_all(void)
  81{
  82        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;
  91        while ((m = getmntent(f)) != NULL) {
  92                if (strcmp(m->mnt_type, MNTTYPE_SWAP) == 0) {
  93                        /* 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);
  99                        }
 100                }
 101        }
 102
 103        if (ENABLE_FEATURE_CLEAN_UP)
 104                endmntent(f);
 105
 106        return err;
 107}
 108
 109int swap_on_off_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 110int swap_on_off_main(int argc UNUSED_PARAM, char **argv)
 111{
 112        int ret;
 113
 114#if !ENABLE_FEATURE_SWAPON_PRI
 115        ret = getopt32(argv, "a");
 116#else
 117        if (applet_name[5] == 'n')
 118                opt_complementary = "p+";
 119        ret = getopt32(argv, (applet_name[5] == 'n') ? "ap:" : "a", &g_flags);
 120
 121        if (ret & 2) { // -p
 122                g_flags = SWAP_FLAG_PREFER |
 123                        ((g_flags & SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT);
 124                ret &= 1;
 125        }
 126#endif
 127
 128        if (ret /* & 1: not needed */) // -a
 129                return do_em_all();
 130
 131        argv += optind;
 132        if (!*argv)
 133                bb_show_usage();
 134
 135        /* ret = 0; redundant */
 136        do {
 137                ret += swap_enable_disable(*argv);
 138        } while (*++argv);
 139
 140        return ret;
 141}
 142