Home | History | Annotate | Download | only in lib
      1 /*
      2  * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
      3  *
      4  * This program is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU General Public License as
      6  * published by the Free Software Foundation; either version 2 of
      7  * the License, or (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it would be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program; if not, write the Free Software Foundation,
     16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     17  *
     18  * Author: Alexey Kodanev <alexey.kodanev (at) oracle.com>
     19  *
     20  */
     21 
     22 #define _GNU_SOURCE
     23 #include <stdio.h>
     24 #include <stdlib.h>
     25 #include <unistd.h>
     26 
     27 #include "test.h"
     28 #include "ltp_priv.h"
     29 #include "old_module.h"
     30 
     31 void tst_module_exists(void (cleanup_fn)(void),
     32 	const char *mod_name, char **mod_path)
     33 {
     34 	/* check current working directory */
     35 	if (access(mod_name, F_OK) == 0) {
     36 		if (mod_path != NULL)
     37 			*mod_path = strdup(mod_name);
     38 		return;
     39 	}
     40 	char *buf = NULL;
     41 	int err = -1;
     42 	/* check LTP installation path */
     43 	const char *ltproot = getenv("LTPROOT");
     44 	if (ltproot != NULL) {
     45 		if (asprintf(&buf, "%s/testcases/bin/%s",
     46 			ltproot, mod_name) == -1) {
     47 			tst_brkm(TBROK | TERRNO, cleanup_fn,
     48 				"asprintf failed at %s:%d",
     49 				__FILE__, __LINE__);
     50 			return;
     51 		}
     52 		err = access(buf, F_OK);
     53 	}
     54 	/* check start working directory */
     55 	if (err == -1 && tst_tmpdir_created()) {
     56 		free(buf);
     57 		if (asprintf(&buf, "%s/%s", tst_get_startwd(),
     58 			mod_name) == -1) {
     59 			tst_brkm(TBROK | TERRNO, cleanup_fn,
     60 				"asprintf failed at %s:%d",
     61 				__FILE__, __LINE__);
     62 			return;
     63 		}
     64 		err = access(buf, F_OK);
     65 	}
     66 
     67 	if (err != 0) {
     68 		free(buf);
     69 		tst_brkm(TCONF, cleanup_fn, "Failed to find module '%s'",
     70 			mod_name);
     71 		return;
     72 	}
     73 
     74 	if (mod_path != NULL)
     75 		*mod_path = buf;
     76 	else
     77 		free(buf);
     78 }
     79 
     80 void tst_module_load(void (cleanup_fn)(void),
     81 	const char *mod_name, char *const argv[])
     82 {
     83 	char *mod_path = NULL;
     84 	tst_module_exists(cleanup_fn, mod_name, &mod_path);
     85 
     86 	const int offset = 2; /* command name & module path */
     87 	int size = 0;
     88 	while (argv && argv[size])
     89 		++size;
     90 	size += offset;
     91 	const char *mod_argv[size + 1]; /* + NULL in the end */
     92 	mod_argv[size] = NULL;
     93 	mod_argv[0] = "insmod";
     94 	mod_argv[1] = mod_path;
     95 
     96 	int i;
     97 	for (i = offset; i < size; ++i)
     98 		mod_argv[i] = argv[i - offset];
     99 
    100 	tst_run_cmd(cleanup_fn, mod_argv, NULL, NULL, 0);
    101 	free(mod_path);
    102 }
    103 
    104 void tst_module_unload(void (cleanup_fn)(void), const char *mod_name)
    105 {
    106 	int i, rc;
    107 
    108 	const char *const argv[] = { "rmmod", mod_name, NULL };
    109 
    110 	rc = 1;
    111 	for (i = 0; i < 50; i++) {
    112 		rc = tst_run_cmd(NULL, argv, "/dev/null", "/dev/null", 1);
    113 		if (!rc)
    114 			break;
    115 
    116 		usleep(20000);
    117 	}
    118 
    119 	if (rc) {
    120 		tst_brkm(TBROK, cleanup_fn,
    121 			 "could not unload %s module", mod_name);
    122 	}
    123 }
    124