1367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand#include <stdio.h>
2367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand#include <stdlib.h>
3367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand#include <unistd.h>
4367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand#include <getopt.h>
5367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand#include <asm/page.h>
6367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand#include <sys/swap.h>
7367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand
8367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand/* XXX These need to be obtained from kernel headers. See b/9336527 */
9367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand#define SWAP_FLAG_PREFER        0x8000
10367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand#define SWAP_FLAG_PRIO_MASK     0x7fff
11367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand#define SWAP_FLAG_PRIO_SHIFT    0
12367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand#define SWAP_FLAG_DISCARD       0x10000
13367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand
14367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchandvoid usage(char *name)
15367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand{
16367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    fprintf(stderr, "Usage: %s [-p prio] <filename>\n"
17367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand        "        prio must be between 0 and %d\n", name, SWAP_FLAG_PRIO_MASK);
18367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand}
19367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand
20367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchandint parse_prio(char *prio_str)
21367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand{
22367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    unsigned long p = strtoul(prio_str, NULL, 10);
23367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand
24367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    return (p > SWAP_FLAG_PRIO_MASK)? -1 : (int)p;
25367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand}
26367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand
27367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchandint swapon_main(int argc, char **argv)
28367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand{
29367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    int err = 0;
30367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    int flags = 0;
31367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    int prio;
32367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand
33367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    opterr = 0;
34367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    do {
35367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand        int c = getopt(argc, argv, "hp:");
36367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand        if (c == -1)
37367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand            break;
38367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand
39367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand        switch (c) {
40367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand            case 'p':
41367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                if (optarg != NULL)
42367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                    prio = parse_prio(optarg);
43367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                else
44367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                    prio = -1;
45367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand
46367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                if (prio < 0) {
47367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                    usage(argv[0]);
48367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                    return -EINVAL;
49367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                }
50367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                flags |= SWAP_FLAG_PREFER;
51367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                flags |= (prio << SWAP_FLAG_PRIO_SHIFT) & SWAP_FLAG_PRIO_MASK;
52367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                break;
53367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand            case 'h':
54367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                usage(argv[0]);
55367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                return 0;
56367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand            case '?':
57367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                fprintf(stderr, "unknown option: %c\n", optopt);
58367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand                return -EINVAL;
59367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand        }
60367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    } while (1);
61367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand
62367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    if (optind != argc - 1) {
63367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand        usage(argv[0]);
64367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand        return -EINVAL;
65367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    }
66367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand
67367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    err = swapon(argv[argc - 1], flags);
68367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    if (err) {
69367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand        fprintf(stderr, "swapon failed for %s\n", argv[argc - 1]);
70367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    }
71367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand
72367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand    return err;
73367297c3d764eaf6e60880964e1739df13f0b703Rom Lemarchand}
74