Whamcloud - gitweb
b=16488
[fs/lustre-release.git] / lustre / tests / cmknod.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/tests/cmknod.c
37  *
38  * Simple test to check that device nodes are correctly created and visible
39  */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <fcntl.h>
47 #include <unistd.h>
48 #include <errno.h>
49
50 #define TEST_MINOR 120
51 #define TEST_MAJOR 25
52
53 void usage(char *prog)
54 {
55         fprintf(stderr, "usage: %s <filename>\n", prog);
56         exit(1);
57 }
58
59 /* UMKA: This stuff inlined here instead of using appropriate header 
60    to avoid linking to symbols which is not present in newer libc.
61    
62    Currently this is the case, as UML image contains RedHat 9 and 
63    developers use something newer (Fedora, etc.). */
64 inline unsigned int
65 __gnu_dev_major (unsigned long long int __dev)
66 {
67         return ((__dev >> 8) & 0xfff) | ((unsigned int) (__dev >> 32) & ~0xfff);
68 }
69
70 inline unsigned int
71 __gnu_dev_minor (unsigned long long int __dev)
72 {
73         return (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff);
74 }
75
76 inline unsigned long long int
77 __gnu_dev_makedev (unsigned int __major, unsigned int __minor)
78 {
79         return ((__minor & 0xff) | ((__major & 0xfff) << 8)
80                 | (((unsigned long long int) (__minor & ~0xff)) << 12)
81                 | (((unsigned long long int) (__major & ~0xfff)) << 32));
82 }
83
84 #define __minor(dev) __gnu_dev_minor(dev)
85 #define __major(dev) __gnu_dev_major(dev)
86 #define __makedev(maj, min) __gnu_dev_makedev(maj, min)
87
88 int main( int argc, char **argv)
89 {
90         char *prog = argv[0];
91         char *filename = argv[1];
92         int rc;
93         struct stat st;
94         dev_t device = __makedev(TEST_MAJOR, TEST_MINOR);
95
96         if (argc != 2) 
97                 usage(prog);
98
99         unlink(filename);
100         
101         /* First try block devices */
102         rc = mknod(filename, 0700 | S_IFBLK, device);
103         if ( rc < 0 ) {
104                 fprintf(stderr, "%s: mknod(%s) failed: rc %d: %s\n",
105                         prog, filename, errno, strerror(errno));
106                 return 2;
107         }
108
109         rc = stat(filename, &st);
110         if ( rc < 0 ) {
111                 fprintf(stderr, "%s: stat(%s) failed: rc %d: %s\n",
112                         prog, filename, errno, strerror(errno));
113                 return 3;
114         }
115         
116         if ( st.st_rdev != device) {
117                 fprintf(stderr, "%s: created device other than requested: (%u,%u) instead of (%u,%u)\n", 
118                         prog, __major(st.st_rdev),__minor(st.st_rdev),__major(device),__minor(device));
119                 return 4;
120         }
121         if (!S_ISBLK(st.st_mode)) {
122                 fprintf(stderr, "%s: created device of different type. Requested block device, got mode %o\n", prog, st.st_mode);
123                 return 5;
124         }
125
126         rc = unlink(filename);
127         if ( rc < 0 ) {
128                 fprintf(stderr, "%s: Cannot unlink created device %s, rc %d: %s\n",
129                         prog, filename, errno, strerror(errno));
130                 return 6;
131         }
132
133         /* Second try char devices */
134         rc = mknod(filename, 0700 | S_IFCHR, device);
135         if ( rc < 0 ) {
136                 fprintf(stderr, "%s: mknod(%s) failed: rc %d: %s\n",
137                         prog, filename, errno, strerror(errno));
138                 return 7;
139         }
140
141         rc = stat(filename, &st);
142         if ( rc < 0 ) {
143                 fprintf(stderr, "%s: stat(%s) failed: rc %d: %s\n",
144                         prog, filename, errno, strerror(errno));
145                 return 8;
146         }
147         if ( st.st_rdev != device) {
148                 fprintf(stderr, "%s: created device other than requested: (%u,%u) instead of (%u,%u)\n", 
149                         prog, __major(st.st_rdev),__minor(st.st_rdev),__major(device),__minor(device));
150                 return 9;
151         }
152         if (!S_ISCHR(st.st_mode)) {
153                 fprintf(stderr, "%s: created device of different type. Requested char device, got mode %o\n", prog, st.st_mode);
154                 return 10;
155         }
156
157         rc = unlink(filename);
158         if ( rc < 0 ) {
159                 fprintf(stderr, "%s: Cannot unlink created device %s, rc %d: %s\n",
160                         prog, filename, errno, strerror(errno));
161                 return 11;
162         }
163
164         printf("%s: device nodes created correctly\n", prog);
165
166         return 0;
167 }