Home | History | Annotate | Download | only in zram
      1 /*
      2  * zram: generic RAM based compressed R/W block devices
      3  * http://lkml.org/lkml/2010/8/9/227
      4  *
      5  * Copyright (C) 2010  Red Hat, Inc.
      6  * This program is free software; you can redistribute it and/or
      7  * modify it under the terms of version 2 of the GNU General Public
      8  * License as published by the Free Software Foundation.
      9  *
     10  * This program is distributed in the hope that it would be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     13  *
     14  * Further, this software is distributed without any warranty that it
     15  * is free of the rightful claim of any third person regarding
     16  * infringement or the like.  Any license provided herein, whether
     17  * implied or otherwise, applies only to this software file.  Patent
     18  * licenses, if any, provided herein do not apply to combinations of
     19  * this program with other software, or any other product whatsoever.
     20  *
     21  * You should have received a copy of the GNU General Public License
     22  * along with this program; if not, write the Free Software
     23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     24  * 02110-1301, USA.
     25  */
     26 
     27 #include <sys/types.h>
     28 #include <sys/stat.h>
     29 #include <sys/mman.h>
     30 #include <errno.h>
     31 #include <fcntl.h>
     32 #include <stdio.h>
     33 #include <string.h>
     34 #include <unistd.h>
     35 
     36 #include "test.h"
     37 #include "safe_macros.h"
     38 
     39 char *TCID = "zram03";
     40 int TST_TOTAL = 1;
     41 
     42 #define PATH_ZRAM	"/sys/block/zram0"
     43 #define SIZE		(512 * 1024 * 1024L)
     44 #define DEVICE		"/dev/zram0"
     45 
     46 static int modprobe;
     47 
     48 static void set_disksize(void);
     49 static void write_device(void);
     50 static void verify_device(void);
     51 static void reset(void);
     52 static void setup(void);
     53 static void cleanup(void);
     54 static void print(char *string);
     55 static void dump_info(void);
     56 
     57 int main(int argc, char *argv[])
     58 {
     59 	int lc;
     60 
     61 	tst_parse_opts(argc, argv, NULL, NULL);
     62 
     63 	setup();
     64 
     65 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     66 		tst_count = 0;
     67 
     68 		set_disksize();
     69 
     70 		write_device();
     71 		dump_info();
     72 		verify_device();
     73 
     74 		reset();
     75 		dump_info();
     76 	}
     77 	cleanup();
     78 	tst_exit();
     79 }
     80 
     81 static void set_disksize(void)
     82 {
     83 	tst_resm(TINFO, "create a zram device with %ld bytes in size.", SIZE);
     84 	SAFE_FILE_PRINTF(cleanup, PATH_ZRAM "/disksize", "%ld", SIZE);
     85 }
     86 
     87 static void write_device(void)
     88 {
     89 	int fd;
     90 	char *s;
     91 
     92 	tst_resm(TINFO, "map this zram device into memory.");
     93 	fd = SAFE_OPEN(cleanup, DEVICE, O_RDWR);
     94 	s = SAFE_MMAP(cleanup, NULL, SIZE, PROT_READ | PROT_WRITE,
     95 		      MAP_SHARED, fd, 0);
     96 
     97 	tst_resm(TINFO, "write all the memory.");
     98 	memset(s, 'a', SIZE - 1);
     99 	s[SIZE - 1] = '\0';
    100 
    101 	SAFE_MUNMAP(cleanup, s, SIZE);
    102 	SAFE_CLOSE(cleanup, fd);
    103 }
    104 
    105 static void verify_device(void)
    106 {
    107 	int fd;
    108 	long i = 0, fail = 0;
    109 	char *s;
    110 
    111 	tst_resm(TINFO, "verify contents from device.");
    112 	fd = SAFE_OPEN(cleanup, DEVICE, O_RDONLY);
    113 	s = SAFE_MMAP(cleanup, NULL, SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
    114 
    115 	while (s[i] && i < SIZE - 1) {
    116 		if (s[i] != 'a')
    117 			fail++;
    118 		i++;
    119 	}
    120 	if (i != SIZE - 1) {
    121 		tst_resm(TFAIL, "expect size: %ld, actual size: %ld.",
    122 			 SIZE - 1, i);
    123 	} else if (s[i] != '\0') {
    124 		tst_resm(TFAIL, "zram device seems not null terminated");
    125 	} else if (fail) {
    126 		tst_resm(TFAIL, "%ld failed bytes found.", fail);
    127 	} else {
    128 		tst_resm(TPASS, "data read from zram device is consistent "
    129 			 "with those are written");
    130 	}
    131 
    132 	SAFE_MUNMAP(cleanup, s, SIZE);
    133 	SAFE_CLOSE(cleanup, fd);
    134 }
    135 
    136 static void reset(void)
    137 {
    138 	tst_resm(TINFO, "reset it.");
    139 	SAFE_FILE_PRINTF(cleanup, PATH_ZRAM "/reset", "1");
    140 }
    141 
    142 static void setup(void)
    143 {
    144 	int retried = 0;
    145 
    146 	tst_require_root();
    147 
    148 retry:
    149 	if (access(PATH_ZRAM, F_OK) == -1) {
    150 		if (errno == ENOENT) {
    151 			if (retried) {
    152 				tst_brkm(TCONF, NULL,
    153 					 "system has no zram device.");
    154 			}
    155 			if (system("modprobe zram") == -1) {
    156 				tst_brkm(TBROK | TERRNO, cleanup,
    157 					 "system(modprobe zram) failed");
    158 			}
    159 			modprobe = 1;
    160 			retried = 1;
    161 			goto retry;
    162 		} else
    163 			tst_brkm(TBROK | TERRNO, NULL, "access");
    164 	}
    165 
    166 	tst_sig(FORK, DEF_HANDLER, cleanup);
    167 	TEST_PAUSE;
    168 }
    169 
    170 static void cleanup(void)
    171 {
    172 	if (modprobe == 1 && system("rmmod zram") == -1)
    173 		tst_resm(TWARN | TERRNO, "system(rmmod zram) failed");
    174 }
    175 
    176 static void print(char *string)
    177 {
    178 	char filename[BUFSIZ], value[BUFSIZ];
    179 
    180 	sprintf(filename, "%s/%s", PATH_ZRAM, string);
    181 	SAFE_FILE_SCANF(cleanup, filename, "%s", value);
    182 	tst_resm(TINFO, "%s is %s", filename, value);
    183 }
    184 
    185 static void dump_info(void)
    186 {
    187 	print("initstate");
    188 	print("compr_data_size");
    189 	print("orig_data_size");
    190 	print("disksize");
    191 	print("mem_used_total");
    192 	print("num_reads");
    193 	print("num_writes");
    194 	print("zero_pages");
    195 }
    196