34
34
35
35
#include <stdio.h>
36
36
#include <errno.h>
37
- #include <fcntl.h>
38
37
#include <stdlib.h>
39
38
#include <unistd.h>
40
39
#include <string.h>
41
- #include <getopt.h>
42
- #include <libgen.h>
43
40
#include <sys/file.h>
44
41
#include <sys/stat.h>
45
- #include <sys/sysmacros.h>
46
42
#include <sys/types.h>
47
- #include <sys/ioctl.h>
48
- #include <linux/major.h>
49
43
50
44
#include "tap-ctl.h"
51
45
#include "blktap.h"
@@ -62,7 +56,7 @@ tap_ctl_prepare_directory(const char *dir)
62
56
63
57
name = strdup (dir );
64
58
if (!name )
65
- return ENOMEM ;
59
+ return - errno ;
66
60
67
61
start = name ;
68
62
@@ -73,8 +67,8 @@ tap_ctl_prepare_directory(const char *dir)
73
67
74
68
err = mkdir (name , 0700 );
75
69
if (err && errno != EEXIST ) {
70
+ err = - errno ;
76
71
PERROR ("mkdir %s" , name );
77
- err = errno ;
78
72
EPRINTF ("mkdir failed with %d\n" , err );
79
73
break ;
80
74
}
@@ -116,19 +110,72 @@ tap_ctl_check_environment(void)
116
110
}
117
111
118
112
static int
119
- tap_ctl_allocate_device (int * minor , char * * devname )
113
+ tap_ctl_allocate_minor (int * minor , char * * minor_name )
120
114
{
115
+ char * path = NULL ;
116
+ struct stat st_buf ;
117
+ int err , id , st , f , fid ;
118
+
121
119
* minor = -1 ;
122
- if (!devname )
123
- return EINVAL ;
124
120
125
- /* TO-DO: get this from a file based resource */
126
- * minor = 1 ;
127
- return 0 ;
121
+ f = open (BLKTAP2_NP_RUN_DIR , O_RDONLY );
122
+ if (f == -1 ) {
123
+ err = - errno ;
124
+ EPRINTF ("Failed to open runtime directory %d\n" , errno );
125
+ return err ;
126
+ }
127
+
128
+ /* The only way this can fail is with an EINTR or ENOLCK*/
129
+ err = flock (f , LOCK_EX );
130
+ if (err == -1 ) {
131
+ err = - errno ;
132
+ EPRINTF ("Failed to lock runtime directory %d\n" , errno );
133
+ return err ;
134
+ }
135
+
136
+ for (id = 0 ; id < MAX_ID ; id ++ ) {
137
+ err = asprintf (& path , "%s/tapdisk-%d" , BLKTAP2_NP_RUN_DIR , id );
138
+ if (err == -1 ) {
139
+ err = - errno ;
140
+ goto out ;
141
+ }
142
+
143
+ st = stat (path , & st_buf );
144
+ if (st == 0 ) {
145
+ /* Already exists */
146
+ free (path );
147
+ path = NULL ;
148
+ continue ;
149
+ }
150
+ if (errno != ENOENT ) {
151
+ err = - errno ;
152
+ free (path );
153
+ goto out ;
154
+ }
155
+
156
+ fid = open (path , O_CREAT | O_WRONLY , 0600 );
157
+ if (fid == -1 ) {
158
+ err = - errno ;
159
+ EPRINTF ("Failed to create ID file %s, %d\n" , path , errno );
160
+ free (path );
161
+ goto out ;
162
+ }
163
+ close (fid );
164
+
165
+ * minor = id ;
166
+ * minor_name = path ;
167
+ break ;
168
+ }
169
+
170
+ err = 0 ;
171
+ out :
172
+ flock (f , LOCK_UN );
173
+ close (f );
174
+ return err ;
128
175
}
129
176
130
177
int
131
- tap_ctl_allocate (int * minor , char * * devname )
178
+ tap_ctl_allocate (int * minor , char * * minor_name )
132
179
{
133
180
int err ;
134
181
@@ -140,7 +187,7 @@ tap_ctl_allocate(int *minor, char **devname)
140
187
return err ;
141
188
}
142
189
143
- err = tap_ctl_allocate_device (minor , devname );
190
+ err = tap_ctl_allocate_minor (minor , minor_name );
144
191
if (err ) {
145
192
EPRINTF ("tap-ctl allocate failed to allocate device" );
146
193
return err ;
0 commit comments