swaponoff.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. //usage:#define swapon_trivial_usage
  10. //usage: "[-a]" IF_FEATURE_SWAPON_PRI(" [-p PRI]") " [DEVICE]"
  11. //usage:#define swapon_full_usage "\n\n"
  12. //usage: "Start swapping on DEVICE\n"
  13. //usage: "\n -a Start swapping on all swap devices"
  14. //usage: IF_FEATURE_SWAPON_PRI(
  15. //usage: "\n -p PRI Set swap device priority"
  16. //usage: )
  17. //usage:
  18. //usage:#define swapoff_trivial_usage
  19. //usage: "[-a] [DEVICE]"
  20. //usage:#define swapoff_full_usage "\n\n"
  21. //usage: "Stop swapping on DEVICE\n"
  22. //usage: "\n -a Stop swapping on all swap devices"
  23. #include "libbb.h"
  24. #include <mntent.h>
  25. #ifndef __BIONIC__
  26. # include <sys/swap.h>
  27. #endif
  28. #if ENABLE_FEATURE_MOUNT_LABEL
  29. # include "volume_id.h"
  30. #else
  31. # define resolve_mount_spec(fsname) ((void)0)
  32. #endif
  33. #ifndef MNTTYPE_SWAP
  34. # define MNTTYPE_SWAP "swap"
  35. #endif
  36. #if ENABLE_FEATURE_SWAPON_PRI
  37. struct globals {
  38. int flags;
  39. } FIX_ALIASING;
  40. #define G (*(struct globals*)&bb_common_bufsiz1)
  41. #define g_flags (G.flags)
  42. #else
  43. #define g_flags 0
  44. #endif
  45. #define INIT_G() do { } while (0)
  46. static int swap_enable_disable(char *device)
  47. {
  48. int status;
  49. struct stat st;
  50. resolve_mount_spec(&device);
  51. xstat(device, &st);
  52. #if ENABLE_DESKTOP
  53. /* test for holes */
  54. if (S_ISREG(st.st_mode))
  55. if (st.st_blocks * (off_t)512 < st.st_size)
  56. bb_error_msg("warning: swap file has holes");
  57. #endif
  58. if (applet_name[5] == 'n')
  59. status = swapon(device, g_flags);
  60. else
  61. status = swapoff(device);
  62. if (status != 0) {
  63. bb_simple_perror_msg(device);
  64. return 1;
  65. }
  66. return 0;
  67. }
  68. static int do_em_all(void)
  69. {
  70. struct mntent *m;
  71. FILE *f;
  72. int err;
  73. f = setmntent("/etc/fstab", "r");
  74. if (f == NULL)
  75. bb_perror_msg_and_die("/etc/fstab");
  76. err = 0;
  77. while ((m = getmntent(f)) != NULL) {
  78. if (strcmp(m->mnt_type, MNTTYPE_SWAP) == 0) {
  79. /* swapon -a should ignore entries with noauto,
  80. * but swapoff -a should process them */
  81. if (applet_name[5] != 'n'
  82. || hasmntopt(m, MNTOPT_NOAUTO) == NULL
  83. ) {
  84. err += swap_enable_disable(m->mnt_fsname);
  85. }
  86. }
  87. }
  88. if (ENABLE_FEATURE_CLEAN_UP)
  89. endmntent(f);
  90. return err;
  91. }
  92. int swap_on_off_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  93. int swap_on_off_main(int argc UNUSED_PARAM, char **argv)
  94. {
  95. int ret;
  96. INIT_G();
  97. #if !ENABLE_FEATURE_SWAPON_PRI
  98. ret = getopt32(argv, "a");
  99. #else
  100. if (applet_name[5] == 'n')
  101. opt_complementary = "p+";
  102. ret = getopt32(argv, (applet_name[5] == 'n') ? "ap:" : "a", &g_flags);
  103. if (ret & 2) { // -p
  104. g_flags = SWAP_FLAG_PREFER |
  105. ((g_flags & SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT);
  106. ret &= 1;
  107. }
  108. #endif
  109. if (ret /* & 1: not needed */) // -a
  110. return do_em_all();
  111. argv += optind;
  112. if (!*argv)
  113. bb_show_usage();
  114. /* ret = 0; redundant */
  115. do {
  116. ret += swap_enable_disable(*argv);
  117. } while (*++argv);
  118. return ret;
  119. }