Initial commit.
[rhbz1184405.git] / init.c
1 /* Try to reproduce RHBZ#1184405.
2  * Note: needs to be linked statically.
3  * By Richard W.M. Jones <rjones@redhat.com>
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <inttypes.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <sys/types.h>
12 #include <sys/ioctl.h>
13 #include <sys/stat.h>
14 #include <sys/wait.h>
15 #include <linux/fs.h>
16
17 extern long init_module (void *, unsigned long, const char *);
18
19 /* NB! Must match the number of disks in Makefile. */
20 #define NR_SCSI_DISKS 6
21
22 /* NB! Must match the module list in Makefile.  Also they must be
23  * in module dependency order.
24  */
25 static const char *modules[] = {
26   "virtio.ko",
27   "virtio_ring.ko",
28   "virtio_mmio.ko",
29   "virtio_scsi.ko",
30   NULL
31 };
32
33 static void load_modules (void);
34 static void make_devices (void);
35 static void run_test (const char *dev);
36
37 int
38 main (int argc, char *argv[])
39 {
40   int i;
41   char dev[] = "/dev/sda";
42   int child_pids[NR_SCSI_DISKS-1];
43
44   printf ("init: started\n");
45   load_modules ();
46
47   /* Really we should wait for the kernel to probe devices, but bleah. */
48   sleep (2);
49
50   make_devices ();
51
52   for (i = 0; i < NR_SCSI_DISKS-1; ++i) {
53     child_pids[i] = fork ();
54     if (child_pids[i] == -1) {
55       perror ("fork");
56       exit (EXIT_FAILURE);
57     }
58     if (child_pids[i] == 0) {   /* child */
59       dev[7] = 'a' + i + 1;     /* /dev/sd[b..] */
60       run_test (dev);
61       _exit (EXIT_SUCCESS);
62     }
63   }
64
65   run_test (dev);               /* /dev/sda test in parent */
66
67   for (i = 0; i < NR_SCSI_DISKS-1; ++i) {
68     waitpid (child_pids[i], NULL, 0);
69   }
70
71   printf ("init: parent process exiting\n");
72   exit (EXIT_SUCCESS);
73 }
74
75 static char buffer[BUFSIZ];
76 #define MIN(a,b) ((a)<(b)?(a):(b))
77
78 static void
79 run_test (const char *dev)
80 {
81   int fd;
82   uint64_t size;
83   ssize_t r;
84
85   printf ("init: testing %s\n", dev);
86   fflush (stdout);
87
88   fd = open (dev, O_RDONLY);
89   if (fd == -1) {
90     perror (dev);
91     _exit (EXIT_FAILURE);
92   }
93   if (ioctl (fd, BLKGETSIZE64, &size) == -1) {
94     perror ("ioctl: BLKGETSIZE64");
95     _exit (EXIT_FAILURE);
96   }
97
98   while (size > 0) {
99     r = read (fd, buffer, MIN (BUFSIZ, size));
100     if (r == -1) {
101       perror ("read");
102       _exit (EXIT_FAILURE);
103     }
104     size -= r;
105   }
106
107   if (close (fd) == -1) {
108     perror ("close");
109     _exit (EXIT_FAILURE);
110   }
111
112   printf ("init: test of %s finished successfully\n", dev);
113   fflush (stdout);
114 }
115
116 /* Originally taken from supermin's init.c */
117 static void
118 load_modules (void)
119 {
120   size_t i;
121   int fd;
122   struct stat statbuf;
123   size_t size;
124   ssize_t r;
125
126   for (i = 0; modules[i] != NULL; ++i) {
127     printf ("init: loading module %s\n", modules[i]);
128
129     fd = open (modules[i], O_RDONLY);
130     if (fd == -1) {
131       perror (modules[i]);
132       exit (EXIT_FAILURE);
133     }
134     if (fstat (fd, &statbuf) == -1) {
135       perror (modules[i]);
136       exit (EXIT_FAILURE);
137     }
138     char buf[size = statbuf.st_size];
139     while (size > 0) {
140       r = read (fd, buf, size);
141       if (r == -1) {
142         perror ("read");
143         exit (EXIT_FAILURE);
144       }
145       size -= r;
146     }
147     close (fd);
148
149     if (init_module (buf, statbuf.st_size, "") != 0) {
150       fprintf (stderr, "insmod: ");
151       perror (modules[i]);
152       exit (EXIT_FAILURE);
153     }
154   }
155 }
156
157 /* Much less trouble than udev! */
158 static void
159 make_devices (void)
160 {
161   int i;
162   char dev[] = "/dev/sda";
163
164   printf ("init: creating device nodes\n");
165
166   for (i = 0; i < NR_SCSI_DISKS; ++i) {
167     dev[7] = 'a' + i;
168     if (mknod (dev, S_IFBLK, makedev (8, 16*i)) == -1) {
169       perror (dev);
170       exit (EXIT_FAILURE);
171     }
172   }
173 }