blob: 863f7734a2b62fdc33c1797c3117d94723749b0c [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersen87590061999-10-18 21:22:59 +00002/*
3 * Mini swapon/swapoff implementation for busybox
4 *
Eric Andersenc7bda1c2004-03-15 08:29:22 +00005 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
Eric Andersen87590061999-10-18 21:22:59 +00006 *
Rob Landleye9a7a622006-09-22 02:52:41 +00007 * Licensed under the GPL version 2, see the file LICENSE in this tarball.
Eric Andersen87590061999-10-18 21:22:59 +00008 */
9
Denis Vlasenkob6adbf12007-05-26 19:00:18 +000010#include "libbb.h"
Eric Andersen87590061999-10-18 21:22:59 +000011#include <mntent.h>
Eric Andersene76c3b02001-04-05 03:14:39 +000012#include <sys/swap.h>
Eric Andersene76c3b02001-04-05 03:14:39 +000013
Denis Vlasenkoee56e012008-05-18 23:05:34 +000014#if ENABLE_FEATURE_SWAPON_PRI
15struct globals {
16 int flags;
17};
18#define G (*(struct globals*)&bb_common_bufsiz1)
19#define g_flags (G.flags)
20#else
21#define g_flags 0
22#endif
23
Rob Landley20cc6d52006-09-12 21:42:17 +000024static int swap_enable_disable(char *device)
Eric Andersen87590061999-10-18 21:22:59 +000025{
Erik Andersene49d5ec2000-02-08 19:58:47 +000026 int status;
Eric Andersen97b141a2002-11-03 00:25:23 +000027 struct stat st;
28
Rob Landleyc5b1d4d2006-03-13 15:45:16 +000029 xstat(device, &st);
Eric Andersen97b141a2002-11-03 00:25:23 +000030
Denis Vlasenko56594072007-03-14 22:55:39 +000031#if ENABLE_DESKTOP
Eric Andersen97b141a2002-11-03 00:25:23 +000032 /* test for holes */
Mike Frysinger6943a942005-09-13 02:29:39 +000033 if (S_ISREG(st.st_mode))
Denis Vlasenkof8b21d02007-11-05 19:33:38 +000034 if (st.st_blocks * (off_t)512 < st.st_size)
Denis Vlasenko56594072007-03-14 22:55:39 +000035 bb_error_msg("warning: swap file has holes");
Denis Vlasenkob3f09f42007-03-12 18:16:24 +000036#endif
Eric Andersen87590061999-10-18 21:22:59 +000037
Denis Vlasenko8f8f2682006-10-03 21:00:43 +000038 if (applet_name[5] == 'n')
Denis Vlasenkoee56e012008-05-18 23:05:34 +000039 status = swapon(device, g_flags);
Erik Andersene49d5ec2000-02-08 19:58:47 +000040 else
41 status = swapoff(device);
42
Eric Andersendb1df5e2002-10-26 10:27:42 +000043 if (status != 0) {
Denis Vlasenko0c97c9d2007-10-01 11:58:38 +000044 bb_simple_perror_msg(device);
Mike Frysinger2d5e4f62005-09-16 04:41:20 +000045 return 1;
Eric Andersendb1df5e2002-10-26 10:27:42 +000046 }
Mike Frysinger6943a942005-09-13 02:29:39 +000047
Mike Frysinger2d5e4f62005-09-16 04:41:20 +000048 return 0;
Eric Andersen87590061999-10-18 21:22:59 +000049}
50
Eric Andersendb1df5e2002-10-26 10:27:42 +000051static int do_em_all(void)
Eric Andersen87590061999-10-18 21:22:59 +000052{
53 struct mntent *m;
Mike Frysinger6943a942005-09-13 02:29:39 +000054 FILE *f;
55 int err;
Eric Andersen87590061999-10-18 21:22:59 +000056
Mike Frysinger6943a942005-09-13 02:29:39 +000057 f = setmntent("/etc/fstab", "r");
Matt Kraaia9819b22000-12-22 01:48:07 +000058 if (f == NULL)
Manuel Novoa III cad53642003-03-19 09:13:01 +000059 bb_perror_msg_and_die("/etc/fstab");
Mike Frysinger6943a942005-09-13 02:29:39 +000060
61 err = 0;
62 while ((m = getmntent(f)) != NULL)
63 if (strcmp(m->mnt_type, MNTTYPE_SWAP) == 0)
Mike Frysinger2d5e4f62005-09-16 04:41:20 +000064 err += swap_enable_disable(m->mnt_fsname);
Mike Frysinger6943a942005-09-13 02:29:39 +000065
Erik Andersene49d5ec2000-02-08 19:58:47 +000066 endmntent(f);
Mike Frysinger6943a942005-09-13 02:29:39 +000067
Eric Andersendb1df5e2002-10-26 10:27:42 +000068 return err;
Eric Andersen87590061999-10-18 21:22:59 +000069}
70
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +000071int swap_on_off_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denis Vlasenkoa60f84e2008-07-05 09:18:54 +000072int swap_on_off_main(int argc UNUSED_PARAM, char **argv)
Eric Andersen87590061999-10-18 21:22:59 +000073{
Mike Frysinger2d5e4f62005-09-16 04:41:20 +000074 int ret;
Mike Frysinger6943a942005-09-13 02:29:39 +000075
Denis Vlasenkoee56e012008-05-18 23:05:34 +000076#if !ENABLE_FEATURE_SWAPON_PRI
Denis Vlasenkofe7cd642007-08-18 15:32:12 +000077 ret = getopt32(argv, "a");
Denis Vlasenkoee56e012008-05-18 23:05:34 +000078#else
79 opt_complementary = "p+";
80 ret = getopt32(argv, (applet_name[5] == 'n') ? "ap:" : "a", &g_flags);
81
82 if (ret & 2) { // -p
83 g_flags = SWAP_FLAG_PREFER |
84 ((g_flags & SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT);
85 ret &= 1;
86 }
87#endif
88
89 if (ret /* & 1: not needed */) // -a
Rob Landleybc3d4a12005-09-13 01:30:19 +000090 return do_em_all();
Mike Frysinger6943a942005-09-13 02:29:39 +000091
Denis Vlasenkoee56e012008-05-18 23:05:34 +000092 argv += optind;
93 if (!*argv)
94 bb_show_usage();
95
Denis Vlasenkob3f09f42007-03-12 18:16:24 +000096 /* ret = 0; redundant */
Denis Vlasenkoee56e012008-05-18 23:05:34 +000097 do {
Mike Frysinger2d5e4f62005-09-16 04:41:20 +000098 ret += swap_enable_disable(*argv);
Denis Vlasenkoee56e012008-05-18 23:05:34 +000099 } while (*++argv);
100
Mike Frysinger2d5e4f62005-09-16 04:41:20 +0000101 return ret;
Eric Andersen87590061999-10-18 21:22:59 +0000102}