2 * Copyright (C) 2017-2018 Red Hat Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 #define SIZE 1024*1024
50 static char data
[SIZE
];
52 static unsigned histogram
[256];
54 /* After reading the whole disk above, we then read randomly selected
55 * subsets of the disk and compare the data (it should be identical).
61 main (int argc
, char *argv
[])
65 struct random_state random_state
;
71 snprintf (sizearg
, sizeof sizearg
, "%d", SIZE
);
73 if (test_start_nbdkit ("random", sizearg
, NULL
) == -1)
76 g
= guestfs_create ();
78 perror ("guestfs_create");
82 r
= guestfs_add_drive_opts (g
, "",
83 GUESTFS_ADD_DRIVE_OPTS_READONLY
, 1,
84 GUESTFS_ADD_DRIVE_OPTS_FORMAT
, "raw",
85 GUESTFS_ADD_DRIVE_OPTS_PROTOCOL
, "nbd",
86 GUESTFS_ADD_DRIVE_OPTS_SERVER
, server
,
91 if (guestfs_launch (g
) == -1)
94 /* Read the whole device. */
95 rdata
= guestfs_pread_device (g
, "/dev/sda", SIZE
, 0, &rsize
);
99 fprintf (stderr
, "test-random: short read\n");
102 memcpy (data
, rdata
, SIZE
);
105 /* Test that the data is sufficiently random using a simple
106 * histogram. This just tests for gross errors and is not a
107 * complete statistical study.
109 for (i
= 0; i
< SIZE
; ++i
) {
110 unsigned char c
= (unsigned char) data
[i
];
113 for (i
= 0; i
< 256; ++i
) {
114 const unsigned expected
= SIZE
/ 256;
115 if (histogram
[i
] < 80 * expected
/ 100) {
116 fprintf (stderr
, "test-random: "
117 "random data is not uniformly distributed\n"
118 "eg. byte %d occurs %u times (expected about %u times)\n",
119 i
, histogram
[i
], expected
);
124 /* Randomly read parts of the disk to ensure we get the same data.
126 xsrandom (time (NULL
), &random_state
);
127 for (i
= 0; i
< NR_READS
; ++i
) {
128 offset
= xrandom (&random_state
);
129 offset
%= SIZE
- RSIZE
;
130 rdata
= guestfs_pread_device (g
, "/dev/sda", RSIZE
, offset
, &rsize
);
133 if (rsize
!= RSIZE
) {
134 fprintf (stderr
, "test-random: short read\n");
137 if (memcmp (&data
[offset
], rdata
, rsize
) != 0) {
138 fprintf (stderr
, "test-random: returned different data\n");
144 if (guestfs_shutdown (g
) == -1)