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:
parent
25383a5da2
commit
367297c3d7
4 changed files with 192 additions and 1 deletions
|
@ -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
94
toolbox/mkswap.c
Normal 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
21
toolbox/swapoff.c
Normal 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
73
toolbox/swapon.c
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue