~ubuntu-core-dev/module-init-tools/ubuntu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#ifndef _TESTING_H
#define _TESTING_H

/* Testing code. */
#ifdef JUST_TESTING

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <sys/utsname.h>
#include <asm/unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <time.h>

/* We don't use all of these. */
static int modtest_uname(struct utsname *buf) __attribute__((unused));
static long modtest_create_module(const char *name, size_t size)
__attribute__((unused));
static void *modtest_fopen(const char *path, const char *mode)
__attribute__((unused));
static int modtest_open(const char *path, int flags, mode_t mode)
__attribute__((unused));
static int modtest_stat(const char *file_name, struct stat *buf)
__attribute__((unused));
static int modtest_lstat(const char *file_name, struct stat *buf)
__attribute__((unused));
static DIR *modtest_opendir(const char *name) __attribute__((unused));
static int modtest_system(const char *string) __attribute__((unused));
static int modtest_rename(const char *oldpath, const char *newpath)
__attribute__((unused));
static long modtest_init_module(void *map, unsigned long size,
				const char *optstring) __attribute__((unused));
static long modtest_delete_module(const char *modname, unsigned int flags)
__attribute__((unused));

static int modtest_readlink(const char *path, char *buf, size_t bufsiz)
__attribute__((unused));

static int modtest_uname(struct utsname *buf)
{
	char *release = NULL;

	strcpy(buf->sysname, "Linux");
	strcpy(buf->nodename, "fakenodename");
	if ((release = getenv("MODTEST_UNAME")))
		strcpy(buf->release, release);
	else {
		printf("MODTEST_OVERRIDE_ROOT used but MODTEST_UNAME not set.\n");
		exit(1);
	}
	strcpy(buf->version, "Fakeversion");
	strcpy(buf->machine, "fakemachine");
	return 0;
}

static long modtest_create_module(const char *name, size_t size)
{
	if (getenv("MODTEST_DO_CREATE_MODULE"))
		return 0;
	errno = ENOSYS;
	return -1;
}

static const struct timespec modtest_delay = {
	.tv_sec = 0,
	.tv_nsec = 500 * 1000 * 1000
};

static long modtest_init_module(void *map, unsigned long size,
				const char *optstring)
{

	if (getenv("MODPROBE_WAIT")) {
		int fd;
		const char *file = getenv("MODPROBE_WAIT");

		printf("Looping on %s\n", file);
		fflush(stdout);
		while ((fd = open(file, O_RDONLY)) < 0)
			nanosleep(&modtest_delay, NULL);
		close(fd);
		printf("Removing %s\n", file);
		unlink(file);
	}
	if (getenv("MODTEST_DUMP_INIT")) {
		while (size) {
			int ret;
			ret = write(2, map, size);
			if (ret < 0) exit(1);
			size -= ret;
			map += ret;
		}
	} else		
		printf("INIT_MODULE: %lu %s\n", size, optstring);
	
	return 0;
}

static long modtest_delete_module(const char *modname, unsigned int flags)
{
	char flagnames[100];

	if (getenv("MODPROBE_WAIT")) {
		int fd;
		const char *file = getenv("MODPROBE_WAIT");

		printf("Looping on %s\n", file);
		fflush(stdout);
		while ((fd = open(file, O_RDONLY)) < 0)
			nanosleep(&modtest_delay, NULL);
		close(fd);
		printf("Removing %s\n", file);
		fflush(stdout);
		unlink(file);
	}
	flagnames[0] = '\0';
	if (flags & O_EXCL)
		strcat(flagnames, "EXCL ");
	if (flags & O_TRUNC)
		strcat(flagnames, "TRUNC ");
	if (flags & O_NONBLOCK)
		strcat(flagnames, "NONBLOCK ");
	if (flags & ~(O_EXCL|O_TRUNC|O_NONBLOCK))
		strcat(flagnames, "UNKNOWN ");

	printf("DELETE_MODULE: %s %s\n", modname, flagnames);
	return 0;
}

/* Add prefix to absolute paths; relative paths are left unchanged */
static const char *modtest_mapname(const char *path, char *buf, size_t buflen)
{
	char *root; 

	if (path[0] != '/')
		return path;

	root = getenv("MODTEST_OVERRIDE_ROOT");
	if (!root)
		return path;

	snprintf(buf, buflen, "%s%s", root, path);
	return buf;
}

static void *modtest_fopen(const char *path, const char *mode)
{
	char path_buf[PATH_MAX];

	path = modtest_mapname(path, path_buf, sizeof(path_buf));
	return fopen(path, mode);
}

static int modtest_open(const char *path, int flags, mode_t mode)
{
	char path_buf[PATH_MAX];

	path = modtest_mapname(path, path_buf, sizeof(path_buf));
	return open(path, flags, mode);
}

static int modtest_stat(const char *path, struct stat *buf)
{
	char path_buf[PATH_MAX];

	path = modtest_mapname(path, path_buf, sizeof(path_buf));
	return stat(path, buf);
}

static int modtest_lstat(const char *path, struct stat *buf)
{
	char path_buf[PATH_MAX];

	path = modtest_mapname(path, path_buf, sizeof(path_buf));
	return lstat(path, buf);
}

static DIR *modtest_opendir(const char *path)
{
	char path_buf[PATH_MAX];

	path = modtest_mapname(path, path_buf, sizeof(path_buf));
	return opendir(path);
}

static int modtest_system(const char *string)
{
	if (getenv("MODTEST_DO_SYSTEM"))
		return system(string);
	printf("SYSTEM: %s\n", string);
	return 0;
}

static int modtest_rename(const char *oldpath, const char *newpath)
{
	char oldpath_buf[PATH_MAX];
	char newpath_buf[PATH_MAX];

	oldpath = modtest_mapname(oldpath, oldpath_buf, sizeof(oldpath_buf));
	newpath = modtest_mapname(newpath, newpath_buf, sizeof(newpath_buf));
	return rename(oldpath, newpath);
}

static int modtest_readlink(const char *path, char *buf, size_t bufsiz)
{
	char path_buf[PATH_MAX];

	path = modtest_mapname(path, path_buf, sizeof(path_buf));
	return readlink(path, buf, bufsiz);
}

#ifdef CONFIG_USE_ZLIB
#include <zlib.h>
static gzFile *modtest_gzopen(const char *path, const char *mode)
__attribute__((unused));

static gzFile *modtest_gzopen(const char *path, const char *mode)
{
	char path_buf[PATH_MAX];

	path = modtest_mapname(path, path_buf, sizeof(path_buf));
	return gzopen(path, mode);
}
#endif

/* create_module call */
#undef create_module
#define create_module modtest_create_module

#define uname modtest_uname
#define delete_module modtest_delete_module
#define init_module modtest_init_module
#define open modtest_open
#define fopen modtest_fopen
#define stat(name, ptr) modtest_stat(name, ptr)
#define lstat(name, ptr) modtest_lstat(name, ptr)
#define opendir modtest_opendir
#define system modtest_system
#define rename modtest_rename
#define readlink modtest_readlink
#define gzopen modtest_gzopen

#endif /* JUST_TESTING */
#endif /* _TESTING_H */