8 Commits
Author SHA1 Message Date
Gao feng 6680827faf send kill signal if term is ignored by container process
Fix the bug that stoppod is blocked.

Signed-off-by: Gao feng <feng@hyper.sh>
2015-08-13 16:52:36 +08:00
Gao feng 7699c38b99 ignore cbfs rom
Signed-off-by: Gao feng <feng@hyper.sh>
2015-08-13 16:52:26 +08:00
Gao feng aa265352ff send Next message to hyper in vbox environment
Signed-off-by: Gao feng <feng@hyper.sh>
2015-08-06 10:21:05 +08:00
Gao feng 56e5e66f86 remove vbox-bootimage target
Signed-off-by: Gao feng <feng@hyper.sh>
2015-07-30 16:13:06 +08:00
Gao feng 753364bbff remove hyper daemon test program
Signed-off-by: Gao feng <feng@hyper.sh>
2015-07-30 16:09:59 +08:00
Gao feng 8fbb28cc6f make cbfs target recursive
Signed-off-by: Gao feng <feng@hyper.sh>
2015-07-30 16:09:16 +08:00
Gao feng 066ba95737 Update README
no need input password now.

Signed-off-by: Gao feng <feng@hyper.sh>
2015-07-30 15:59:18 +08:00
Gao feng 1b9789937f Add VirtualBox support
Run hyperStart on VirtualBox

Signed-off-by: Gao feng <feng@hyper.sh>
2015-07-30 15:57:44 +08:00
24 changed files with 2633 additions and 441 deletions
+2
View File
@@ -10,7 +10,9 @@
init
build/hyper_daemon
build/hyper-initrd.img
build/cbfs.rom
build/root/*
build/*iso
build/daemon
build/.*
src/.*
+5
View File
@@ -1 +1,6 @@
SUBDIRS=src build
initrd-local:
@echo finish make initrd
cbfs-local:
@echo finish make cbfs
+8
View File
@@ -11,3 +11,11 @@ clone this repo, and make sure have build-essentials installed. Go into the work
> make
Then you can find `hyper-initrd.img` in build directory, together with a pre-build kernel.
If you want to get the boot disk file for VirtaulBox, please reconfigure with flag --with-vbox,
> ./configure --with-vbox
> make
Then you can find `hyper-vbox-bootimage.iso` in build directory, booting from this iso will
bring you to the hyper world.
+8 -3
View File
@@ -1,7 +1,12 @@
bin_PROGRAMS=hyper_daemon
hyper_daemon_SOURCES=hyper_daemon.c ../src/net.c
all-local:
all-local: initrd
if WITH_VBOX
initrd-local:
bash ./make-initrd.sh vbox
else
initrd-local:
bash ./make-initrd.sh
endif
cbfs-local:
bash ./make-initrd.sh cbfs
-168
View File
@@ -1,168 +0,0 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/socket.h>
#include <linux/un.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "../src/hyper.h"
#include "../src/net.h"
int test_sendmsg(int fd, unsigned int type, unsigned int len, char *message)
{
uint8_t buf[4096];
/* send hyper info to guest */
hyper_set_be32(buf, type);
len += 8;
fprintf(stdout, "type is %u, len is %u\n", type, len);
hyper_set_be32(buf + 4, len);
if (message)
memcpy(buf + 8, message, len - 8);
if (write(fd, buf, len) != len) {
fprintf(stderr, "send SETDVM MESSAGE failed\n");
return -1;
}
fprintf(stdout, "finish sending\n");
return 0;
}
int test_sendmsg_from_file(int fd, unsigned int type, char *file)
{
int file_fd = open(file, O_RDONLY);
uint8_t buf[4096];
unsigned int len = 0;
if (file_fd < 0) {
perror("fail to open file");
return -1;
}
while (len < 4096) {
int size = read(file_fd, buf + len, sizeof(buf) - len);
fprintf(stdout, "read %d data\n", size);
if (size < 0) {
perror("fail to read data");
return -1;
} else if (size == 0) {
/* buf[len] = '\0';*/
fprintf(stdout, "get buf %s, call sendmsg\n", buf);
test_sendmsg(fd, type, len, (char *)buf);
break;
}
len += size;
}
close(file_fd);
if (read(fd, buf, 8) != 8) {
fprintf(stderr, "read response failed\n");
return -1;
}
type = hyper_get_be32(buf);
if (type != ACK) {
fprintf(stderr, "incorrect type %d\n", type);
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
int sock, fd = -1;
struct sockaddr_un addr;
uint8_t buf[8];
unsigned int type;
unlink("/tmp/hyper.sock");
sock = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
if (sock == -1) {
perror("create unix socket failed");
return -1;
}
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, "/tmp/hyper.sock", UNIX_PATH_MAX);
addr.sun_path[UNIX_PATH_MAX - 1] = '\0';
if (bind(sock, ((struct sockaddr *) &addr), sizeof(addr)) == -1) {
perror("bind failed");
goto out;
}
if (listen(sock, 1) == -1) {
perror("bind failed");
goto out;
}
while (fd == -1)
fd = accept4(sock, NULL, NULL, SOCK_CLOEXEC);
fprintf(stdout, "connected\n");
if (read(fd, buf, 8) != 8) {
fprintf(stderr, "read failed, buf %s\n", buf);
goto out1;
}
type = hyper_get_be32(buf);
fprintf(stdout, "get type %d\n", type);
if (type != READY) {
fprintf(stderr, "incorrect type %d\n", type);
goto out1;
}
fprintf(stdout, "get length %d\n", hyper_get_be32(buf + 4));
/* test_sendmsg_from_file(fd, SETDVM, "sethyper.json"); */
if (test_sendmsg_from_file(fd, STARTPOD, "startpod.json") < 0) {
fprintf(stderr, "send startpod message failed\n");
goto out1;
}
if (test_sendmsg_from_file(fd, EXECCMD, "execcmd.json") < 0) {
fprintf(stderr, "send execcmd message failed\n");
goto out1;
}
if (test_sendmsg(fd, STOPPOD, 0, NULL) < 0) {
fprintf(stderr, "send stoppod message failed\n");
goto out1;
}
if (read(fd, buf, 8) != 8) {
fprintf(stderr, "read response failed\n");
return -1;
}
type = hyper_get_be32(buf);
if (type != ACK) {
fprintf(stderr, "incorrect type %d\n", type);
return -1;
}
if (read(fd, buf, 8) != 8) {
fprintf(stderr, "read response failed\n");
return -1;
}
out1:
close(fd);
out:
close(sock);
return 0;
}
BIN
View File
Binary file not shown.
+75 -35
View File
@@ -432,9 +432,7 @@ CONFIG_GENERIC_EARLY_IOREMAP=y
# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
CONFIG_X86_RESERVE_LOW=64
CONFIG_MTRR=y
CONFIG_MTRR_SANITIZER=y
CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
# CONFIG_MTRR_SANITIZER is not set
CONFIG_X86_PAT=y
CONFIG_ARCH_USES_PG_UNCACHED=y
CONFIG_ARCH_RANDOM=y
@@ -585,11 +583,7 @@ CONFIG_PACKET=y
# CONFIG_PACKET_DIAG is not set
CONFIG_UNIX=y
# CONFIG_UNIX_DIAG is not set
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
# CONFIG_XFRM_STATISTICS is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -597,17 +591,16 @@ CONFIG_INET=y
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE_DEMUX is not set
CONFIG_NET_IP_TUNNEL=y
# CONFIG_NET_IP_TUNNEL is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_NET_UDP_TUNNEL is not set
# CONFIG_NET_FOU is not set
# CONFIG_NET_FOU_IP_TUNNELS is not set
# CONFIG_GENEVE is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
CONFIG_INET_TUNNEL=y
# CONFIG_INET_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
@@ -626,14 +619,11 @@ CONFIG_IPV6=y
# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
CONFIG_INET6_XFRM_MODE_TRANSPORT=y
CONFIG_INET6_XFRM_MODE_TUNNEL=y
CONFIG_INET6_XFRM_MODE_BEET=y
# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
# CONFIG_INET6_XFRM_MODE_BEET is not set
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
# CONFIG_IPV6_VTI is not set
CONFIG_IPV6_SIT=y
# CONFIG_IPV6_SIT_6RD is not set
CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_IPV6_SIT is not set
# CONFIG_IPV6_TUNNEL is not set
# CONFIG_IPV6_GRE is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -730,7 +720,7 @@ CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
# CONFIG_PARPORT is not set
CONFIG_PNP=y
CONFIG_PNP_DEBUG_MESSAGES=y
# CONFIG_PNP_DEBUG_MESSAGES is not set
#
# Protocols
@@ -758,7 +748,6 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
# CONFIG_XEN_BLKDEV_BACKEND is not set
CONFIG_VIRTIO_BLK=y
# CONFIG_BLK_DEV_HD is not set
# CONFIG_BLK_DEV_RBD is not set
@@ -943,7 +932,69 @@ CONFIG_VIRTIO_NET=y
# CONFIG_NET_DSA_MV88E6171 is not set
# CONFIG_NET_DSA_MV88E6352 is not set
# CONFIG_NET_DSA_BCM_SF2 is not set
# CONFIG_ETHERNET is not set
CONFIG_ETHERNET=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_ADAPTEC is not set
# CONFIG_NET_VENDOR_AGERE is not set
# CONFIG_NET_VENDOR_ALTEON is not set
# CONFIG_ALTERA_TSE is not set
# CONFIG_NET_VENDOR_AMD is not set
# CONFIG_NET_XGENE is not set
# CONFIG_NET_VENDOR_ARC is not set
# CONFIG_NET_VENDOR_ATHEROS is not set
# CONFIG_NET_VENDOR_BROADCOM is not set
# CONFIG_NET_VENDOR_BROCADE is not set
# CONFIG_NET_VENDOR_CHELSIO is not set
# CONFIG_NET_VENDOR_CISCO is not set
# CONFIG_CX_ECAT is not set
# CONFIG_DNET is not set
# CONFIG_NET_VENDOR_DEC is not set
# CONFIG_NET_VENDOR_DLINK is not set
# CONFIG_NET_VENDOR_EMULEX is not set
# CONFIG_NET_VENDOR_EXAR is not set
# CONFIG_NET_VENDOR_HP is not set
CONFIG_NET_VENDOR_INTEL=y
# CONFIG_E100 is not set
CONFIG_E1000=y
# CONFIG_E1000E is not set
# CONFIG_IGB is not set
# CONFIG_IGBVF is not set
# CONFIG_IXGB is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGBEVF is not set
# CONFIG_I40E is not set
# CONFIG_I40EVF is not set
# CONFIG_FM10K is not set
# CONFIG_NET_VENDOR_I825XX is not set
# CONFIG_IP1000 is not set
# CONFIG_JME is not set
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MELLANOX is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_MYRI is not set
# CONFIG_FEALNX is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
# CONFIG_NET_VENDOR_NVIDIA is not set
# CONFIG_NET_VENDOR_OKI is not set
# CONFIG_ETHOC is not set
# CONFIG_NET_PACKET_ENGINE is not set
# CONFIG_NET_VENDOR_QLOGIC is not set
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_REALTEK is not set
# CONFIG_NET_VENDOR_RDC is not set
# CONFIG_NET_VENDOR_ROCKER is not set
# CONFIG_NET_VENDOR_SAMSUNG is not set
# CONFIG_NET_VENDOR_SEEQ is not set
# CONFIG_NET_VENDOR_SILAN is not set
# CONFIG_NET_VENDOR_SIS is not set
# CONFIG_SFC is not set
# CONFIG_NET_VENDOR_SMSC is not set
# CONFIG_NET_VENDOR_STMICRO is not set
# CONFIG_NET_VENDOR_SUN is not set
# CONFIG_NET_VENDOR_TEHUTI is not set
# CONFIG_NET_VENDOR_TI is not set
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_NET_SB1000 is not set
@@ -961,7 +1012,6 @@ CONFIG_VIRTIO_NET=y
#
# CONFIG_WAN is not set
CONFIG_XEN_NETDEV_FRONTEND=y
# CONFIG_XEN_NETDEV_BACKEND is not set
# CONFIG_VMXNET3 is not set
# CONFIG_ISDN is not set
@@ -995,17 +1045,8 @@ CONFIG_INPUT=y
#
# Hardware I/O ports
#
CONFIG_SERIO=y
# CONFIG_SERIO is not set
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=m
# CONFIG_SERIO_ALTERA_PS2 is not set
# CONFIG_SERIO_PS2MULT is not set
# CONFIG_SERIO_ARC_PS2 is not set
# CONFIG_GAMEPORT is not set
#
@@ -1216,14 +1257,13 @@ CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
#
# CONFIG_XEN_BALLOON is not set
# CONFIG_XEN_DEV_EVTCHN is not set
CONFIG_XEN_BACKEND=y
# CONFIG_XEN_BACKEND is not set
# CONFIG_XENFS is not set
# CONFIG_XEN_SYS_HYPERVISOR is not set
CONFIG_XEN_XENBUS_FRONTEND=y
# CONFIG_XEN_GNTDEV is not set
# CONFIG_XEN_GRANT_DEV_ALLOC is not set
CONFIG_SWIOTLB_XEN=y
CONFIG_XEN_PCIDEV_BACKEND=m
CONFIG_XEN_PRIVCMD=m
CONFIG_XEN_HAVE_PVMMU=y
# CONFIG_STAGING is not set
@@ -1385,7 +1425,7 @@ CONFIG_9P_FS_POSIX_ACL=y
CONFIG_9P_FS_SECURITY=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="utf8"
CONFIG_NLS_CODEPAGE_437=m
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
@@ -1433,7 +1473,7 @@ CONFIG_NLS_CODEPAGE_437=m
# CONFIG_NLS_MAC_INUIT is not set
# CONFIG_NLS_MAC_ROMANIAN is not set
# CONFIG_NLS_MAC_TURKISH is not set
CONFIG_NLS_UTF8=m
# CONFIG_NLS_UTF8 is not set
#
# Kernel hacking
+37 -5
View File
@@ -18,15 +18,18 @@ do
fi
done
done
cd ./root && find . | cpio -H newc -o | gzip -9 > ../hyper-initrd.img
if [ "$1" != "cbfs" ]; then
exit 0
if [ "$1"x = "vbox"x ]; then
echo "build initrd for vbox"
cp ./vbox/driver/* ./root
fi
cd ../
cd ./root && find . | cpio -H newc -o | gzip -9 > ../hyper-initrd.img
cd ../
rm -rf ./root
if [ "$1"x = "cbfs"x ]; then
echo "build cbfs"
rm -rf .cbfs
rm -rf cbfs.rom
@@ -38,3 +41,32 @@ cbfstool .cbfs/cbfs.rom add -f kernel -n vmlinuz -t raw
cbfstool .cbfs/cbfs.rom add -f hyper-initrd.img -n initrd -t raw
cp .cbfs/cbfs.rom ./
rm -rf .cbfs
exit 0
fi
if [ "$1"x = "vbox"x ]; then
mkdir tmp
mkdir -p tmp/images
mkdir -p tmp/kernel
mkdir -p tmp/isolinux
cd tmp
cp ../vbox/kernel ./kernel/
cp ../hyper-initrd.img ./images/initrd.img
cp ../vbox/isolinux/isolinux.bin ./isolinux/
cp ../vbox/isolinux/ldlinux.c32 ./isolinux/
cat > isolinux/syslinux.cfg <<EOF
DEFAULT linux
LABEL linux
SAY Now booting the kernel from SYSLINUX...
KERNEL /kernel/kernel
APPEND initrd=/images/initrd.img
EOF
cd ../
mkisofs -o hyper-vbox-boot.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table tmp
rm -fr tmp
fi
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
File diff suppressed because it is too large Load Diff
+11 -10
View File
@@ -2,9 +2,9 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([hyperstart], [0.1], [www.hyper.sh])
AC_INIT([hyperstart], [0.2], [www.hyper.sh])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
AM_EXTRA_RECURSIVE_TARGETS([cbfs])
AM_EXTRA_RECURSIVE_TARGETS([initrd cbfs])
AC_CONFIG_SRCDIR([src/init.c])
AC_CONFIG_HEADERS([config.h])
@@ -37,15 +37,16 @@ if test "$fail" = "1" ; then
AC_MSG_ERROR(Unable to find necessary functions)
fi
AC_ARG_WITH([ttys],
[AS_HELP_STRING([--with-ttys],
[use pci serial device as container tty])],
[],[with_ttys=yes])
AC_ARG_WITH([vbox],
[AS_HELP_STRING([--with-vbox],
[run hyperstart on Virtualbox])],
[],[with_vbox=no])
if test "x$with_ttys" != "xno" ; then
AC_DEFINE_UNQUOTED([WITH_TTYS], 1, [where use pci serial device as container tty])
if test "x$with_vbox" != "xno" ; then
AC_DEFINE_UNQUOTED([WITH_VBOX], 1, [run hyperstart on Virtualbox])
fi
AM_CONDITIONAL([WITH_TTYS], [test "x$with_ttys" != "xno"])
AM_CONDITIONAL([WITH_VBOX], [test "x$with_vbox" != "xno"])
AC_CONFIG_FILES([
Makefile
@@ -58,7 +59,7 @@ AC_MSG_RESULT([
${PACKAGE} ${VERSION}
prefix: ${prefix}
with-ttys: ${with_ttys}
with-vbox: ${with_vbox}
compiler: ${CC}
cflags: ${CFLAGS}
+21 -8
View File
@@ -42,27 +42,29 @@ static int container_setup_volume(struct hyper_container *container)
sprintf(dev, "/.oldroot/dev/%s", vol->device);
sprintf(path, "/tmp/%s", vol->mountpoint);
fprintf(stdout, "mount %s to %s\n", dev, vol->mountpoint);
fprintf(stdout, "mount %s to %s, tmp path %s\n",
dev, vol->mountpoint, path);
if (hyper_mkdir(path) < 0 || hyper_mkdir(vol->mountpoint) < 0) {
fprintf(stdout, "mountpoint %s\n", vol->mountpoint);
perror("create volume dir failed");
continue;
return -1;
}
if (mount(dev, path, vol->fstype, 0, NULL) < 0) {
perror("mount volume device faled");
continue;
return -1;
}
if (mount(path, vol->mountpoint, NULL, MS_BIND, NULL) < 0) {
perror("mount volume device faled");
continue;
return -1;
}
if (vol->readonly &&
mount(path, vol->mountpoint, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0)
mount(path, vol->mountpoint, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0) {
perror("mount fsmap faled");
return -1;
}
umount(path);
}
@@ -110,6 +112,10 @@ static int container_setup_mount(struct hyper_container *container)
char src[512];
struct fsmap *map;
hyper_mkdir("/proc");
hyper_mkdir("/sys");
hyper_mkdir("/dev");
if (mount("proc", "/proc", "proc", 0, NULL) < 0 ||
mount("sysfs", "/sys", "sysfs", 0, NULL) < 0 ||
mount("devtmpfs", "/dev", "devtmpfs", 0, NULL) < 0) {
@@ -305,7 +311,6 @@ static int hyper_container_init(void *data)
fprintf(stdout, "root directory for container is %s/%s, init task %s\n",
root, container->rootfs, container->exec.argv[0]);
hyper_list_dir(root);
sprintf(oldroot, "%s/%s/.oldroot", root, container->rootfs);
if (hyper_mkdir(oldroot) < 0) {
perror("make oldroot directroy failed");
@@ -352,6 +357,7 @@ static int hyper_container_init(void *data)
close(arg->pipe[1]);
execvp(container->exec.argv[0], container->exec.argv);
perror("exec container command failed");
_exit(-1);
@@ -364,12 +370,12 @@ fail:
int hyper_start_container(struct hyper_container *container)
{
int stacksize = getpagesize() * 4;
void *stack = malloc(stacksize);
struct hyper_container_arg arg = {
.c = container,
};
int flags = CLONE_NEWNS | SIGCHLD;
uint32_t type;
void *stack;
int pid;
if (container->image == NULL || container->exec.argv == NULL) {
@@ -383,6 +389,12 @@ int hyper_start_container(struct hyper_container *container)
goto fail;
}
stack = malloc(stacksize);
if (stack == NULL) {
perror("fail to allocate stack for container init");
return -1;
}
pid = clone(hyper_container_init, stack + stacksize, flags, &arg);
free(stack);
if (pid < 0) {
@@ -406,6 +418,7 @@ int hyper_start_container(struct hyper_container *container)
fail:
fprintf(stdout, "container %s init exit code %d\n", container->id, -1);
container->exec.code = -1;
return -1;
}
+178 -15
View File
@@ -5,33 +5,44 @@
#include <fcntl.h>
#include <unistd.h>
#include "net.h"
#include "util.h"
#include "hyper.h"
#include "event.h"
void hyper_reset_event(struct hyper_event *de)
{
free(de->buf.data);
de->buf.data = NULL;
free(de->rbuf.data);
free(de->wbuf.data);
memset(de, 0, sizeof(*de));
}
int hyper_init_event(struct hyper_event *de,
struct hyper_event_ops *ops,
uint32_t size, int to, void *arg)
int hyper_init_event(struct hyper_event *de, struct hyper_event_ops *ops, void *arg)
{
struct hyper_buf *buf = &de->buf;
struct hyper_buf *rbuf = &de->rbuf;
struct hyper_buf *wbuf = &de->wbuf;
memset(buf, 0, sizeof(*buf));
memset(rbuf, 0, sizeof(*rbuf));
memset(wbuf, 0, sizeof(*wbuf));
de->ops = ops;
de->ptr = arg;
de->to = to;
buf->size = size;
rbuf->size = ops->rbuf_size;
wbuf->size = ops->wbuf_size;
if (size) {
buf->data = malloc(size);
if (buf->data == NULL) {
fprintf(stderr, "allocate data for event failed\n");
if (rbuf->size) {
rbuf->data = malloc(rbuf->size);
if (rbuf->data == NULL) {
fprintf(stderr, "allocate read buffer for event failed\n");
return -1;
}
}
if (wbuf->size) {
wbuf->data = malloc(wbuf->size);
if (wbuf->data == NULL) {
fprintf(stderr, "allocate write buffer for event failed\n");
return -1;
}
}
@@ -39,13 +50,14 @@ int hyper_init_event(struct hyper_event *de,
return 0;
}
int hyper_add_event(int efd, struct hyper_event *de)
int hyper_add_event(int efd, struct hyper_event *de, int flag)
{
struct epoll_event event = {
.events = EPOLLIN,
.events = flag,
.data.ptr = de,
};
de->flag = flag;
if (hyper_setfd_nonblock(de->fd) < 0) {
perror("set fd nonblock failed");
return -1;
@@ -61,6 +73,148 @@ int hyper_add_event(int efd, struct hyper_event *de)
return 0;
}
int hyper_modify_event(int efd, struct hyper_event *de, int flag)
{
struct epoll_event event = {
.events = flag,
.data.ptr = de,
};
if (de->flag == flag)
return 0;
de->flag = flag;
fprintf(stdout, "%s modify event fd %d, %p, event %d\n",
__func__, de->fd, de, flag);
if (epoll_ctl(efd, EPOLL_CTL_MOD, de->fd, &event) < 0) {
perror("epoll_ctl fd failed");
return -1;
}
return 0;
}
static int hyper_getmsg_len(struct hyper_event *de, uint32_t *len)
{
struct hyper_buf *buf = &de->rbuf;
if (buf->get < de->ops->len_offset + 4)
return -1;
*len = hyper_get_be32(buf->data + de->ops->len_offset);
return 0;
}
int hyper_event_read(struct hyper_event *de)
{
struct hyper_buf *buf = &de->rbuf;
uint32_t len = 4;
uint8_t data[4];
int offset = de->ops->len_offset;
int end = offset + 4;
int size;
fprintf(stdout, "%s\n", __func__);
while (hyper_getmsg_len(de, &len) < 0) {
size = read(de->fd, buf->data + buf->get, end - buf->get);
if (size > 0) {
buf->get += size;
fprintf(stdout, "already read %" PRIu32 " bytes data\n",
buf->get);
if (de->ops->ack) {
/* control channel, need ack */
hyper_set_be32(data, size);
hyper_send_msg(de->fd, NEXT, 4, data);
}
continue;
}
if (errno == EINTR)
continue;
if (errno != EAGAIN && size != 0) {
perror("fail to read");
return -1;
}
return 0;
}
fprintf(stdout, "get length %" PRIu32"\n", len);
if (len > buf->size) {
fprintf(stderr, "get length %" PRIu32", too long\n", len);
return -1;
}
while (buf->get < len) {
size = read(de->fd, buf->data + buf->get, len - buf->get);
if (size > 0) {
buf->get += size;
fprintf(stdout, "read %d bytes data, total data %" PRIu32 "\n",
size, buf->get);
if (de->ops->ack) {
/* control channel, need ack */
hyper_set_be32(data, size);
hyper_send_msg(de->fd, NEXT, 4, data);
}
continue;
}
if (errno == EINTR)
continue;
if (errno != EAGAIN && size != 0) {
perror("fail to read");
return -1;
}
/* size == 0 : No one connect to qemu socket */
return 0;
}
/* get the whole data */
if (de->ops->handle(de, len) != 0)
return -1;
/* len: length of the already get new data */
buf->get -= len;
memmove(buf->data, buf->data + len, buf->get);
return 0;
}
int hyper_event_write(struct hyper_event *de)
{
struct hyper_buf *buf = &de->wbuf;
uint32_t len = 0;
int size = 0;
while (len < buf->get) {
size = write(de->fd, buf->data + len, buf->get - len);
if (size <= 0) {
if (errno == EINTR)
continue;
if (errno == EAGAIN || size == 0)
break;
return -1;
}
len += size;
}
buf->get -= len;
memmove(buf->data, buf->data + len, buf->get);
if (buf->get == 0) {
hyper_modify_event(ctl.efd, de, EPOLLIN);
}
return 0;
}
void hyper_event_hup(struct hyper_event *de, int efd)
{
if (epoll_ctl(efd, EPOLL_CTL_DEL, de->fd, NULL) < 0)
@@ -80,7 +234,16 @@ int hyper_handle_event(int efd, struct epoll_event *event)
de->ops->hup(de, efd);
return 0;
} else if (event->events & EPOLLIN) {
fprintf(stdout, "%s event EPOLLIN, de %p, fd %d, %p\n",
__func__, de, de->fd, de->ops);
return de->ops->read(de);
} else if (event->events & EPOLLOUT) {
fprintf(stdout, "%s event EPOLLOUT, de %p, fd %d, %p\n",
__func__, de, de->fd, de->ops);
if (de->ops->write)
return de->ops->write(de);
fprintf(stderr, "warning: %p received unexpected write event\n", de);
return 0;
} else if (event->events & EPOLLERR) {
fprintf(stderr, "get epoll err of not epool in event\n");
return -1;
+13 -5
View File
@@ -8,9 +8,13 @@ struct hyper_event;
struct hyper_event_ops {
int (*read)(struct hyper_event *e);
int (*getlen)(struct hyper_event *e, uint32_t *len);
int (*write)(struct hyper_event *e);
int (*handle)(struct hyper_event *e, uint32_t len);
void (*hup)(struct hyper_event *e, int efd);
int rbuf_size;
int wbuf_size;
int len_offset;
int ack;
};
struct hyper_buf {
@@ -21,16 +25,20 @@ struct hyper_buf {
struct hyper_event {
int fd;
int to;
struct hyper_buf buf;
int flag;
struct hyper_buf rbuf;
struct hyper_buf wbuf;
struct hyper_event_ops *ops;
void *ptr;
};
int hyper_add_event(int efd, struct hyper_event *de);
int hyper_add_event(int efd, struct hyper_event *de, int flag);
int hyper_modify_event(int efd, struct hyper_event *de, int flag);
int hyper_init_event(struct hyper_event *de, struct hyper_event_ops *ops,
uint32_t size, int to, void *arg);
void *arg);
int hyper_handle_event(int efd, struct epoll_event *event);
void hyper_reset_event(struct hyper_event *de);
void hyper_event_hup(struct hyper_event *de, int efd);
int hyper_event_read(struct hyper_event *de);
int hyper_event_write(struct hyper_event *de);
#endif
+28 -18
View File
@@ -19,14 +19,14 @@
static int pts_loop(struct hyper_event *de)
{
int size = 0;
uint8_t buf[512];
uint8_t seq[12];
int size = 0, i;
struct hyper_buf *buf = &ctl.tty.wbuf;
struct hyper_exec *exec = container_of(de, struct hyper_exec, e);
fprintf(stdout, "%s\n", __func__);
while (1) {
size = read(de->fd, buf, sizeof(buf));
dprintf("%s\n", __func__);
while (buf->get + 12 < buf->size) {
size = read(de->fd, buf->data + buf->get + 12, buf->size - buf->get - 12);
dprintf("%s: read %d data\n", __func__, size);
if (size <= 0) {
if (errno == EINTR)
continue;
@@ -37,13 +37,18 @@ static int pts_loop(struct hyper_event *de)
return -1;
}
hyper_set_be64(seq, exec->seq);
hyper_set_be32(seq + 8, size + 12);
hyper_set_be64(buf->data + buf->get, exec->seq);
hyper_set_be32(buf->data + buf->get + 8, size + 12);
buf->get += size + 12;
if (hyper_send_data(de->to, seq, 12) < 0)
continue;
dprintf("%s: seq %" PRIu64" len %" PRIu32"\n", __func__, exec->seq, size);
for (i = 0; i < size; i++)
dprintf("%0x ", buf->data[i]);
}
hyper_send_data(de->to, buf, size);
if (hyper_modify_event(ctl.efd, &ctl.tty, EPOLLIN | EPOLLOUT) < 0) {
fprintf(stderr, "modify ctl tty event to in & out failed\n");
return -1;
}
return 0;
@@ -51,7 +56,10 @@ static int pts_loop(struct hyper_event *de)
struct hyper_event_ops pts_ops = {
.read = pts_loop,
.write = hyper_event_write,
.hup = hyper_event_hup,
.wbuf_size = 512,
/* don't need read buff, the pts data will store in tty buffer */
};
int hyper_setup_exec_tty(struct hyper_exec *e)
@@ -186,8 +194,8 @@ int hyper_exec_in_container(struct hyper_pod *pod,
fprintf(stdout, "init container exec pts event %p, ops %p, fd %d\n",
&exec->e, &pts_ops, exec->e.fd);
if (hyper_init_event(&exec->e, &pts_ops, 0, ctl.tty.fd, NULL) < 0 ||
hyper_add_event(ctl.efd, &exec->e) < 0) {
if (hyper_init_event(&exec->e, &pts_ops, pod) < 0 ||
hyper_add_event(ctl.efd, &exec->e, EPOLLIN) < 0) {
fprintf(stderr, "add pts master event failed\n");
return -1;
}
@@ -224,8 +232,8 @@ int hyper_request_restart_containers(struct hyper_pod *pod)
if (exec->seq == 0)
continue;
if (hyper_init_event(&exec->e, &pts_ops, 0, ctl.tty.fd, NULL) < 0 ||
hyper_add_event(ctl.efd, &exec->e) < 0) {
if (hyper_init_event(&exec->e, &pts_ops, pod) < 0 ||
hyper_add_event(ctl.efd, &exec->e, EPOLLIN) < 0) {
fprintf(stderr, "add pts master event failed\n");
return -1;
}
@@ -297,8 +305,8 @@ int hyper_exec_cmd(char *json, int length)
fprintf(stdout, "init pod exec pts event %p, ops %p, fd %d\n",
&exec->e, &pts_ops, exec->e.fd);
if (hyper_init_event(&exec->e, &pts_ops, 0, ctl.tty.fd, NULL) < 0 ||
hyper_add_event(ctl.efd, &exec->e) < 0) {
if (hyper_init_event(&exec->e, &pts_ops, pod) < 0 ||
hyper_add_event(ctl.efd, &exec->e, EPOLLIN) < 0) {
fprintf(stderr, "add pts master event failed\n");
return -1;
}
@@ -421,6 +429,7 @@ fail:
_exit(-1);
}
int hyper_release_exec(struct hyper_exec *exec,
struct hyper_pod *pod)
{
@@ -449,7 +458,8 @@ int hyper_release_exec(struct hyper_exec *exec,
/* should shutdown? */
if (pod->policy == POLICY_NEVER ||
((pod->policy == POLICY_ONFAILURE) && pod->code == 0)) {
hyper_shutdown(pod);
hyper_send_finish(pod);
//hyper_shutdown(pod);
return 0;
}
+1
View File
@@ -24,6 +24,7 @@ enum {
WINSIZE,
PING,
FINISH,
NEXT,
};
enum {
+251 -138
View File
@@ -41,9 +41,6 @@ struct hyper_ctl ctl;
static void hyper_cleanup_pod(struct hyper_pod *pod);
static int hyper_handle_exit(struct hyper_pod *pod, int to,
int container, int option);
static int hyper_event_read(struct hyper_event *de);
static int hyper_type_getlen(struct hyper_event *de, uint32_t *len);
static int hyper_seq_getlen(struct hyper_event *de, uint32_t *len);
static int hyper_set_win_size(char *json, int length)
{
@@ -103,7 +100,7 @@ out:
static int pod_ctl_pipe_handle(struct hyper_event *de, uint32_t len)
{
struct hyper_buf *buf = &de->buf;
struct hyper_buf *buf = &de->rbuf;
struct hyper_pod *pod = de->ptr;
uint32_t type;
@@ -183,7 +180,10 @@ static int signal_loop(struct hyper_event *de, int container)
struct signalfd_siginfo sinfo;
struct hyper_pod *pod = de->ptr;
to = de->to;
if (container)
to = pod->ctl.fd;
else
to = ctl.tty.fd;
fprintf(stdout, "%s write to %d\n", __func__, to);
@@ -225,9 +225,10 @@ static int hyper_signal_loop(struct hyper_event *de)
static struct hyper_event_ops pod_ctl_pipe_ops = {
.read = hyper_event_read,
.getlen = hyper_type_getlen,
.handle = pod_ctl_pipe_handle,
.hup = hyper_event_hup,
.rbuf_size = 8,
.len_offset = 4,
};
static struct hyper_event_ops pod_signal_ops = {
@@ -248,16 +249,16 @@ static int pod_init_loop(struct hyper_pod *pod)
fprintf(stdout, "hyper_init_event pod ctl pipe event %p, ops %p, fd %d\n",
&pod->ctl, &pod_ctl_pipe_ops, pod->ctl.fd);
if (hyper_init_event(&pod->ctl, &pod_ctl_pipe_ops, 8, -1, pod) < 0 ||
hyper_add_event(pod->efd, &pod->ctl) < 0) {
if (hyper_init_event(&pod->ctl, &pod_ctl_pipe_ops, pod) < 0 ||
hyper_add_event(pod->efd, &pod->ctl, EPOLLIN) < 0) {
fprintf(stderr, "hyper add pod ctl pipe event failed\n");
return -1;
}
fprintf(stdout, "hyper_init_event pod signal event %p, ops %p, fd %d\n",
&pod->sig, &pod_signal_ops, pod->sig.fd);
if (hyper_init_event(&pod->sig, &pod_signal_ops, 0, pod->ctl.fd, pod) < 0 ||
hyper_add_event(pod->efd, &pod->sig) < 0) {
if (hyper_init_event(&pod->sig, &pod_signal_ops, pod) < 0 ||
hyper_add_event(pod->efd, &pod->sig, EPOLLIN) < 0) {
fprintf(stderr, "hyper add pod tty pipe event failed\n");
return -1;
}
@@ -341,7 +342,7 @@ fail:
static int hyper_ctl_pipe_handle(struct hyper_event *de, uint32_t len)
{
struct hyper_buf *buf = &de->buf;
struct hyper_buf *buf = &de->rbuf;
struct hyper_pod *pod = de->ptr;
uint32_t type, pid = 0;
uint8_t code;
@@ -360,7 +361,7 @@ static int hyper_ctl_pipe_handle(struct hyper_event *de, uint32_t len)
case FINISHCMD:
pid = hyper_get_be32(buf->data + 8);
code = buf->data[12];
if (hyper_send_exec_eof(de->to, pod, &pod->ce_head, pid, code) < 0) {
if (hyper_send_exec_eof(ctl.tty.fd, pod, &pod->ce_head, pid, code) < 0) {
fprintf(stderr, "hyper_ctl_pipe_loop send eof failed\n");
return -1;
}
@@ -416,8 +417,8 @@ static int hyper_watch_pty(struct hyper_pod *pod)
fprintf(stdout, "hyper_init_event container pts event %p, ops %p, fd %d\n",
&c->exec.e, &pts_ops, c->exec.e.fd);
if (hyper_init_event(&c->exec.e, &pts_ops, 0, ctl.tty.fd, NULL) < 0 ||
hyper_add_event(ctl.efd, &c->exec.e) < 0) {
if (hyper_init_event(&c->exec.e, &pts_ops, pod) < 0 ||
hyper_add_event(ctl.efd, &c->exec.e, EPOLLIN) < 0) {
fprintf(stderr, "add container pts master event failed\n");
return -1;
}
@@ -428,9 +429,10 @@ static int hyper_watch_pty(struct hyper_pod *pod)
static struct hyper_event_ops hyper_ctl_pipe_ops = {
.read = hyper_event_read,
.getlen = hyper_type_getlen,
.handle = hyper_ctl_pipe_handle,
.hup = hyper_event_hup,
.rbuf_size = 256,
.len_offset = 4,
};
static int hyper_setup_container(struct hyper_pod *pod)
@@ -498,14 +500,74 @@ static int hyper_setup_container(struct hyper_pod *pod)
}
fprintf(stdout, "hyper_init_event hyper ctl pipe fd %d\n", ctl.ctl.fd);
if (hyper_init_event(&ctl.ctl, &hyper_ctl_pipe_ops, 256, ctl.tty.fd, pod) < 0 ||
hyper_add_event(ctl.efd, &ctl.ctl) < 0) {
if (hyper_init_event(&ctl.ctl, &hyper_ctl_pipe_ops, pod) < 0 ||
hyper_add_event(ctl.efd, &ctl.ctl, EPOLLIN) < 0) {
return -1;
}
return 0;
}
#ifdef WITH_VBOX
#define MAX_HOST_NAME 256
#define MAX_NLS_NAME 32
#define VBSF_MOUNT_SIGNATURE_BYTE_0 '\377'
#define VBSF_MOUNT_SIGNATURE_BYTE_1 '\376'
#define VBSF_MOUNT_SIGNATURE_BYTE_2 '\375'
struct vbsf_mount_info_new
{
char nullchar; /* name cannot be '\0' -- we use this field
to distinguish between the old structure
and the new structure */
char signature[3]; /* signature */
int length; /* length of the whole structure */
char name[MAX_HOST_NAME]; /* share name */
char nls_name[MAX_NLS_NAME]; /* name of an I/O charset */
int uid; /* user ID for all entries, default 0=root */
int gid; /* group ID for all entries, default 0=root */
int ttl; /* time to live */
int dmode; /* mode for directories if != 0xffffffff */
int fmode; /* mode for regular files if != 0xffffffff */
int dmask; /* umask applied to directories */
int fmask; /* umask applied to regular files */
};
static int hyper_setup_shared(struct hyper_pod *pod)
{
struct vbsf_mount_info_new mntinf;
if (pod->tag == NULL) {
fprintf(stdout, "no shared directroy\n");
return 0;
}
if (hyper_mkdir("/tmp/hyper/shared") < 0) {
perror("fail to create /tmp/hyper/shared");
return -1;
}
bzero(&mntinf, sizeof(mntinf));
mntinf.nullchar = '\0';
mntinf.signature[0] = VBSF_MOUNT_SIGNATURE_BYTE_0;
mntinf.signature[1] = VBSF_MOUNT_SIGNATURE_BYTE_1;
mntinf.signature[2] = VBSF_MOUNT_SIGNATURE_BYTE_2;
mntinf.length = sizeof(mntinf);
mntinf.dmode = ~0U;
mntinf.fmode = ~0U;
strcpy(mntinf.name, pod->tag);
if (mount(NULL, "/tmp/hyper/shared", "vboxsf",
MS_NODEV, &mntinf) < 0) {
perror("fail to mount shared dir");
return -1;
}
return 0;
}
#else
static int hyper_setup_shared(struct hyper_pod *pod)
{
if (pod->tag == NULL) {
@@ -518,13 +580,16 @@ static int hyper_setup_shared(struct hyper_pod *pod)
return -1;
}
if (mount(pod->tag, "/tmp/hyper/shared", "9p", MS_MGC_VAL, "trans=virtio,cache=loose") < 0) {
perror("fail to mount 9p shared dir");
if (mount(pod->tag, "/tmp/hyper/shared", "9p",
MS_MGC_VAL| MS_NODEV, "trans=virtio,cache=loose") < 0) {
perror("fail to mount shared dir");
return -1;
}
return 0;
}
#endif
static int hyper_setup_pod(struct hyper_pod *pod)
{
@@ -566,12 +631,98 @@ static void hyper_print_uptime(void)
close(fd);
}
static void hyper_kill_process(int pid)
{
char path[64];
char *line = NULL, *ignore = "SigIgn:";
size_t len = 0;
ssize_t read;
FILE *file;
char *sub;
sprintf(path, "/proc/%u/status", pid);
fprintf(stdout, "fopen %s\n", path);
file = fopen(path, "r");
if (file == NULL) {
perror("can not open process proc status file");
return;
}
while ((read = getline(&line, &len, file)) != -1) {
long mask;
if (strstr(line, ignore) == NULL)
continue;
sub = line + strlen(ignore);
fprintf(stdout, "find sigign %s", sub);
mask = atol(sub);
fprintf(stdout, "mask is %ld\n", mask);
if ((mask >> (SIGTERM - 1)) & 0x1) {
fprintf(stdout, "signal term is ignored, kill it\n");
kill(pid, SIGKILL);
}
break;
}
fclose(file);
free(line);
}
static void hyper_term_all(struct hyper_pod *pod)
{
int npids = 0;
int index = 0;
int pid;
DIR *dp;
struct dirent *de;
pid_t *pids = NULL;
dp = opendir("/proc");
if (dp == NULL)
return;
while ((de = readdir(dp)) && de != NULL) {
if (!isdigit(de->d_name[0]))
continue;
pid = atoi(de->d_name);
if (pid == 1)
continue;
if (index <= npids) {
pids = realloc(pids, npids + 16384);
if (pids == NULL)
return;
npids += 16384;
}
pids[index++] = pid;
}
fprintf(stdout, "Sending SIGTERM\n");
for (--index; index >= 0; --index) {
fprintf(stdout, "kill process %d\n", pids[index]);
kill(pids[index], SIGTERM);
}
free(pids);
closedir(dp);
for (index = 0; index < pod->c_num; index++) {
hyper_kill_process(pod->c[index].exec.pid);
}
}
static void hyper_cleanup_pod(struct hyper_pod *pod)
{
close(pod->sig.fd);
hyper_reset_event(&pod->sig);
hyper_kill_all();
hyper_term_all(pod);
hyper_handle_exit(pod, pod->ctl.fd, 1, 0);
pod->init_pid = 0;
@@ -667,7 +818,7 @@ static int hyper_stop_pod(struct hyper_pod *pod)
return 0;
}
static int hyper_setup_channel(char *name)
static int hyper_setup_ctl_channel(char *name)
{
int ret = hyper_open_channel(name, 0);
@@ -680,56 +831,83 @@ static int hyper_setup_channel(char *name)
goto out;
}
if (hyper_setfd_nonblock(ret) < 0) {
perror("set hyper channel O_NONBLOCK failed");
goto out;
}
return ret;
out:
close(ret);
return -1;
}
static int hyper_setup_tty_channel(char *name)
{
int ret = hyper_open_channel(name, O_NONBLOCK);
if (ret < 0)
return -1;
return ret;
}
static int hyper_ttyfd_handle(struct hyper_event *de, uint32_t len)
{
struct hyper_buf *buf = &de->buf;
struct hyper_buf *rbuf = &de->rbuf;
struct hyper_pod *pod = de->ptr;
struct hyper_exec *exec;
struct hyper_buf *wbuf;
uint64_t seq = 0;
int size;
fprintf(stdout, "%s\n", __func__);
seq = hyper_get_be64(rbuf->data);
seq = hyper_get_be64(buf->data);
dprintf(stdout, "\n%s seq %" PRIu64", len %" PRIu32"\n", __func__, seq, len - 12);
exec = hyper_find_exec_by_seq(pod, seq);
if (exec == NULL) {
uint8_t data[12];
wbuf = &de->wbuf;
fprintf(stderr, "can't find exec whose seq is %" PRIu64 "\n", seq);
/* goodbye */
hyper_set_be64(data, seq);
hyper_set_be32(data + 8, 12);
hyper_send_data(de->fd, data, 12);
if (wbuf->get + 12 > wbuf->size)
return 0;
hyper_set_be64(wbuf->data + wbuf->get, seq);
hyper_set_be32(wbuf->data + wbuf->get + 8, 12);
wbuf->get += 12;
if (hyper_modify_event(ctl.efd, de, EPOLLIN | EPOLLOUT) < 0) {
fprintf(stderr, "modify ctl tty event to in & out failed\n");
return -1;
}
return 0;
}
fprintf(stdout, "find exec %s pid %d, seq is %" PRIu64 "\n",
dprintf(stdout, "find exec %s pid %d, seq is %" PRIu64 "\n",
exec->id ? exec->id : "pod", exec->pid, exec->seq);
wbuf = &exec->e.wbuf;
if (hyper_send_data(exec->e.fd, buf->data + 12, len - 12) < 0) {
fprintf(stderr, "send data to exec tty failed\n");
size = wbuf->size - wbuf->get;
if (size == 0)
return 0;
/* Data may lost since pts buffer is full. do not allow one exec pts occupy all
* of the tty buff. */
if (size > (len - 12))
size = (len - 12);
if (size > 0) {
memcpy(wbuf->data + wbuf->get, rbuf->data + 12, size);
wbuf->get += size;
if (hyper_modify_event(ctl.efd, &exec->e, EPOLLIN | EPOLLOUT) < 0) {
fprintf(stderr, "modify exec pts event to in & out failed\n");
return -1;
}
}
return 0;
}
static int hyper_channel_handle(struct hyper_event *de, uint32_t len)
{
struct hyper_buf *buf = &de->buf;
struct hyper_buf *buf = &de->rbuf;
struct hyper_pod *pod = de->ptr;
uint32_t type = 0;
int i, ret = 0;
@@ -780,101 +958,22 @@ static int hyper_channel_handle(struct hyper_event *de, uint32_t len)
return 0;
}
static int hyper_type_getlen(struct hyper_event *de, uint32_t *len)
{
struct hyper_buf *buf = &de->buf;
if (buf->get < 8)
return -1;
*len = hyper_get_be32(buf->data + 4);
return 0;
}
static int hyper_seq_getlen(struct hyper_event *de, uint32_t *len)
{
struct hyper_buf *buf = &de->buf;
if (buf->get < 12)
return -1;
*len = hyper_get_be32(buf->data + 8);
return 0;
}
static int hyper_event_read(struct hyper_event *de)
{
struct hyper_buf *buf = &de->buf;
uint32_t len = 0;
int size;
fprintf(stdout, "%s\n", __func__);
if (de->ops->getlen(de, &len) == 0) {
fprintf(stdout, "get length %" PRIu32"\n", len);
goto again;
}
while (1) {
size = read(de->fd, buf->data + buf->get, buf->size - buf->get);
if (size < 0) {
if (errno == EINTR)
continue;
if (errno == EAGAIN)
return 0;
perror("fail to read");
break;
} else if (size == 0) {
/* No one connect to qemu socket */
return 0;
}
fprintf(stdout, "read %d bytes data, total data %" PRIu32 "\n",
size, buf->get);
buf->get += size;
again:
if (len == 0) {
if (de->ops->getlen(de, &len) < 0) {
/* Need type & length fields */
continue;
}
fprintf(stdout, "get length %" PRIu32"\n", len);
if (len > buf->size || len == 0) {
fprintf(stderr, "message incorrect\n");
break;
}
}
/* check if get the whole data */
if (buf->get >= len) {
if (de->ops->handle(de, len) != 0)
break;
/* len: length of the already get new data */
buf->get -= len;
memmove(buf->data, buf->data + len, buf->get);
len = 0;
goto again;
}
}
return -1;
}
static struct hyper_event_ops hyper_channel_ops = {
.read = hyper_event_read,
.getlen = hyper_type_getlen,
.handle = hyper_channel_handle,
.rbuf_size = 10240,
.len_offset = 4,
/* TODO: vbox hyper should support channel ack */
.ack = 1,
};
static struct hyper_event_ops hyper_ttyfd_ops = {
.read = hyper_event_read,
.getlen = hyper_seq_getlen,
.write = hyper_event_write,
.handle = hyper_ttyfd_handle,
.rbuf_size = 4096,
.wbuf_size = 10240,
.len_offset = 8,
};
static struct hyper_event_ops hyper_signal_ops = {
@@ -896,22 +995,22 @@ static int hyper_loop(void)
fprintf(stdout, "hyper_init_event hyper channel event %p, ops %p, fd %d\n",
&ctl.chan, &hyper_channel_ops, ctl.chan.fd);
if (hyper_init_event(&ctl.chan, &hyper_channel_ops, 4096, -1, pod) < 0 ||
hyper_add_event(ctl.efd, &ctl.chan) < 0) {
if (hyper_init_event(&ctl.chan, &hyper_channel_ops, pod) < 0 ||
hyper_add_event(ctl.efd, &ctl.chan, EPOLLIN) < 0) {
return -1;
}
fprintf(stdout, "hyper_init_event hyper ttyfd event %p, ops %p, fd %d\n",
&ctl.tty, &hyper_ttyfd_ops, ctl.tty.fd);
if (hyper_init_event(&ctl.tty, &hyper_ttyfd_ops, 4096, -1, pod) < 0 ||
hyper_add_event(ctl.efd, &ctl.tty) < 0) {
if (hyper_init_event(&ctl.tty, &hyper_ttyfd_ops, pod) < 0 ||
hyper_add_event(ctl.efd, &ctl.tty, EPOLLIN) < 0) {
return -1;
}
fprintf(stdout, "hyper_init_event hyper signal event %p, ops %p, fd %d\n",
&ctl.sig, &hyper_signal_ops, ctl.sig.fd);
if (hyper_init_event(&ctl.sig, &hyper_signal_ops, 0, ctl.tty.fd, pod) < 0 ||
hyper_add_event(ctl.efd, &ctl.sig) < 0) {
if (hyper_init_event(&ctl.sig, &hyper_signal_ops, pod) < 0 ||
hyper_add_event(ctl.efd, &ctl.sig, EPOLLIN) < 0) {
return -1;
}
@@ -940,7 +1039,7 @@ static int hyper_loop(void)
int main(int argc, char *argv[])
{
char *cmdline;
char *cmdline, *ctl_serial, *tty_serial;
sigset_t mask;
if (hyper_mkdir("/dev") < 0 ||
@@ -983,6 +1082,22 @@ int main(int argc, char *argv[])
ioctl(STDIN_FILENO, TIOCSCTTY, 1);
#ifdef WITH_VBOX
ctl_serial = "/dev/ttyS0";
tty_serial = "/dev/ttyS1";
if (hyper_insmod("/vboxguest.ko") < 0 ||
hyper_insmod("/vboxsf.ko") < 0) {
fprintf(stderr, "fail to load modules\n");
return -1;
}
#else
ctl_serial = "sh.hyper.channel.0";
tty_serial = "sh.hyper.channel.1";
#endif
setenv("PATH", "/bin:/sbin/:/usr/bin/:/usr/sbin/", 1);
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
@@ -997,17 +1112,15 @@ int main(int argc, char *argv[])
return -1;
}
setenv("PATH", "/bin:/sbin/:/usr/bin/:/usr/sbin/", 1);
ctl.chan.fd = hyper_setup_channel("sh.hyper.channel.0");
ctl.chan.fd = hyper_setup_ctl_channel(ctl_serial);
if (ctl.chan.fd < 0) {
fprintf(stderr, "fail to setup hyper virtio serial port\n");
fprintf(stderr, "fail to setup hyper control serial port\n");
goto out1;
}
ctl.tty.fd = hyper_open_channel("sh.hyper.channel.1", O_NONBLOCK);
ctl.tty.fd = hyper_setup_tty_channel(tty_serial);
if (ctl.tty.fd < 0) {
fprintf(stderr, "fail to setup hyper virtio serial port\n");
fprintf(stderr, "fail to setup hyper tty serial port\n");
goto out2;
}
+5 -1
View File
@@ -7,8 +7,10 @@
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <termios.h>
#include "hyper.h"
#include "../config.h"
void hyper_set_be32(uint8_t *buf, uint32_t val)
{
@@ -55,7 +57,9 @@ int hyper_send_data(int fd, uint8_t *data, uint32_t len)
perror("send hyper data failed");
return -1;
}
#if WITH_VBOX
tcdrain(fd);
#endif
length += size;
}
+114 -24
View File
@@ -14,8 +14,9 @@
#include <sys/reboot.h>
#include <linux/reboot.h>
#include "net.h"
#include "util.h"
#include "hyper.h"
#include "../config.h"
char *read_cmdline(void)
{
@@ -86,6 +87,102 @@ int hyper_mkdir(char *hyper_path)
return 0;
}
#if WITH_VBOX
#include <termios.h>
int hyper_open_channel(char *channel, int mode)
{
struct termios term;
int fd = open(channel, O_RDWR | O_CLOEXEC | mode);
fprintf(stdout, "open %s get %d\n", channel, fd);
if (fd < 0) {
perror("fail to open channel device");
return -1;
}
bzero(&term, sizeof(term));
cfmakeraw(&term);
term.c_cflag |= CLOCAL | CREAD| CRTSCTS;
term.c_cc[VTIME] = 0;
term.c_cc[VMIN] = 0;
cfsetispeed(&term, B115200);
cfsetospeed(&term, B115200);
tcsetattr(fd, TCSANOW, &term);
return fd;
}
static const char *moderror(int err)
{
switch (err) {
case ENOEXEC:
return "Invalid module format";
case ENOENT:
return "Unknown symbol in module";
case ESRCH:
return "Module has wrong symbol version";
case EINVAL:
return "Invalid parameters";
default:
return strerror(err);
}
}
extern long init_module (void *, unsigned long, const char *);
int hyper_insmod(char *module)
{
size_t size, offset = 0, rc;
struct stat st;
char *buf = NULL;
int ret;
int fd = open(module, O_RDONLY);
if (fd == -1) {
fprintf (stderr, "insmod: open: %s: %m\n", module);
return -1;
}
if (fstat(fd, &st) == -1) {
perror ("insmod: fstat");
goto err;
}
size = st.st_size;
buf = malloc(size);
if (buf == NULL)
goto err;
do {
rc = read(fd, buf + offset, size - offset);
if (rc == -1) {
perror ("insmod: read");
goto err;
}
offset += rc;
} while (offset < size);
if (init_module(buf, size, "") != 0) {
fprintf (stderr, "insmod: init_module: %s: %s\n", module, moderror(errno));
goto err;
}
ret = 0;
out:
close(fd);
if (buf)
free(buf);
return ret;
err:
ret = -1;
goto out;
}
#else
int hyper_open_channel(char *channel, int mode)
{
struct dirent **list;
@@ -133,7 +230,7 @@ int hyper_open_channel(char *channel, int mode)
fprintf(stdout, "open hyper channel %s\n", path);
fd = open(path, O_RDWR | O_CLOEXEC | mode);
if (fd < 0)
perror("fail to open channel deice");
perror("fail to open channel device");
break;
}
@@ -142,34 +239,22 @@ int hyper_open_channel(char *channel, int mode)
return fd;
}
int hyper_insmod(char *module)
{
return 0;
}
#endif
int hyper_open_serial_dev(char *tty)
{
int fd = open(tty, O_RDWR | O_CLOEXEC | O_NOCTTY);
if (fd < 0) {
if (fd < 0)
perror("fail to open tty device");
return -1;
}
return fd;
}
int hyper_open_serial(char *tty)
{
char path[256];
memset(path, 0, sizeof(path));
if (snprintf(path, sizeof(path), "/dev/%s", tty) < 0) {
fprintf(stderr, "get channel device %s path failed\n", tty);
return -1;
}
fprintf(stdout, "open hyper tty %s\n", path);
return hyper_open_serial_dev(path);
}
int hyper_setfd_cloexec(int fd)
{
int flags = fcntl(fd, F_GETFD);
@@ -306,7 +391,7 @@ void hyper_kill_all(void)
closedir(dp);
}
void hyper_shutdown(struct hyper_pod *pod)
int hyper_send_finish(struct hyper_pod *pod)
{
int i;
uint8_t *data = calloc(pod->c_num, 4);
@@ -314,9 +399,14 @@ void hyper_shutdown(struct hyper_pod *pod)
for (i = 0; i < pod->c_num; i++)
hyper_set_be32(data + (i * 4), pod->c[i].exec.code);
hyper_send_msg(ctl.chan.fd, FINISH, pod->c_num * 4, data);
return hyper_send_msg(ctl.chan.fd, FINISH, pod->c_num * 4, data);
}
hyper_kill_all();
void hyper_shutdown(struct hyper_pod *pod)
{
hyper_send_finish(pod);
//hyper_kill_all();
hyper_unmount_all();
+13 -3
View File
@@ -1,18 +1,28 @@
#ifndef _UTIL_H_
#define _UTIL_H_
#include "hyper.h"
#include <stdio.h>
#include "../config.h"
struct hyper_pod;
#ifdef WITH_DEBUG
#define dprintf(fmt, ...) \
fprintf(stdout, fmt, ##_VA_ARGS__)
#else
#define dprintf(fmr, ...)
#endif
char *read_cmdline(void);
int hyper_list_dir(char *path);
int hyper_mkdir(char *path);
int hyper_open_channel(char *channel, int mode);
int hyper_open_serial_dev(char *tty);
int hyper_open_serial(char *tty);
int hyper_setfd_cloexec(int fd);
int hyper_setfd_block(int fd);
int hyper_setfd_nonblock(int fd);
void hyper_shutdown(struct hyper_pod *pod);
void hyper_kill_all(void);
int hyper_send_finish(struct hyper_pod *pod);
void hyper_unmount_all(void);
int hyper_insmod(char *module);
#endif