Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.

Commit d1a502f

Browse files
authored
Merge pull request #313 from bergwolf/netlink
use netlink uevent to get device ready message
2 parents ccbfc5a + 08481c5 commit d1a502f

File tree

10 files changed

+201
-58
lines changed

10 files changed

+201
-58
lines changed

src/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
COMMIT=`git describe --dirty --always --tags 2> /dev/null || true`
22
AM_CFLAGS = -Wall -Werror -DVERSIONCOMMIT=\""$(VERSION), commit: $(COMMIT)"\"
33
bin_PROGRAMS=hyperstart
4-
hyperstart_SOURCES=init.c jsmn.c net.c util.c parse.c parson.c container.c exec.c event.c portmapping.c
4+
hyperstart_SOURCES=init.c jsmn.c net.c util.c parse.c parson.c container.c exec.c event.c portmapping.c netlink.c
55
if HAVE_VSOCK
66
hyperstart_SOURCES+=vsock.c
77
endif

src/container.c

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "hyper.h"
2121
#include "parse.h"
2222
#include "syscall.h"
23+
#include "netlink.h"
2324

2425
static int container_populate_volume(char *src, char *dest)
2526
{
@@ -134,7 +135,7 @@ static int container_setup_volume(struct hyper_container *container)
134135
if (!strcmp(vol->fstype, "xfs"))
135136
options = "nouuid";
136137

137-
if (hyper_mount_blockdev(dev, path, vol->fstype, options) < 0) {
138+
if (mount(dev, path, vol->fstype, 0, options) < 0) {
138139
perror("mount volume device failed");
139140
return -1;
140141
}
@@ -528,6 +529,7 @@ struct hyper_container_arg {
528529
struct hyper_pod *pod;
529530
int mntns_referenced_efd;
530531
int container_inited_efd;
532+
int container_root_dev_efd;
531533
};
532534

533535
static int hyper_setup_container_rootfs(void *data)
@@ -551,11 +553,6 @@ static int hyper_setup_container_rootfs(void *data)
551553
/* To create files/directories accessible for all users. */
552554
umask(0);
553555

554-
if (container->fstype && hyper_rescan_scsi() < 0) {
555-
fprintf(stdout, "rescan scsi failed\n");
556-
goto fail;
557-
}
558-
559556
if (mount("", "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
560557
perror("mount SLAVE failed");
561558
goto fail;
@@ -576,19 +573,24 @@ static int hyper_setup_container_rootfs(void *data)
576573
char dev[128];
577574
char *options = NULL;
578575

576+
/* wait for rootfs ready message */
577+
if (hyper_eventfd_recv(arg->container_root_dev_efd) < 0) {
578+
fprintf(stderr, "wait for /proc/self/ns/mnt opened failed\n");
579+
goto fail;
580+
}
581+
579582
if (container->scsiaddr) {
580583
free(container->image);
581584
container->image = NULL;
582585
hyper_find_sd(container->scsiaddr, &container->image);
583586
}
584-
585587
sprintf(dev, "/dev/%s", container->image);
586588
fprintf(stdout, "device %s\n", dev);
587589

588590
if (!strncmp(container->fstype, "xfs", strlen("xfs")))
589591
options = "nouuid";
590592

591-
if (hyper_mount_blockdev(dev, root, container->fstype, options) < 0) {
593+
if (mount(dev, root, container->fstype, 0, options) < 0) {
592594
perror("mount device failed");
593595
goto fail;
594596
}
@@ -717,6 +719,36 @@ static void hyper_cleanup_pty(struct hyper_container *c)
717719
perror("clean up container pty failed");
718720
}
719721

722+
int container_prepare_rootfs_dev(struct hyper_container *container, struct hyper_pod *pod)
723+
{
724+
char dev[512];
725+
726+
if (container->fstype == NULL)
727+
return 0;
728+
729+
if (hyper_rescan_scsi() < 0) {
730+
fprintf(stderr, "failed to issue scsi rescan\n");
731+
return -1;
732+
}
733+
734+
if (container->scsiaddr) {
735+
free(container->image);
736+
container->image = NULL;
737+
hyper_find_sd(container->scsiaddr, &container->image);
738+
}
739+
740+
if (container->image) {
741+
sprintf(dev, "/dev/%s", container->image);
742+
if (access(dev, R_OK) == 0)
743+
return 0;
744+
sprintf(dev, "/block/%s", container->image);
745+
} else {
746+
sprintf(dev, "/0:0:%s/block/", container->scsiaddr);
747+
}
748+
749+
return hyper_netlink_wait_dev(pod->ueventfd, dev);
750+
}
751+
720752
int hyper_setup_container(struct hyper_container *container, struct hyper_pod *pod)
721753
{
722754
int stacksize = getpagesize() * 42;
@@ -725,6 +757,7 @@ int hyper_setup_container(struct hyper_container *container, struct hyper_pod *p
725757
.pod = pod,
726758
.mntns_referenced_efd = -1,
727759
.container_inited_efd = -1,
760+
.container_root_dev_efd = -1,
728761
};
729762
int flags = CLONE_NEWNS | SIGCHLD;
730763
char path[128];
@@ -735,7 +768,9 @@ int hyper_setup_container(struct hyper_container *container, struct hyper_pod *p
735768

736769
arg.mntns_referenced_efd = eventfd(0, EFD_CLOEXEC);
737770
arg.container_inited_efd = eventfd(0, EFD_CLOEXEC);
738-
if (arg.mntns_referenced_efd < 0 || arg.container_inited_efd < 0) {
771+
arg.container_root_dev_efd = eventfd(0, EFD_CLOEXEC);
772+
if (arg.mntns_referenced_efd < 0 || arg.container_inited_efd < 0 ||
773+
arg.container_root_dev_efd < 0) {
739774
perror("create eventfd between pod init execcmd failed");
740775
goto fail;
741776
}
@@ -772,6 +807,13 @@ int hyper_setup_container(struct hyper_container *container, struct hyper_pod *p
772807
fprintf(stdout, "hyper send mntns referenced event: normal\n");
773808
hyper_eventfd_send(arg.mntns_referenced_efd, HYPER_EVENTFD_NORMAL);
774809

810+
if (container_prepare_rootfs_dev(container, pod) < 0) {
811+
fprintf(stderr, "fail to prepare container rootfs dev\n");
812+
goto fail;
813+
}
814+
fprintf(stdout, "hyper send root dev ready event: normal\n");
815+
hyper_eventfd_send(arg.container_root_dev_efd, HYPER_EVENTFD_NORMAL);
816+
775817
/* wait for ready message */
776818
if (hyper_eventfd_recv(arg.container_inited_efd) < 0) {
777819
fprintf(stderr, "wait for setup container rootfs failed\n");
@@ -780,12 +822,14 @@ int hyper_setup_container(struct hyper_container *container, struct hyper_pod *p
780822

781823
close(arg.mntns_referenced_efd);
782824
close(arg.container_inited_efd);
825+
close(arg.container_root_dev_efd);
783826
return 0;
784827
fail:
785828
close(container->ns);
786829
container->ns = -1;
787830
close(arg.mntns_referenced_efd);
788831
close(arg.container_inited_efd);
832+
close(arg.container_root_dev_efd);
789833
return -1;
790834
}
791835

src/hyper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ struct hyper_pod {
3939
uint32_t remains;
4040
int req_destroy;
4141
int efd;
42+
int ueventfd;
4243
};
4344

4445
struct portmapping_white_list {
@@ -65,6 +66,7 @@ struct hyper_epoll {
6566
struct hyper_event tty;
6667
struct hyper_event vsock_ctl_listener;
6768
struct hyper_event vsock_msg_listener;
69+
struct hyper_event dev;
6870
};
6971

7072
static inline int hyper_symlink(char *oldpath, char *newpath)

src/init.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "container.h"
3333
#include "syscall.h"
3434
#include "vsock.h"
35+
#include "netlink.h"
3536

3637
static struct hyper_pod global_pod = {
3738
.containers = LIST_HEAD_INIT(global_pod.containers),
@@ -1191,10 +1192,10 @@ static int hyper_ctlmsg_handle(struct hyper_event *he, uint32_t len)
11911192
hyper_cmd_online_cpu_mem();
11921193
break;
11931194
case SETUPINTERFACE:
1194-
ret = hyper_cmd_setup_interface((char *)buf->data + 8, len - 8);
1195+
ret = hyper_cmd_setup_interface((char *)buf->data + 8, len - 8, pod);
11951196
break;
11961197
case SETUPROUTE:
1197-
ret = hyper_cmd_setup_route((char *)buf->data + 8, len - 8);
1198+
ret = hyper_cmd_setup_route((char *)buf->data + 8, len - 8, pod);
11981199
break;
11991200
case SIGNALPROCESS:
12001201
ret = hyper_signal_process(pod, (char *)buf->data + 8, len - 8);
@@ -1443,6 +1444,11 @@ static int hyper_loop(void)
14431444
}
14441445
}
14451446

1447+
if (hyper_setup_netlink_listener(&hyper_epoll.dev) < 0 ||
1448+
hyper_add_event(hyper_epoll.efd, &hyper_epoll.dev, EPOLLIN))
1449+
return -1;
1450+
pod->ueventfd = hyper_epoll.dev.fd;
1451+
14461452
events = calloc(MAXEVENTS, sizeof(*events));
14471453

14481454
while (1) {

src/net.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "hyper.h"
1414
#include "util.h"
1515
#include "parse.h"
16+
#include "netlink.h"
1617
#include "../config.h"
1718

1819
void hyper_set_be32(uint8_t *buf, uint32_t val)
@@ -131,16 +132,19 @@ static int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int a
131132
return 0;
132133
}
133134

134-
static int hyper_get_ifindex(char *nic)
135+
static int hyper_get_ifindex(char *nic, struct hyper_pod *pod)
135136
{
136137
int fd, ifindex = -1;
137138
char path[512], buf[8];
138139

139140
sprintf(path, "/sys/class/net/%s/ifindex", nic);
140141
fprintf(stdout, "net device sys path is %s\n", path);
141142

142-
while (access(path, R_OK) < 0) {
143-
sched_yield();
143+
if (access(path, R_OK) < 0) {
144+
sprintf(path, "/net/%s/", nic);
145+
if (hyper_netlink_wait_dev(pod->ueventfd, path) < 0)
146+
return -1;
147+
sprintf(path, "/sys/class/net/%s/ifindex", nic);
144148
}
145149

146150
fd = open(path, O_RDONLY);
@@ -291,7 +295,8 @@ static int get_netmask(unsigned *val, const char *addr)
291295
}
292296

293297
static int hyper_setup_route(struct rtnl_handle *rth,
294-
struct hyper_route *rt)
298+
struct hyper_route *rt,
299+
struct hyper_pod *pod)
295300
{
296301
uint32_t data;
297302
struct {
@@ -330,7 +335,7 @@ static int hyper_setup_route(struct rtnl_handle *rth,
330335
}
331336

332337
if (rt->device) {
333-
int ifindex = hyper_get_ifindex(rt->device);
338+
int ifindex = hyper_get_ifindex(rt->device, pod);
334339
if (ifindex < 0) {
335340
fprintf(stderr, "failed to get the ifindix of %s\n", rt->device);
336341
return -1;
@@ -444,7 +449,8 @@ static int hyper_set_interface_mtu(struct rtnl_handle *rth,
444449
}
445450

446451
static int hyper_setup_interface(struct rtnl_handle *rth,
447-
struct hyper_interface *iface)
452+
struct hyper_interface *iface,
453+
struct hyper_pod *pod)
448454
{
449455
uint8_t data[4];
450456
unsigned mask;
@@ -467,7 +473,7 @@ static int hyper_setup_interface(struct rtnl_handle *rth,
467473
req.n.nlmsg_type = RTM_NEWADDR;
468474
req.ifa.ifa_family = AF_INET;
469475

470-
ifindex = hyper_get_ifindex(iface->device);
476+
ifindex = hyper_get_ifindex(iface->device, pod);
471477
if (ifindex < 0) {
472478
fprintf(stderr, "failed to get the ifindix of %s\n", iface->device);
473479
return -1;
@@ -557,7 +563,7 @@ int hyper_setup_network(struct hyper_pod *pod)
557563
for (i = 0; i < pod->i_num; i++) {
558564
iface = &pod->iface[i];
559565

560-
ret = hyper_setup_interface(&rth, iface);
566+
ret = hyper_setup_interface(&rth, iface, pod);
561567
if (ret < 0) {
562568
fprintf(stderr, "link up device %s failed\n", iface->device);
563569
goto out;
@@ -573,7 +579,7 @@ int hyper_setup_network(struct hyper_pod *pod)
573579
for (i = 0; i < pod->r_num; i++) {
574580
rt = &pod->rt[i];
575581

576-
ret = hyper_setup_route(&rth, rt);
582+
ret = hyper_setup_route(&rth, rt, pod);
577583
if (ret < 0) {
578584
fprintf(stderr, "setup route failed\n");
579585
goto out;
@@ -585,7 +591,7 @@ int hyper_setup_network(struct hyper_pod *pod)
585591
return ret;
586592
}
587593

588-
int hyper_cmd_setup_interface(char *json, int length)
594+
int hyper_cmd_setup_interface(char *json, int length, struct hyper_pod *pod)
589595
{
590596
int ret = -1;
591597
struct hyper_interface *iface;
@@ -603,7 +609,7 @@ int hyper_cmd_setup_interface(char *json, int length)
603609
fprintf(stderr, "parse interface failed\n");
604610
goto out;
605611
}
606-
ret = hyper_setup_interface(&rth, iface);
612+
ret = hyper_setup_interface(&rth, iface, pod);
607613
if (ret < 0) {
608614
fprintf(stderr, "link up device %s failed\n", iface->device);
609615
goto out1;
@@ -617,7 +623,8 @@ int hyper_cmd_setup_interface(char *json, int length)
617623
return ret;
618624
}
619625

620-
int hyper_cmd_setup_route(char *json, int length) {
626+
int hyper_cmd_setup_route(char *json, int length, struct hyper_pod *pod)
627+
{
621628
struct hyper_route *rts = NULL;
622629
int i, ret = -1;
623630
uint32_t r_num;
@@ -632,7 +639,7 @@ int hyper_cmd_setup_route(char *json, int length) {
632639
}
633640

634641
for (i = 0; i < r_num; i++) {
635-
ret = hyper_setup_route(&rth, &rts[i]);
642+
ret = hyper_setup_route(&rth, &rts[i], pod);
636643
if (ret < 0) {
637644
fprintf(stderr, "setup route failed\n");
638645
goto out;

src/net.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ uint32_t hyper_get_be32(uint8_t *buf);
4646
void hyper_set_be64(uint8_t *buf, uint64_t val);
4747
uint64_t hyper_get_be64(uint8_t *buf);
4848
int hyper_setup_network(struct hyper_pod *pod);
49-
int hyper_cmd_setup_interface(char *json, int length);
50-
int hyper_cmd_setup_route(char *json, int length);
49+
int hyper_cmd_setup_interface(char *json, int length, struct hyper_pod *pod);
50+
int hyper_cmd_setup_route(char *json, int length, struct hyper_pod *pod);
5151
int hyper_setup_dns(struct hyper_pod *pod);
5252
int hyper_setup_hostname(struct hyper_pod *pod);
5353
int hyper_send_data_block(int fd, uint8_t *data, uint32_t len);

0 commit comments

Comments
 (0)