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 		}
     51 		err = access(buf, F_OK);
     52 	}
     53 	/* check start working directory */
     54 	if (err == -1 && tst_tmpdir_created()) {
     55 		free(buf);
     56 		if (asprintf(&buf, "%s/%s", tst_get_startwd(),
     57 			mod_name) == -1) {
     58 			tst_brkm(TBROK | TERRNO, cleanup_fn,
     59 				"asprintf failed at %s:%d",
     60 				__FILE__, __LINE__);
     61 		}
     62 		err = access(buf, F_OK);
     63 	}
     64 
     65 	if (err != 0) {
     66 		free(buf);
     67 		tst_brkm(TCONF, cleanup_fn, "Failed to find module '%s'",
     68 			mod_name);
     69 	}
     70 
     71 	if (mod_path != NULL)
     72 		*mod_path = buf;
     73 	else
     74 		free(buf);
     75 }
     76 
     77 void tst_module_load(void (cleanup_fn)(void),
     78 	const char *mod_name, char *const argv[])
     79 {
     80 	char *mod_path = NULL;
     81 	tst_module_exists(cleanup_fn, mod_name, &mod_path);
     82 
     83 	const int offset = 2; /* command name & module path */
     84 	int size = 0;
     85 	while (argv && argv[size])
     86 		++size;
     87 	size += offset;
     88 	const char *mod_argv[size + 1]; /* + NULL in the end */
     89 	mod_argv[size] = NULL;
     90 	mod_argv[0] = "insmod";
     91 	mod_argv[1] = mod_path;
     92 
     93 	int i;
     94 	for (i = offset; i < size; ++i)
     95 		mod_argv[i] = argv[i - offset];
     96 
     97 	tst_run_cmd(cleanup_fn, mod_argv, NULL, NULL, 0);
     98 	free(mod_path);
     99 }
    100 
    101 void tst_module_unload(void (cleanup_fn)(void), const char *mod_name)
    102 {
    103 	int i, rc;
    104 
    105 	const char *const argv[] = { "rmmod", mod_name, NULL };
    106 
    107 	rc = 1;
    108 	for (i = 0; i < 50; i++) {
    109 		rc = tst_run_cmd(NULL, argv, "/dev/null", "/dev/null", 1);
    110 		if (!rc)
    111 			break;
    112 
    113 		usleep(20000);
    114 	}
    115 
    116 	if (rc) {
    117 		tst_brkm(TBROK, cleanup_fn,
    118 			 "could not unload %s module", mod_name);
    119 	}
    120 }
    121