Skip to content

Commit b60d59c

Browse files
committed
CP-35551: create files to replace block device minor ids
Signed-off-by: Mark Syms <[email protected]>
1 parent 301d298 commit b60d59c

13 files changed

+498
-433
lines changed

control/Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
AM_CFLAGS = -Wall
33
AM_CFLAGS += -Werror
44
AM_CFLAGS += $(if $(GCOV),-fprofile-dir=/tmp/coverage/blktap/control -fprofile-arcs -ftest-coverage)
5+
AM_CFLAGS += -g
56

67
AM_CPPFLAGS = -D_GNU_SOURCE
78
AM_CPPFLAGS += -DTAPCTL

control/tap-ctl-allocate.c

+63-16
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,12 @@
3434

3535
#include <stdio.h>
3636
#include <errno.h>
37-
#include <fcntl.h>
3837
#include <stdlib.h>
3938
#include <unistd.h>
4039
#include <string.h>
41-
#include <getopt.h>
42-
#include <libgen.h>
4340
#include <sys/file.h>
4441
#include <sys/stat.h>
45-
#include <sys/sysmacros.h>
4642
#include <sys/types.h>
47-
#include <sys/ioctl.h>
48-
#include <linux/major.h>
4943

5044
#include "tap-ctl.h"
5145
#include "blktap.h"
@@ -62,7 +56,7 @@ tap_ctl_prepare_directory(const char *dir)
6256

6357
name = strdup(dir);
6458
if (!name)
65-
return ENOMEM;
59+
return -errno;
6660

6761
start = name;
6862

@@ -73,8 +67,8 @@ tap_ctl_prepare_directory(const char *dir)
7367

7468
err = mkdir(name, 0700);
7569
if (err && errno != EEXIST) {
70+
err = -errno;
7671
PERROR("mkdir %s", name);
77-
err = errno;
7872
EPRINTF("mkdir failed with %d\n", err);
7973
break;
8074
}
@@ -116,19 +110,72 @@ tap_ctl_check_environment(void)
116110
}
117111

118112
static int
119-
tap_ctl_allocate_device(int *minor, char **devname)
113+
tap_ctl_allocate_minor(int *minor, char **minor_name)
120114
{
115+
char *path = NULL;
116+
struct stat st_buf;
117+
int err, id, st, f, fid;
118+
121119
*minor = -1;
122-
if (!devname)
123-
return EINVAL;
124120

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;
128175
}
129176

130177
int
131-
tap_ctl_allocate(int *minor, char **devname)
178+
tap_ctl_allocate(int *minor, char **minor_name)
132179
{
133180
int err;
134181

@@ -140,7 +187,7 @@ tap_ctl_allocate(int *minor, char **devname)
140187
return err;
141188
}
142189

143-
err = tap_ctl_allocate_device(minor, devname);
190+
err = tap_ctl_allocate_minor(minor, minor_name);
144191
if (err) {
145192
EPRINTF("tap-ctl allocate failed to allocate device");
146193
return err;

control/tap-ctl-free.c

+54-14
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,68 @@
3737
#include <fcntl.h>
3838
#include <stdlib.h>
3939
#include <unistd.h>
40-
#include <getopt.h>
41-
#include <sys/ioctl.h>
40+
#include <sys/file.h>
4241

4342
#include "tap-ctl.h"
4443
#include "blktap.h"
4544

4645
int
4746
tap_ctl_free(const int minor)
4847
{
49-
/* TO-DO: Take the lock and remove the associated marker file */
50-
/* int fd, err; */
48+
char *path = NULL;
49+
int mfd = -1, fd, err;
5150

52-
/* fd = open(BLKTAP2_CONTROL_DEVICE, O_RDONLY); */
53-
/* if (fd == -1) { */
54-
/* EPRINTF("failed to open control device: %d\n", errno); */
55-
/* return errno; */
56-
/* } */
51+
fd = open(BLKTAP2_NP_RUN_DIR, O_RDONLY);
52+
if (fd == -1) {
53+
err = -errno;
54+
EPRINTF("Failed to open runtime directory %d\n", errno);
55+
return err;
56+
}
5757

58-
/* err = ioctl(fd, BLKTAP2_IOCTL_FREE_TAP, minor); */
59-
/* err = (err == -1) ? -errno : 0; */
60-
/* close(fd); */
58+
/* The only way this can fail is with an EINTR or ENOLCK*/
59+
err = flock(fd, LOCK_EX);
60+
if (err == -1) {
61+
err = -errno;
62+
EPRINTF("Failed to lock runtime directory %d\n", errno);
63+
return err;
64+
}
6165

62-
/* return err; */
63-
return 0;
66+
err = asprintf(&path, "%s/tapdisk-%d", BLKTAP2_NP_RUN_DIR, minor);
67+
if (err == -1) {
68+
err = -errno;
69+
goto out;
70+
}
71+
err = 0;
72+
73+
/* Non-Blocking lock to check it's not in use */
74+
mfd = open(path, O_RDONLY);
75+
if (mfd == -1) {
76+
err = -errno;
77+
EPRINTF("Failed to open marker file %s, %d, err=%d\n",
78+
path, minor, errno);
79+
goto out;
80+
}
81+
82+
err = flock(mfd, LOCK_EX | LOCK_NB);
83+
if (err == -1) {
84+
err = -errno;
85+
EPRINTF("Unable to lock marker file %s, err = %d\n",
86+
path, errno);
87+
goto out;
88+
}
89+
90+
unlink(path);
91+
92+
out:
93+
if (path)
94+
free(path);
95+
96+
if (mfd != -1) {
97+
flock(mfd, LOCK_UN);
98+
close(mfd);
99+
}
100+
101+
flock(fd, LOCK_UN);
102+
close(fd);
103+
return err;
64104
}

drivers/tapdisk-control.c

+14
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,13 @@ tapdisk_control_attach_vbd(struct tapdisk_ctl_conn *conn,
633633
goto out;
634634
}
635635

636+
/* Lock the marker file to prevent freeing in use*/
637+
err = tapdisk_vbd_lock(vbd);
638+
if (err) {
639+
ERR(err, "Failed to lock VBD marker file for %d\n", minor);
640+
goto fail_vbd;
641+
}
642+
636643
tapdisk_server_add_vbd(vbd);
637644

638645
out:
@@ -645,6 +652,10 @@ tapdisk_control_attach_vbd(struct tapdisk_ctl_conn *conn,
645652
}
646653

647654
return err;
655+
656+
fail_vbd:
657+
free(vbd);
658+
goto out;
648659
}
649660

650661
static int
@@ -669,6 +680,9 @@ tapdisk_control_detach_vbd(struct tapdisk_ctl_conn *conn,
669680
goto out;
670681
}
671682

683+
/* Unlock marker file */
684+
tapdisk_vbd_unlock(vbd);
685+
672686
if (list_empty(&vbd->images)) {
673687
tapdisk_server_remove_vbd(vbd);
674688
tapdisk_vbd_free(vbd);

drivers/tapdisk-vbd.c

+51-6
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <sys/ioctl.h>
4444
#include <sys/stat.h>
4545
#include <sys/types.h>
46+
#include <sys/file.h>
4647

4748
#include "debug.h"
4849
#include "libvhd.h"
@@ -664,6 +665,55 @@ tapdisk_vbd_open_vdi(td_vbd_t *vbd, const char *name, td_flag_t flags, int prt_d
664665
return err;
665666
}
666667

668+
static int
669+
open_vbd_marker(int id)
670+
{
671+
char *path = NULL;
672+
int err, fid;
673+
674+
err = asprintf(&path, "%s/tapdisk-%d", BLKTAP2_NP_RUN_DIR, id);
675+
if (err == -1) {
676+
return -errno;
677+
}
678+
679+
fid = open(path, O_RDONLY, 0600);
680+
if (fid == -1) {
681+
err = -errno;
682+
EPRINTF("Failed to open VBD marker file for %d\n", id);
683+
goto out;
684+
}
685+
686+
return fid;
687+
688+
out:
689+
if (path) {
690+
free(path);
691+
}
692+
return err;
693+
}
694+
695+
void tapdisk_vbd_unlock(td_vbd_t *vbd)
696+
{
697+
flock(vbd->lock_fd, LOCK_UN);
698+
close(vbd->lock_fd);
699+
}
700+
701+
int tapdisk_vbd_lock(td_vbd_t *vbd)
702+
{
703+
int fid;
704+
705+
fid = open_vbd_marker(vbd->uuid);
706+
if (fid < 0) {
707+
/* Already logged */
708+
return -1;
709+
}
710+
711+
vbd->lock_fd = fid;
712+
flock(vbd->lock_fd, LOCK_EX);
713+
714+
return 0;
715+
}
716+
667717
/*
668718
int
669719
tapdisk_vbd_open(td_vbd_t *vbd, const char *name,
@@ -741,6 +791,7 @@ tapdisk_vbd_shutdown(td_vbd_t *vbd)
741791
vbd->kicked);
742792

743793
tapdisk_vbd_close_vdi(vbd);
794+
tapdisk_vbd_unlock(vbd);
744795
tapdisk_server_remove_vbd(vbd);
745796
tapdisk_vbd_free(vbd);
746797

@@ -844,12 +895,6 @@ tapdisk_vbd_retry_needed(td_vbd_t *vbd)
844895
list_empty(&vbd->new_requests));
845896
}
846897

847-
int
848-
tapdisk_vbd_lock(td_vbd_t *vbd)
849-
{
850-
return 0;
851-
}
852-
853898
int
854899
tapdisk_vbd_quiesce_queue(td_vbd_t *vbd)
855900
{

drivers/tapdisk-vbd.h

+5
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ struct td_vbd_handle {
165165
struct td_vbd_encryption encryption;
166166

167167
bool watchdog_warned;
168+
169+
int lock_fd;
168170
};
169171

170172
#define tapdisk_vbd_for_each_request(vreq, tmp, list) \
@@ -206,6 +208,9 @@ int tapdisk_vbd_open_vdi(td_vbd_t * vbd, const char *params, td_flag_t flags,
206208
int prt_devnum);
207209
void tapdisk_vbd_close_vdi(td_vbd_t *);
208210

211+
int tapdisk_vbd_lock(td_vbd_t *);
212+
void tapdisk_vbd_unlock(td_vbd_t *);
213+
209214
int tapdisk_vbd_queue_request(td_vbd_t *, td_vbd_request_t *);
210215
void tapdisk_vbd_forward_request(td_request_t);
211216

include/blktap.h

+3
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,7 @@
3737
#define BLKTAP2_CONTROL_SOCKET "ctl"
3838
#define BLKTAP2_ENOSPC_SIGNAL_FILE "/run/tapdisk-enospc"
3939

40+
/* Maximum number of possible minor ids, to match old kernel definition */
41+
#define MAX_ID 16384
42+
4043
#endif /* _TD_BLKTAP_H_ */

mockatests/control/Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ test_control_LDFLAGS = -lcmocka
1515
test_control_LDFLAGS += -static-libtool-libs
1616
# Would be good to use the cmocka malloc wraps but looks like maybe strdup doesn't call malloc
1717
#test_control_LDFLAGS += -Wl,--wrap=malloc,--wrap=free
18+
test_control_LDFLAGS += -Wl,--wrap=stat
1819
test_control_LDFLAGS += -Wl,--wrap=socket,--wrap=connect,--wrap=read,--wrap=select,--wrap=write,--wrap=fdopen
1920
test_control_LDFLAGS += -Wl,--wrap=open,--wrap=ioctl,--wrap=close,--wrap=access,--wrap=mkdir,--wrap=flock,--wrap=unlink,--wrap=__xmknod
2021
#test_control_LDFLAGS += -Wl,--wrap=execl,--wrap=waitpid

0 commit comments

Comments
 (0)