swaponoff.c 2.2 KB

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