Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb328088 authored by Rom Lemarchand's avatar Rom Lemarchand Committed by Android (Google) Code Review
Browse files

Merge "toolbox: swap utils"

parents 622810ce 367297c3
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -65,7 +65,10 @@ TOOLS := \
	runcon \
	getsebool \
	setsebool \
	load_policy
	load_policy \
	swapon \
	swapoff \
	mkswap

ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
TOOLS += r

toolbox/mkswap.c

0 → 100644
+94 −0
Original line number Diff line number Diff line
#include <stdio.h>
#include <unistd.h>
#include <asm/page.h>
#include <sys/swap.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

/* XXX This needs to be obtained from kernel headers. See b/9336527 */
struct linux_swap_header {
    char            bootbits[1024]; /* Space for disklabel etc. */
    uint32_t        version;
    uint32_t        last_page;
    uint32_t        nr_badpages;
    unsigned char   sws_uuid[16];
    unsigned char   sws_volume[16];
    uint32_t        padding[117];
    uint32_t        badpages[1];
};

#define MAGIC_SWAP_HEADER     "SWAPSPACE2"
#define MAGIC_SWAP_HEADER_LEN 10
#define MIN_PAGES             10

int mkswap_main(int argc, char **argv)
{
    int err = 0;
    int fd;
    ssize_t len;
    off_t swap_size;
    int pagesize;
    struct linux_swap_header sw_hdr;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
        return -EINVAL;
    }

    fd = open(argv[1], O_WRONLY);
    if (fd < 0) {
        err = errno;
        fprintf(stderr, "Cannot open %s\n", argv[1]);
        return err;
    }

    pagesize = getpagesize();
    /* Determine the length of the swap file */
    swap_size = lseek(fd, 0, SEEK_END);
    if (swap_size < MIN_PAGES * pagesize) {
        fprintf(stderr, "Swap file needs to be at least %dkB\n",
            (MIN_PAGES * pagesize) >> 10);
        err = -ENOSPC;
        goto err;
    }
    if (lseek(fd, 0, SEEK_SET)) {
        err = errno;
        fprintf(stderr, "Can't seek to the beginning of the file\n");
        goto err;
    }

    memset(&sw_hdr, 0, sizeof(sw_hdr));
    sw_hdr.version = 1;
    sw_hdr.last_page = (swap_size / pagesize) - 1;

    len = write(fd, &sw_hdr, sizeof(sw_hdr));
    if (len != sizeof(sw_hdr)) {
        err = errno;
        fprintf(stderr, "Failed to write swap header into %s\n", argv[1]);
        goto err;
    }

    /* Write the magic header */
    if (lseek(fd, pagesize - MAGIC_SWAP_HEADER_LEN, SEEK_SET) < 0) {
        err = errno;
        fprintf(stderr, "Failed to seek into %s\n", argv[1]);
        goto err;
    }

    len = write(fd, MAGIC_SWAP_HEADER, MAGIC_SWAP_HEADER_LEN);
    if (len != MAGIC_SWAP_HEADER_LEN) {
        err = errno;
        fprintf(stderr, "Failed to write magic swap header into %s\n", argv[1]);
        goto err;
    }

    if (fsync(fd) < 0) {
        err = errno;
        fprintf(stderr, "Failed to sync %s\n", argv[1]);
        goto err;
    }
err:
    close(fd);
    return err;
}

toolbox/swapoff.c

0 → 100644
+21 −0
Original line number Diff line number Diff line
#include <stdio.h>
#include <unistd.h>
#include <asm/page.h>
#include <sys/swap.h>

int swapoff_main(int argc, char **argv)
{
    int err = 0;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
        return -EINVAL;
    }

    err = swapoff(argv[1]);
    if (err) {
        fprintf(stderr, "swapoff failed for %s\n", argv[1]);
    }

    return err;
}

toolbox/swapon.c

0 → 100644
+73 −0
Original line number Diff line number Diff line
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <asm/page.h>
#include <sys/swap.h>

/* XXX These need to be obtained from kernel headers. See b/9336527 */
#define SWAP_FLAG_PREFER        0x8000
#define SWAP_FLAG_PRIO_MASK     0x7fff
#define SWAP_FLAG_PRIO_SHIFT    0
#define SWAP_FLAG_DISCARD       0x10000

void usage(char *name)
{
    fprintf(stderr, "Usage: %s [-p prio] <filename>\n"
        "        prio must be between 0 and %d\n", name, SWAP_FLAG_PRIO_MASK);
}

int parse_prio(char *prio_str)
{
    unsigned long p = strtoul(prio_str, NULL, 10);

    return (p > SWAP_FLAG_PRIO_MASK)? -1 : (int)p;
}

int swapon_main(int argc, char **argv)
{
    int err = 0;
    int flags = 0;
    int prio;

    opterr = 0;
    do {
        int c = getopt(argc, argv, "hp:");
        if (c == -1)
            break;

        switch (c) {
            case 'p':
                if (optarg != NULL)
                    prio = parse_prio(optarg);
                else
                    prio = -1;

                if (prio < 0) {
                    usage(argv[0]);
                    return -EINVAL;
                }
                flags |= SWAP_FLAG_PREFER;
                flags |= (prio << SWAP_FLAG_PRIO_SHIFT) & SWAP_FLAG_PRIO_MASK;
                break;
            case 'h':
                usage(argv[0]);
                return 0;
            case '?':
                fprintf(stderr, "unknown option: %c\n", optopt);
                return -EINVAL;
        }
    } while (1);

    if (optind != argc - 1) {
        usage(argv[0]);
        return -EINVAL;
    }

    err = swapon(argv[argc - 1], flags);
    if (err) {
        fprintf(stderr, "swapon failed for %s\n", argv[argc - 1]);
    }

    return err;
}