toolbox: swap utils

Add swap utilities (mkswap, swapon, swapoff) to the toolbox

Change-Id: If5ed6981670a1cdda6b528b587dbc1be7ccdf832
Signed-off-by: Rom Lemarchand <romlem@google.com>
This commit is contained in:
Rom Lemarchand 2013-06-05 13:25:12 -07:00
parent 25383a5da2
commit 367297c3d7
4 changed files with 192 additions and 1 deletions

View file

@ -65,7 +65,10 @@ TOOLS := \
runcon \
getsebool \
setsebool \
load_policy
load_policy \
swapon \
swapoff \
mkswap
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
TOOLS += r

94
toolbox/mkswap.c Normal file
View file

@ -0,0 +1,94 @@
#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;
}

21
toolbox/swapoff.c Normal file
View file

@ -0,0 +1,21 @@
#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;
}

73
toolbox/swapon.c Normal file
View file

@ -0,0 +1,73 @@
#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;
}