1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /*
21 * NAME
22 * hugetlb.c
23 *
24 * DESCRIPTION
25 * common routines for the hugepage tests.
26 *
27 * The library contains the following routines:
28 *
29 * check_hugepage()
30 * getipckey()
31 * getuserid()
32 * rm_shm()
33 */
34
35 #include <sys/types.h>
36 #include <sys/ipc.h>
37 #include <sys/shm.h>
38 #include <sys/timeb.h>
39 #include <pwd.h>
40 #include "hugetlb.h"
41
check_hugepage(void)42 void check_hugepage(void)
43 {
44 if (access(PATH_HUGEPAGES, F_OK))
45 tst_brkm(TCONF, NULL, "Huge page is not supported.");
46 }
47
48 /*
49 * getipckey() - generates and returns a message key used by the "get"
50 * calls to create an IPC resource.
51 */
getipckey(void (* cleanup_fn)(void))52 int getipckey(void (*cleanup_fn) (void))
53 {
54 const char a = 'a';
55 int ascii_a = (int)a;
56 char *curdir = NULL;
57 size_t size = 0;
58 key_t ipc_key;
59 struct timeb time_info;
60
61 curdir = getcwd(curdir, size);
62 if (curdir == NULL)
63 tst_brkm(TBROK | TERRNO, cleanup_fn, "getcwd(curdir)");
64
65 /*
66 * Get a Sys V IPC key
67 *
68 * ftok() requires a character as a second argument. This is
69 * refered to as a "project identifier" in the man page. In
70 * order to maximize the chance of getting a unique key, the
71 * project identifier is a "random character" produced by
72 * generating a random number between 0 and 25 and then adding
73 * that to the ascii value of 'a'. The "seed" for the random
74 * number is the millisecond value that is set in the timeb
75 * structure after calling ftime().
76 */
77 ftime(&time_info);
78 srandom((unsigned int)time_info.millitm);
79
80 ipc_key = ftok(curdir, ascii_a + random() % 26);
81 if (ipc_key == -1)
82 tst_brkm(TBROK | TERRNO, cleanup_fn, "ftok");
83
84 return ipc_key;
85 }
86
87 /*
88 * getuserid() - return the integer value for the "user" id
89 */
getuserid(void (* cleanup_fn)(void),char * user)90 int getuserid(void (*cleanup_fn) (void), char *user)
91 {
92 struct passwd *ent;
93
94 ent = getpwnam(user);
95 if (ent == NULL)
96 tst_brkm(TBROK | TERRNO, cleanup_fn, "getpwnam");
97
98 return ent->pw_uid;
99 }
100
101 /*
102 * rm_shm() - removes a shared memory segment.
103 */
rm_shm(int shm_id)104 void rm_shm(int shm_id)
105 {
106 if (shm_id == -1)
107 return;
108
109 /*
110 * check for # of attaches ?
111 */
112 if (shmctl(shm_id, IPC_RMID, NULL) == -1) {
113 tst_resm(TINFO, "WARNING: shared memory deletion failed.");
114 tst_resm(TINFO, "This could lead to IPC resource problems.");
115 tst_resm(TINFO, "id = %d", shm_id);
116 }
117 }
118