1 /*
2  * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it would be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * You should have received a copy of the GNU General Public License along
13  * with this program; if not, write the Free Software Foundation, Inc.,
14  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
15  *
16  */
17 
18 /*
19  *    AUTHOR: Madhu T L <madhu.tarikere@wipro.com>
20  *
21  *    DESCRIPTION
22  *      Verify that, delete_module(2) returns -1 and sets errno to EWOULDBLOCK,
23  *      if tried to remove a module while other modules depend on this module.
24  *
25  */
26 
27 #include <errno.h>
28 #include "test.h"
29 #include "old_module.h"
30 #include "safe_macros.h"
31 #include "linux_syscall_numbers.h"
32 
33 #define DUMMY_MOD		"dummy_del_mod"
34 #define DUMMY_MOD_KO		"dummy_del_mod.ko"
35 #define DUMMY_MOD_DEP		"dummy_del_mod_dep"
36 #define DUMMY_MOD_DEP_KO	"dummy_del_mod_dep.ko"
37 
38 static int dummy_mod_loaded;
39 static int dummy_mod_dep_loaded;
40 
41 char *TCID = "delete_module03";
42 
43 int TST_TOTAL = 1;
44 
45 static void setup();
46 static void cleanup(void);
47 
main(int argc,char ** argv)48 int main(int argc, char **argv)
49 {
50 	int lc;
51 
52 	tst_parse_opts(argc, argv, NULL, NULL);
53 
54 	setup();
55 
56 	for (lc = 0; TEST_LOOPING(lc); lc++) {
57 		tst_count = 0;
58 
59 		TEST(ltp_syscall(__NR_delete_module, DUMMY_MOD, 0));
60 
61 		if (TEST_RETURN < 0) {
62 			switch (errno) {
63 			case EWOULDBLOCK:
64 				tst_resm(TPASS | TTERRNO,
65 					 "delete_module() failed as expected");
66 			break;
67 			default:
68 				tst_resm(TFAIL | TTERRNO, "delete_module() "
69 					 "failed unexpectedly; expected: "
70 					 "%d - %s", EWOULDBLOCK,
71 					 strerror(EWOULDBLOCK));
72 			break;
73 			}
74 		} else {
75 			tst_resm(TFAIL, "delete_module()"
76 				 "succeeded unexpectedly");
77 			dummy_mod_loaded = 0;
78 			/*
79 			 * insmod DUMMY_MOD_KO again in case running
80 			 * with -i option
81 			 */
82 			tst_module_load(cleanup, DUMMY_MOD_KO, NULL);
83 			dummy_mod_loaded = 1;
84 		}
85 	}
86 
87 	cleanup();
88 	tst_exit();
89 
90 }
91 
setup(void)92 static void setup(void)
93 {
94 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
95 
96 	tst_require_root();
97 
98 	/* Load first kernel module */
99 	tst_module_load(cleanup, DUMMY_MOD_KO, NULL);
100 	dummy_mod_loaded = 1;
101 
102 	/* Load dependant kernel module */
103 	tst_module_load(cleanup, DUMMY_MOD_DEP_KO, NULL);
104 	dummy_mod_dep_loaded = 1;
105 
106 	TEST_PAUSE;
107 }
108 
cleanup(void)109 static void cleanup(void)
110 {
111 	/* Unload dependent kernel module */
112 	if (dummy_mod_dep_loaded == 1)
113 		tst_module_unload(NULL, DUMMY_MOD_DEP_KO);
114 
115 	/* Unload first kernel module */
116 	if (dummy_mod_loaded == 1)
117 		tst_module_unload(NULL, DUMMY_MOD_KO);
118 }
119