Home | History | Annotate | Download | only in utils
      1 /*
      2  * Crackerjack Project
      3  *
      4  * Copyright (C) 2007-2008, Hitachi, Ltd.
      5  * Author(s): Yumiko Sugita <yumiko.sugita.yf (at) hitachi.com>,
      6  *            Satoshi Fujiwara <sa-fuji (at) sdl.hitachi.co.jp>
      7  *
      8  * This program is free software; you can redistribute it and/or
      9  * modify it under the terms of the GNU General Public License
     10  * as published by the Free Software Foundation; either version 2
     11  * of the License, or (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program; if not, write to the Free Software
     20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     21  *
     22  * $Id: common_j_h.c,v 1.5 2009/11/20 06:48:31 yaberauneya Exp $
     23  *
     24  */
     25 #include <stdio.h>
     26 #include <unistd.h>
     27 #include <sys/types.h>
     28 #include <sys/wait.h>
     29 #include <sys/stat.h>
     30 #include <sys/time.h>
     31 #include <sys/resource.h>
     32 #include <fcntl.h>
     33 #include <pwd.h>
     34 #include <signal.h>
     35 #include <stdlib.h>
     36 #include <string.h>
     37 #include <errno.h>
     38 #include <mqueue.h>
     39 #include "include_j_h.h"
     40 #include "test.h"
     41 
     42 #define barrier() __asm__ __volatile__("": : :"memory")
     43 #define WITH_SIGNALS_BLOCKED(code) {					\
     44 		sigset_t held_sigs_;					\
     45 		sigfillset(&held_sigs_);				\
     46 		sigprocmask(SIG_SETMASK, &held_sigs_, &held_sigs_);	\
     47 		barrier();						\
     48 		code;							\
     49 		barrier();						\
     50 		sigprocmask(SIG_SETMASK, &held_sigs_, NULL);		\
     51 	}
     52 
     53 /*
     54  * Change user ID
     55  *
     56  *   We assume 'test' executable is executed with 'root' permission.
     57  *   So, if you use this function, you can not return 'root' uid.
     58  */
     59 int setup_uid(char *uname)
     60 {
     61 	struct passwd *pw;
     62 	int rc;
     63 
     64 	pw = getpwnam(uname);
     65 	if (!pw) {
     66 		EPRINTF("getpwnam failed.\n");
     67 		return -1;
     68 	}
     69 	rc = setuid(pw->pw_uid);
     70 	if (rc < 0) {
     71 		EPRINTF("setuid failed.\n");
     72 		return -1;
     73 	}
     74 	return 0;
     75 }
     76 
     77 /*
     78  * Change effective user ID
     79  */
     80 int setup_euid(char *uname, uid_t * old_uid)
     81 {
     82 	struct passwd *pw;
     83 	int rc;
     84 
     85 	*old_uid = geteuid();
     86 	pw = getpwnam(uname);
     87 	if (!pw) {
     88 		EPRINTF("getpwnam failed.\n");
     89 		return -1;
     90 	}
     91 	rc = seteuid(pw->pw_uid);
     92 	if (rc < 0) {
     93 		EPRINTF("seteuid failed.\n");
     94 		return -1;
     95 	}
     96 	return 0;
     97 }
     98 
     99 int cleanup_euid(uid_t old_uid)
    100 {
    101 	int rc;
    102 
    103 	rc = seteuid(old_uid);
    104 	if (rc < 0) {
    105 		EPRINTF("seteuid failed.\n");
    106 		return -1;
    107 	}
    108 	return 0;
    109 }
    110 
    111 static void sigterm_handler(int sig)
    112 {
    113 	_exit(0);
    114 }
    115 
    116 /*
    117  * Generate a child process which will send a signal
    118  */
    119 pid_t create_sig_proc(unsigned long usec, int sig, unsigned count)
    120 {
    121 	pid_t pid, cpid;
    122 
    123 	pid = getpid();
    124 	WITH_SIGNALS_BLOCKED(if ((cpid = fork()) == 0) {
    125 			     tst_sig(NOFORK, SIG_DFL, NULL);
    126 			     signal(SIGTERM, sigterm_handler);}
    127 	) ;
    128 	switch (cpid) {
    129 	case 0:
    130 		while (count-- > 0) {
    131 			usleep(usec);
    132 			if (kill(pid, sig) == -1)
    133 				break;
    134 		}
    135 		_exit(0);
    136 		break;
    137 	case -1:
    138 		EPRINTF("fork failed.\n");
    139 		return cpid;
    140 	default:
    141 		return cpid;
    142 	}
    143 }
    144 
    145 /*
    146  * Create and delete test file
    147  */
    148 int setup_file(char *testdir, char *fname, char *path)
    149 {
    150 	return _setup_file(testdir, fname, path,
    151 			   O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
    152 }
    153 
    154 int _setup_file(char *testdir, char *fname, char *path, int flags, mode_t mode)
    155 {
    156 	int rc;
    157 
    158 	sprintf(path, "%s/%s", testdir, fname);
    159 	rc = open(path, flags, mode);
    160 	if (rc < 0) {
    161 		EPRINTF("open failed.\n");
    162 		return -1;
    163 	}
    164 	return rc;
    165 }
    166 
    167 int cleanup_file(char *path)
    168 {
    169 	unlink(path);
    170 	return 0;
    171 }
    172 
    173 /*
    174  * Create and delete swap file
    175  */
    176 /* swap file needs to be more than 40KB */
    177 #define MIN_SWAPFILE_SIZE	(64 * 1024)
    178 int setup_swapfile(char *testdir, char *fname, char *path, size_t size)
    179 {
    180 	int fd = -1, rc;
    181 	size_t r_sz;
    182 	int cmdlen = 256;
    183 	char cmd[cmdlen];
    184 	char *p = NULL;
    185 
    186 	sprintf(path, "%s/%s", testdir, fname);
    187 	fd = open(path, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
    188 	if (fd < 0) {
    189 		EPRINTF("open failed.\n");
    190 		goto ERR_EXIT;
    191 	}
    192 	if (size < MIN_SWAPFILE_SIZE) {
    193 		EPRINTF("size too short.\n");
    194 		goto ERR_EXIT;
    195 	}
    196 	p = malloc(size);
    197 	if (!p) {
    198 		EPRINTF("malloc failed.\n");
    199 		goto ERR_EXIT;
    200 	}
    201 	/* Swap file must not have hole area */
    202 	memset(p, 0x5a, size);
    203 	r_sz = (size_t) write(fd, p, size);
    204 	if (r_sz != size) {
    205 		EPRINTF("write failed.\n");
    206 		goto ERR_EXIT;
    207 	}
    208 	snprintf(cmd, cmdlen, "/sbin/mkswap %s > /dev/null 2>&1", path);
    209 	rc = system(cmd);
    210 	if (rc != 0) {
    211 		EPRINTF("system(%s) failed.\n", cmd);
    212 		goto ERR_EXIT;
    213 	}
    214 	return fd;
    215 
    216 ERR_EXIT:
    217 	if (fd >= 0)
    218 		close(fd);
    219 	if (p)
    220 		free(p);
    221 	return -1;
    222 }
    223 
    224 int cleanup_swapfile(char *path)
    225 {
    226 	unlink(path);
    227 	return 0;
    228 }
    229 
    230 #if 0
    231 /*
    232  * Check max nodes from /sys/devices/system/node/node* files (for NUMA)
    233  */
    234 int get_max_nodes(void)
    235 {
    236 	/* We assume that there is only one node */
    237 	return 1;
    238 }
    239 #endif
    240 
    241 /*
    242  * Get unexist pid
    243  */
    244 pid_t get_unexist_pid(void)
    245 {
    246 	pid_t pid;
    247 	int st;
    248 
    249 	pid = fork();
    250 	switch (pid) {
    251 	case -1:
    252 		EPRINTF("fork failed.\n");
    253 		return -1;
    254 	case 0:
    255 		_exit(0);
    256 	default:
    257 		wait(&st);
    258 		return pid;
    259 	}
    260 }
    261