mirror of
https://github.com/clearlinux/hyperstart.git
synced 2026-09-06 13:41:44 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b055f07cbb | ||
|
|
a615be817c | ||
|
|
4fc7dddb53 | ||
|
|
256c491948 | ||
|
|
9844779c4e | ||
|
|
b6eff45cc4 | ||
|
|
6d75e8cc93 | ||
|
|
fcc968a004 | ||
|
|
bbb111ea6d | ||
|
|
88f445ce34 | ||
|
|
3747b03b70 | ||
|
|
b1d90cf796 | ||
|
|
0470974773 | ||
|
|
66bcaedf2a | ||
|
|
6b4a925945 | ||
|
|
ca80a07ede | ||
|
|
467d776b15 | ||
|
|
3293eaa34b | ||
|
|
18235fc443 | ||
|
|
9a406cc3dd | ||
|
|
d39a4a03f1 | ||
|
|
2878ec5890 | ||
|
|
b900783a3b | ||
|
|
9132f7549d | ||
|
|
232afc9538 | ||
|
|
3d0f9b1692 | ||
|
|
6afbb02017 | ||
|
|
7e64971357 | ||
|
|
eb59290a59 | ||
|
|
dc46e20caa | ||
|
|
8fdd03c635 | ||
|
|
807ef53908 | ||
|
|
1acd0280e8 | ||
|
|
2e3bc177ea | ||
|
|
ec20f8ab0a | ||
|
|
648d99fa64 | ||
|
|
2621a406cf | ||
|
|
72a049a72d | ||
|
|
1fda991fee | ||
|
|
9077cf47b3 | ||
|
|
ac4d6d8fc7 | ||
|
|
b232c8fcc9 | ||
|
|
cb680e280d | ||
|
|
7401981c22 | ||
|
|
83c3c1d424 | ||
|
|
9cd968e2d2 | ||
|
|
290217c87a | ||
|
|
39c027e58c | ||
|
|
22cfaea4d2 | ||
|
|
e3704f66ba | ||
|
|
8ac18bf650 | ||
|
|
d63f716523 | ||
|
|
1973768704 | ||
|
|
4011640b08 | ||
|
|
db6f286244 | ||
|
|
b2e7a0f631 | ||
|
|
f4ad330a75 | ||
|
|
54f5362a03 | ||
|
|
45967cc8b8 | ||
|
|
728d02983e | ||
|
|
4e830d77b4 | ||
|
|
2a669f0558 | ||
|
|
5ed9195bf8 | ||
|
|
064879ff0a | ||
|
|
2360c4dc3f | ||
|
|
da72799c96 | ||
|
|
56198c3acd | ||
|
|
a07cabf2d0 | ||
|
|
440e14cde4 | ||
|
|
5b1b29593e | ||
|
|
519db047fb | ||
|
|
504218c41f | ||
|
|
c0e8d92d9a | ||
|
|
be7654b416 | ||
|
|
1cf932a784 | ||
|
|
5c30a49c27 | ||
|
|
4b662dd4fa | ||
|
|
13a58d6531 | ||
|
|
ecf00fc578 | ||
|
|
819f639334 | ||
|
|
cdc84ecb4b | ||
|
|
9d7a6c0a0f | ||
|
|
d9e871409e | ||
|
|
bb5c2c5744 | ||
|
|
2f2be98cff | ||
|
|
28ea806216 | ||
|
|
8c45a5d6fe | ||
|
|
98262e7e50 | ||
|
|
ff845ee371 | ||
|
|
6224d6b779 | ||
|
|
2fb3ad7474 | ||
|
|
82c1ecd25a | ||
|
|
b46bc34498 | ||
|
|
0c5335b8d5 | ||
|
|
dca1bd6aaa | ||
|
|
c4f06c3fcd | ||
|
|
92fc1d65a5 | ||
|
|
e0bc511a97 | ||
|
|
46fd62cafd | ||
|
|
41438d40d6 | ||
|
|
7294253548 | ||
|
|
41366ae88a | ||
|
|
5edb81f783 | ||
|
|
eea9702389 | ||
|
|
7acbc5e288 | ||
|
|
34ec350357 | ||
|
|
b58b03874d | ||
|
|
02b777058d | ||
|
|
17f9f7b4cf | ||
|
|
4fa99f7a5b | ||
|
|
6efb8d2638 | ||
|
|
e2b79425f1 | ||
|
|
21cb97d970 | ||
|
|
f06259b0b9 | ||
|
|
70dd9f1447 | ||
|
|
8b674e78f5 | ||
|
|
de59d91bc2 | ||
|
|
6824ff3d2e | ||
|
|
ffd28a721c | ||
|
|
6f73ec97e3 | ||
|
|
f01a9f4081 | ||
|
|
79d066d847 | ||
|
|
9089ec3f25 | ||
|
|
6e8bc85878 | ||
|
|
4c0887f131 | ||
|
|
3d942a45bb | ||
|
|
83223f6832 | ||
|
|
a2202183fb | ||
|
|
37856283d5 | ||
|
|
bb7ebdaadd | ||
|
|
fe5c9a9d9c | ||
|
|
62ef95ba93 | ||
|
|
d8fb6c1af3 | ||
|
|
2ccac3fa9c | ||
|
|
52c87dc016 | ||
|
|
f359cb9468 | ||
|
|
3de74e927c | ||
|
|
7b54d5c9da | ||
|
|
1e4711d898 | ||
|
|
cb71f43ed1 | ||
|
|
c72276b004 | ||
|
|
5735f9f674 | ||
|
|
de0c2c97e4 | ||
|
|
8a86dd1f51 | ||
|
|
5ba9b2550d | ||
|
|
da986b4a3a | ||
|
|
5b21370efd | ||
|
|
2f4626dde2 | ||
|
|
bf61d6306e | ||
|
|
74f6930073 | ||
|
|
0c05c999e3 | ||
|
|
97099eb46e | ||
|
|
b28a02fa0d | ||
|
|
9a6738d84d | ||
|
|
d3cfa23dde | ||
|
|
9bfb3be414 | ||
|
|
ae2d491c20 | ||
|
|
b0a601793e | ||
|
|
19f1dc012e | ||
|
|
87b1a5c29a | ||
|
|
4a63bceb67 | ||
|
|
b2f6b89ea6 | ||
|
|
db4f364510 | ||
|
|
2ccea842bd | ||
|
|
3197bcad45 | ||
|
|
3bed96c176 | ||
|
|
eecb4c5612 | ||
|
|
c015887bb6 | ||
|
|
2169309145 | ||
|
|
c5d25b6f5f | ||
|
|
da6b36411a | ||
|
|
06d10f2844 | ||
|
|
70d35640b9 | ||
|
|
1f501c5417 | ||
|
|
1c21bb2e6f | ||
|
|
b6c6e1f991 | ||
|
|
98059369b8 | ||
|
|
03187117e1 | ||
|
|
54aed5efc5 | ||
|
|
98b8211ddc | ||
|
|
cd9a8f4306 | ||
|
|
bb550c2444 | ||
|
|
00308d00b5 | ||
|
|
e255de660d | ||
|
|
ca004ec273 | ||
|
|
52aca5a860 | ||
|
|
5fcac6f0bb | ||
|
|
216bce6fe0 | ||
|
|
e8381942d4 | ||
|
|
51dc391bc0 | ||
|
|
73a9c3e8e9 | ||
|
|
505ad4ddb0 | ||
|
|
20158b9033 | ||
|
|
1e6dffd36f | ||
|
|
d919414192 | ||
|
|
b15d771a56 | ||
|
|
b99768db28 | ||
|
|
1a612982e8 | ||
|
|
3f034fec04 | ||
|
|
831113b7d0 | ||
|
|
64aeb1ceca | ||
|
|
11c7507eed | ||
|
|
828204c1cf | ||
|
|
94720f4ace | ||
|
|
12a797cb9e | ||
|
|
7856628d8a | ||
|
|
193c1cc97e | ||
|
|
c3eee6616f | ||
|
|
3d57690daa | ||
|
|
9ca23869fc | ||
|
|
72996cd5e8 | ||
|
|
ab6ff1d2bd | ||
|
|
40f04580ec | ||
|
|
286e0f9c8f | ||
|
|
6aa71c3bd9 | ||
|
|
01a958b209 | ||
|
|
bbba8776ff | ||
|
|
34b6af632a | ||
|
|
99c593a8be | ||
|
|
57b130adbb | ||
|
|
558adb04ab | ||
|
|
684dd342d7 | ||
|
|
53bdafd2c5 | ||
|
|
f54f77ccaa | ||
|
|
6065205cb2 | ||
|
|
071a0c2b30 | ||
|
|
c4f9764556 | ||
|
|
99fe992d31 | ||
|
|
837016a417 | ||
|
|
d7dd250195 | ||
|
|
8626dfc79e | ||
|
|
75e23882bf | ||
|
|
95394c8e5a | ||
|
|
623d667fa0 | ||
|
|
7279227474 | ||
|
|
d2daea2927 | ||
|
|
f4493e59f9 | ||
|
|
9cca6ef2f9 | ||
|
|
aea6029ba1 | ||
|
|
fcc973cda6 | ||
|
|
0896a874c7 | ||
|
|
53ffb48e0a | ||
|
|
a70c3cfb54 | ||
|
|
1a4a6794e0 | ||
|
|
8024730027 | ||
|
|
211eb96eb6 | ||
|
|
5b7069c8b4 | ||
|
|
ece6aa1a79 | ||
|
|
185cfb9fe4 | ||
|
|
c8b2fee21c | ||
|
|
9ce56b757e | ||
|
|
72fc9ade82 | ||
|
|
05c85499bc | ||
|
|
3785a4d02c | ||
|
|
d74aaa326d | ||
|
|
9615c24fca | ||
|
|
783d711be1 | ||
|
|
30b3bf772b | ||
|
|
d69a74be22 | ||
|
|
908797e672 | ||
|
|
cf2267cff2 | ||
|
|
42ba6daf6d | ||
|
|
61b2963d0d | ||
|
|
c92d2d6430 | ||
|
|
274fa5cd84 | ||
|
|
baa07ce3f9 | ||
|
|
402a930af0 | ||
|
|
4475e2db1b | ||
|
|
2c12120713 | ||
|
|
84207a3f97 | ||
|
|
ab1c293818 | ||
|
|
3fbba94a0f | ||
|
|
a9b7fed072 | ||
|
|
ad196e2fe3 | ||
|
|
0c3b80fdbd | ||
|
|
c835eb9dfe | ||
|
|
99319c29a6 | ||
|
|
354c4f44b6 | ||
|
|
048ee7ba27 | ||
|
|
9eef10d3c3 | ||
|
|
ecdc3cd339 | ||
|
|
4f5b747c2b | ||
|
|
a0bc0851d6 | ||
|
|
c68c7b76d1 | ||
|
|
9590958aae | ||
|
|
d3199fcc60 | ||
|
|
4b45b28122 | ||
|
|
e458707966 | ||
|
|
3554b8ef0b | ||
|
|
48e7b27737 | ||
|
|
1cff207e67 | ||
|
|
aa50e5812b | ||
|
|
64cbfd2a0b | ||
|
|
e487303205 | ||
|
|
5a91148a37 | ||
|
|
6a56562120 | ||
|
|
8803fa8ccb | ||
|
|
90998a9b21 | ||
|
|
5e945d507e | ||
|
|
c1023f414f | ||
|
|
e737392fc4 | ||
|
|
01a09c9b8f | ||
|
|
a524b04f8c | ||
|
|
2332d39620 | ||
|
|
bc28dfedf8 | ||
|
|
09c0a1b41b | ||
|
|
b441c1bffe | ||
|
|
5be2a71a84 | ||
|
|
8766f77f24 | ||
|
|
e4beaad672 | ||
|
|
7f6056fc4c | ||
|
|
5ceb9b8906 | ||
|
|
2ace93e881 | ||
|
|
abd52a4ae2 | ||
|
|
76bccbd261 | ||
|
|
8f70de4d49 | ||
|
|
ea196f786d | ||
|
|
ced3b9dc53 | ||
|
|
5ca0595e4f | ||
|
|
53cd58a121 | ||
|
|
0a86f73869 | ||
|
|
12ba0a42b2 | ||
|
|
1ad3ffcf63 | ||
|
|
5f9a7ee0a2 | ||
|
|
b0c0255148 | ||
|
|
6b67c6a296 | ||
|
|
0017a6110f | ||
|
|
6bbb9ac512 | ||
|
|
6feb864e30 | ||
|
|
6ff04bf83d | ||
|
|
80778ddd25 | ||
|
|
c455e8bc75 | ||
|
|
411cffdeec | ||
|
|
04689c4138 | ||
|
|
50928fc1ef | ||
|
|
20c34a4312 | ||
|
|
fdd2634721 | ||
|
|
b043ac88e1 | ||
|
|
5c18914f2a | ||
|
|
a0e1ecb2ba | ||
|
|
5279ef3f96 | ||
|
|
36fb6e6877 | ||
|
|
6632db44ae | ||
|
|
613a5a19db | ||
|
|
21d63485b1 | ||
|
|
eaae1ae3fb | ||
|
|
333263b344 | ||
|
|
50db29c634 | ||
|
|
fe5c6c29e1 | ||
|
|
34d842901d | ||
|
|
a94833c482 | ||
|
|
0676ed3227 | ||
|
|
e12e480f79 | ||
|
|
3fa27e7464 | ||
|
|
013cbb7e1a | ||
|
|
97aee2acb0 | ||
|
|
43c2336d7f | ||
|
|
220677d76d | ||
|
|
0f396470ff | ||
|
|
94266c5111 | ||
|
|
0b3370f6fa | ||
|
|
c5abeccb65 | ||
|
|
aa7772b36c | ||
|
|
f47d84cf24 | ||
|
|
d97485cfc0 | ||
|
|
4fc4ac0c46 | ||
|
|
bd41fcfbe6 | ||
|
|
bd9623c892 | ||
|
|
00e65b239c | ||
|
|
b654a0fbd3 | ||
|
|
2f757d249d | ||
|
|
db33f31dc1 | ||
|
|
661dcdda07 | ||
|
|
22a65f7666 | ||
|
|
1ce35da941 | ||
|
|
e6cffd9add | ||
|
|
213a00ec5e | ||
|
|
c03c057a42 | ||
|
|
73849713e8 | ||
|
|
0610a4e156 | ||
|
|
29efaadf0a | ||
|
|
02ba85f8e0 | ||
|
|
d563b3ecb0 | ||
|
|
ce0ab6b836 | ||
|
|
feedb0808b | ||
|
|
c14737f39c | ||
|
|
4b6375a4a4 | ||
|
|
bfa1af2101 | ||
|
|
a866e257fd | ||
|
|
d34656475e | ||
|
|
2b1edeceb4 | ||
|
|
f49d1247d2 | ||
|
|
ee697391d6 | ||
|
|
93c02c012f | ||
|
|
545258bd26 | ||
|
|
9611ecf356 | ||
|
|
0887e9a6de | ||
|
|
a2086298f6 | ||
|
|
b7c88467e2 | ||
|
|
0c997dbe85 | ||
|
|
6d3265a7fb | ||
|
|
a46092a90a | ||
|
|
25da342f75 | ||
|
|
c3160aea0a | ||
|
|
7bbc240cae | ||
|
|
1958e11f45 | ||
|
|
738a11dcdc | ||
|
|
280bc617d0 | ||
|
|
252def6bab | ||
|
|
4361f071e8 | ||
|
|
7ef8099916 | ||
|
|
1558b44495 | ||
|
|
0c42ea97a4 | ||
|
|
51f2a45217 | ||
|
|
3b0ff1d7ca | ||
|
|
62dea1454d | ||
|
|
b5f8137499 | ||
|
|
e64268427d | ||
|
|
99ee15c731 | ||
|
|
dfa392edb7 | ||
|
|
7075847ef4 | ||
|
|
19da0a2068 | ||
|
|
180339f16b | ||
|
|
c86afd1a5c | ||
|
|
910a42d647 | ||
|
|
18abe7d9e1 | ||
|
|
ae5338bde5 | ||
|
|
7843001aa7 | ||
|
|
cff19ec212 | ||
|
|
c126e40795 | ||
|
|
11c4d7311b | ||
|
|
1f2b1f5880 | ||
|
|
14f9ba5c3f | ||
|
|
26183926a3 | ||
|
|
a7a3c52c88 | ||
|
|
350997b03c | ||
|
|
48c6e2248a | ||
|
|
08fcf381e8 | ||
|
|
f3f78303b1 | ||
|
|
555bc46d14 | ||
|
|
b14f68378d | ||
|
|
8553460afe | ||
|
|
16cf97584c | ||
|
|
a5680759eb | ||
|
|
b6e073d03c | ||
|
|
d7752ebd8b | ||
|
|
fdc9364062 | ||
|
|
da47929b6a | ||
|
|
3f663e7a4e | ||
|
|
3453f63787 | ||
|
|
8cd46388e5 | ||
|
|
5f819dc68a | ||
|
|
14aa9eaa39 | ||
|
|
c0585278d0 | ||
|
|
d9a36a889e | ||
|
|
788e80ce39 | ||
|
|
68b31dddd5 | ||
|
|
f0d9fc7bce | ||
|
|
684e85cc5e | ||
|
|
d45be919cd | ||
|
|
5c3bd1b19f | ||
|
|
600e8dd3c8 | ||
|
|
08764d5bbc | ||
|
|
749387bbfa | ||
|
|
88bb908c76 | ||
|
|
d260dda29e | ||
|
|
a8362c1a70 | ||
|
|
87fa294a42 | ||
|
|
330c46cdb2 | ||
|
|
27f4b56e71 | ||
|
|
2262bc18fe | ||
|
|
bc0e688f96 | ||
|
|
2fb02c57b6 | ||
|
|
bf0f360935 | ||
|
|
6976865176 | ||
|
|
c862b89079 | ||
|
|
6a15977238 | ||
|
|
7d6468f70b | ||
|
|
ed9a351518 | ||
|
|
d4b3e0ad62 | ||
|
|
1bd2d3d992 | ||
|
|
ce452d5759 | ||
|
|
56cb24bd0d | ||
|
|
c7b46b71a0 | ||
|
|
e7e6b98958 | ||
|
|
2f27b48f7b | ||
|
|
04a501edb7 | ||
|
|
01f07fb952 | ||
|
|
6680827faf | ||
|
|
7699c38b99 | ||
|
|
aa265352ff | ||
|
|
56e5e66f86 | ||
|
|
753364bbff | ||
|
|
8fbb28cc6f | ||
|
|
066ba95737 | ||
|
|
1b9789937f |
@@ -7,11 +7,16 @@
|
|||||||
.#*
|
.#*
|
||||||
.git
|
.git
|
||||||
.deps
|
.deps
|
||||||
|
TAGS
|
||||||
|
tags
|
||||||
init
|
init
|
||||||
build/hyper_daemon
|
build/hyper_daemon
|
||||||
build/hyper-initrd.img
|
build/hyper-initrd.img
|
||||||
|
build/cbfs.rom
|
||||||
build/root/*
|
build/root/*
|
||||||
|
build/*iso
|
||||||
build/daemon
|
build/daemon
|
||||||
|
build/kernel_config.old
|
||||||
build/.*
|
build/.*
|
||||||
src/.*
|
src/.*
|
||||||
Makefile
|
Makefile
|
||||||
|
|||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
|
||||||
|
language: c
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- go: 1.7
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- sudo apt-get update -qq
|
||||||
|
- sudo apt-get install -y autoconf automake pkg-config libdevmapper-dev libsqlite3-dev libvirt-dev qemu libvirt-bin -qq
|
||||||
|
- cd `mktemp -d`
|
||||||
|
- wget https://git.fedorahosted.org/cgit/lvm2.git/snapshot/lvm2-2_02_131.tar.xz
|
||||||
|
- tar xf lvm2-2_02_131.tar.xz
|
||||||
|
- cd lvm2-2_02_131
|
||||||
|
- ./configure && make device-mapper && sudo make install
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cd ${TRAVIS_BUILD_DIR}
|
||||||
|
- ./autogen.sh
|
||||||
|
- ./configure
|
||||||
|
- make
|
||||||
|
- hack/test-cmd.sh
|
||||||
@@ -1 +1,8 @@
|
|||||||
SUBDIRS=src build
|
SUBDIRS=src build
|
||||||
|
|
||||||
|
initrd-local:
|
||||||
|
@echo finish make initrd
|
||||||
|
cbfs-local:
|
||||||
|
@echo finish make cbfs
|
||||||
|
kernel-local:
|
||||||
|
@echo finish make kernel
|
||||||
|
|||||||
@@ -1,13 +1,26 @@
|
|||||||
# The init Task for Hyper
|
# The init Task for HyperContainer
|
||||||
|
|
||||||
You can get binary installer of Hyper and HyperStart through [The Hyper Page](https://github.com/hyperhq/hyper)
|
You can get the binary installer of HyperContainer and HyperStart through [The Hyper Page](https://github.com/hyperhq/hyperd)
|
||||||
|
|
||||||
## Build from source
|
## Build from source
|
||||||
|
|
||||||
clone this repo, and make sure have build-essentials installed. Go into the working copy and
|
clone this repo, and make sure you have build-essentials installed. Go into the working copy and
|
||||||
|
|
||||||
> ./autogen.sh
|
> ./autogen.sh
|
||||||
> ./configure
|
> ./configure
|
||||||
> make
|
> make
|
||||||
|
|
||||||
Then you can find `hyper-initrd.img` in build directory, together with a pre-build kernel.
|
Then you can find `hyper-initrd.img` in the build directory, together with a pre-built kernel.
|
||||||
|
|
||||||
|
If you want to run hyperstart with 64-bit ARM architecture, please reconfigure with flag --with-aarch64,
|
||||||
|
|
||||||
|
> ./configure --with-aarch64
|
||||||
|
> make
|
||||||
|
|
||||||
|
If you want to get the boot disk file for VirtualBox, please reconfigure with flag --with-vbox,
|
||||||
|
|
||||||
|
> ./configure --with-vbox
|
||||||
|
> make
|
||||||
|
|
||||||
|
Then you can find `hyper-vbox-bootimage.iso` in the build directory. Booting from this iso will
|
||||||
|
bring you to the hyper world.
|
||||||
|
|||||||
+5
-5
@@ -8,34 +8,34 @@ DIE=0
|
|||||||
|
|
||||||
test -f src/init.c || {
|
test -f src/init.c || {
|
||||||
echo
|
echo
|
||||||
echo "You must run this script in the top-level hyperint drectory."
|
echo "You must run this script in the top-level hyperstart drectory."
|
||||||
echo
|
echo
|
||||||
DIE=1
|
DIE=1
|
||||||
}
|
}
|
||||||
|
|
||||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||||
echo
|
echo
|
||||||
echo "You must have autoconf installed to generate the hyperinit."
|
echo "You must have autoconf installed to generate the hyperstart."
|
||||||
echo
|
echo
|
||||||
DIE=1
|
DIE=1
|
||||||
}
|
}
|
||||||
|
|
||||||
(autoheader --version) < /dev/null > /dev/null 2>&1 || {
|
(autoheader --version) < /dev/null > /dev/null 2>&1 || {
|
||||||
echo
|
echo
|
||||||
echo "You must have autoheader installed to generate the hypernit."
|
echo "You must have autoheader installed to generate the hyperstart."
|
||||||
echo
|
echo
|
||||||
DIE=1
|
DIE=1
|
||||||
}
|
}
|
||||||
|
|
||||||
(automake --version) < /dev/null > /dev/null 2>&1 || {
|
(automake --version) < /dev/null > /dev/null 2>&1 || {
|
||||||
echo
|
echo
|
||||||
echo "You must have automake installed to generate the hypernit."
|
echo "You must have automake installed to generate the hyperstart."
|
||||||
echo
|
echo
|
||||||
DIE=1
|
DIE=1
|
||||||
}
|
}
|
||||||
(autoreconf --version) < /dev/null > /dev/null 2>&1 || {
|
(autoreconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||||
echo
|
echo
|
||||||
echo "You must have autoreconf installed to generate the hypernit."
|
echo "You must have autoreconf installed to generate the hyperstart."
|
||||||
echo
|
echo
|
||||||
DIE=1
|
DIE=1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
FROM centos:7
|
||||||
|
MAINTAINER Hyper Developers <dev@hyper.sh>
|
||||||
|
|
||||||
|
RUN yum install -y patch gcc ncurses-devel make openssl-devel bc
|
||||||
|
|
||||||
|
ENV KERNEL_VERSION 4.4.12
|
||||||
|
ENV LOCALVERSION -hyper
|
||||||
|
ENV KERNEL_RELEASE ${KERNEL_VERSION}${LOCALVERSION}
|
||||||
|
|
||||||
|
ENV KBUILD_BUILD_USER dev
|
||||||
|
ENV KBUILD_BUILD_HOST hyper.sh
|
||||||
|
ENV KBUILD_BUILD_VERSION 1
|
||||||
|
|
||||||
|
RUN mkdir /root/build/ && mkdir /root/build/result/
|
||||||
|
RUN curl -fSL https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-${KERNEL_VERSION}.tar.gz | tar -zx -C /root/build
|
||||||
|
|
||||||
|
COPY kernel_config /root/build/linux-${KERNEL_VERSION}/.config
|
||||||
|
COPY kernel_patch/ /root/build/kernel_patch/
|
||||||
|
|
||||||
|
RUN cd /root/build/linux-${KERNEL_VERSION}/ && for patch in /root/build/kernel_patch/*.patch; do patch -p1 <$patch || exit 1; done
|
||||||
|
RUN cd /root/build/linux-${KERNEL_VERSION}/ && make silentoldconfig && make -j 8
|
||||||
|
|
||||||
|
# install to /root/build/result/ so that we can get them from it
|
||||||
|
RUN cp /root/build/linux-${KERNEL_VERSION}/arch/x86_64/boot/bzImage /root/build/result/kernel
|
||||||
|
RUN mkdir /root/build/result/modules &&\
|
||||||
|
cd /root/build/linux-${KERNEL_VERSION}/ && make modules_install INSTALL_MOD_PATH="/root/build/result/modules" &&\
|
||||||
|
cd /root/build/result/modules/lib/modules/ && rm -f ${KERNEL_RELEASE}/{build,source} &&\
|
||||||
|
tar -cf /root/build/result/modules.tar ${KERNEL_RELEASE}/ && rm -rf /root/build/result/modules
|
||||||
|
RUN cp /root/build/linux-${KERNEL_VERSION}/.config /root/build/result/kernel_config
|
||||||
+20
-3
@@ -1,7 +1,24 @@
|
|||||||
bin_PROGRAMS=hyper_daemon
|
all-local: initrd
|
||||||
hyper_daemon_SOURCES=hyper_daemon.c ../src/net.c
|
|
||||||
all-local:
|
if WITH_VBOX
|
||||||
|
initrd-local:
|
||||||
|
bash ./make-initrd.sh vbox
|
||||||
|
else
|
||||||
|
if WITH_AARCH64
|
||||||
|
initrd-local:
|
||||||
|
bash ./make-initrd.sh aarch64
|
||||||
|
else
|
||||||
|
initrd-local:
|
||||||
bash ./make-initrd.sh
|
bash ./make-initrd.sh
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
cbfs-local:
|
cbfs-local:
|
||||||
bash ./make-initrd.sh cbfs
|
bash ./make-initrd.sh cbfs
|
||||||
|
|
||||||
|
kernel-local:
|
||||||
|
hyperctl build -t hyperstart-dev:latest .
|
||||||
|
hyperctl run --rm hyperstart-dev:latest cat /root/build/result/kernel >kernel.new && mv -f kernel.new kernel
|
||||||
|
hyperctl run --rm hyperstart-dev:latest cat /root/build/result/modules.tar >modules.tar
|
||||||
|
mv kernel_config kernel_config.old
|
||||||
|
hyperctl run --rm hyperstart-dev:latest cat /root/build/result/kernel_config >kernel_config
|
||||||
|
|||||||
Executable
BIN
Binary file not shown.
@@ -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;
|
|
||||||
}
|
|
||||||
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
+918
-177
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
|||||||
|
From 084b4a5aa4b90975f7ac6b4714a6b449430ef4c4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peng Tao <bergwolf@gmail.com>
|
||||||
|
Date: Wed, 4 May 2016 12:01:22 +0800
|
||||||
|
Subject: [PATCH] HACK: 9P: always use cached inode to fill in v9fs_vfs_getattr
|
||||||
|
|
||||||
|
So that if in cache=none mode, we don't have to lookup server that
|
||||||
|
might not support open-unlink-fstat operation.
|
||||||
|
|
||||||
|
Signed-off-by: Peng Tao <bergwolf@gmail.com>
|
||||||
|
---
|
||||||
|
fs/9p/vfs_inode.c | 2 +-
|
||||||
|
fs/9p/vfs_inode_dotl.c | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
|
||||||
|
index 5110785..43ebb31 100644
|
||||||
|
--- a/fs/9p/vfs_inode.c
|
||||||
|
+++ b/fs/9p/vfs_inode.c
|
||||||
|
@@ -1059,7 +1059,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||||
|
|
||||||
|
p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
|
||||||
|
v9ses = v9fs_dentry2v9ses(dentry);
|
||||||
|
- if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
|
||||||
|
+ if (!d_really_is_negative(dentry) || v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
|
||||||
|
generic_fillattr(d_inode(dentry), stat);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
|
||||||
|
index cb899af..b1e4205 100644
|
||||||
|
--- a/fs/9p/vfs_inode_dotl.c
|
||||||
|
+++ b/fs/9p/vfs_inode_dotl.c
|
||||||
|
@@ -479,7 +479,7 @@ v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
|
||||||
|
|
||||||
|
p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
|
||||||
|
v9ses = v9fs_dentry2v9ses(dentry);
|
||||||
|
- if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
|
||||||
|
+ if (!d_really_is_negative(dentry) || v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
|
||||||
|
generic_fillattr(d_inode(dentry), stat);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.5.0
|
||||||
|
|
||||||
Executable
BIN
Binary file not shown.
+83
-18
@@ -1,40 +1,105 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
rm -rf root
|
rm -rf /tmp/hyperstart-rootfs
|
||||||
mkdir root
|
mkdir -p /tmp/hyperstart-rootfs/lib \
|
||||||
|
/tmp/hyperstart-rootfs/lib64 \
|
||||||
|
/tmp/hyperstart-rootfs/lib/modules
|
||||||
|
|
||||||
cp ../src/init ./root
|
mkdir -m 0755 -p /tmp/hyperstart-rootfs/dev \
|
||||||
|
/tmp/hyperstart-rootfs/sys \
|
||||||
|
/tmp/hyperstart-rootfs/sbin \
|
||||||
|
/tmp/hyperstart-rootfs/bin \
|
||||||
|
/tmp/hyperstart-rootfs/proc
|
||||||
|
|
||||||
ldd ./root/init | while read line
|
cp ../src/init /tmp/hyperstart-rootfs
|
||||||
|
cp busybox /tmp/hyperstart-rootfs
|
||||||
|
cp iptables /tmp/hyperstart-rootfs
|
||||||
|
cp libm.so.6 /tmp/hyperstart-rootfs/lib64/
|
||||||
|
|
||||||
|
if [ "$1"x = "aarch64"x ]; then
|
||||||
|
echo "build hyperstart for aarch64"
|
||||||
|
tar -xf modules_aarch64.tar -C /tmp/hyperstart-rootfs/lib/modules
|
||||||
|
else
|
||||||
|
tar -xf modules.tar -C /tmp/hyperstart-rootfs/lib/modules
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create symlinks to busybox and iptables
|
||||||
|
BUSYBOX_BINARIES=(/bin/sh /bin/tar /bin/hwclock /sbin/modprobe /sbin/depmod)
|
||||||
|
for bin in ${BUSYBOX_BINARIES[@]}
|
||||||
|
do
|
||||||
|
mkdir -p /tmp/hyperstart-rootfs/`dirname ${bin}`
|
||||||
|
ln -sf /busybox /tmp/hyperstart-rootfs/${bin}
|
||||||
|
done
|
||||||
|
IPTABLES_BINARIES=(/sbin/iptables /sbin/iptables-restore /sbin/iptables-save)
|
||||||
|
for bin in ${IPTABLES_BINARIES[@]}
|
||||||
|
do
|
||||||
|
mkdir -p /tmp/hyperstart-rootfs/`dirname ${bin}`
|
||||||
|
ln -sf /iptables /tmp/hyperstart-rootfs/${bin}
|
||||||
|
done
|
||||||
|
|
||||||
|
ldd /tmp/hyperstart-rootfs/init | while read line
|
||||||
do
|
do
|
||||||
arr=(${line// / })
|
arr=(${line// / })
|
||||||
|
|
||||||
for lib in ${arr[@]}
|
for lib in ${arr[@]}
|
||||||
do
|
do
|
||||||
if [ "${lib:0:1}" = "/" ]; then
|
if [ "${lib:0:1}" = "/" ]; then
|
||||||
dir=root`dirname $lib`
|
dir=/tmp/hyperstart-rootfs`dirname $lib`
|
||||||
mkdir -p "${dir}"
|
mkdir -p "${dir}"
|
||||||
cp -f $lib $dir
|
cp -f $lib $dir
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
cd ./root && find . | cpio -H newc -o | gzip -9 > ../hyper-initrd.img
|
|
||||||
|
|
||||||
|
if [ "$1"x = "vbox"x ]; then
|
||||||
|
echo "build initrd for vbox"
|
||||||
|
cp ./vbox/driver/* /tmp/hyperstart-rootfs
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$1" != "cbfs" ]; then
|
( cd /tmp/hyperstart-rootfs && find . | cpio -H newc -o | gzip -9 ) > ./hyper-initrd.img
|
||||||
|
|
||||||
|
rm -rf /tmp/hyperstart-rootfs
|
||||||
|
|
||||||
|
if [ "$1"x = "cbfs"x ]; then
|
||||||
|
echo "build cbfs"
|
||||||
|
rm -rf .cbfs
|
||||||
|
rm -rf cbfs.rom
|
||||||
|
|
||||||
|
mkdir .cbfs
|
||||||
|
dd if=/dev/zero of=.cbfs/boot.bin bs=4096 count=1
|
||||||
|
cbfstool .cbfs/cbfs.rom create -s 8128k -B .cbfs/boot.bin -m x86 0x1000
|
||||||
|
cbfstool .cbfs/cbfs.rom add -f kernel -n vmlinuz -t raw
|
||||||
|
cbfstool .cbfs/cbfs.rom add -f hyper-initrd.img -n initrd -t raw
|
||||||
|
echo 'console=ttyS0 panic=1 no_timer_check' > .cbfs/cmdline
|
||||||
|
cbfstool .cbfs/cbfs.rom add -f .cbfs/cmdline -n cmdline -t raw
|
||||||
|
cp .cbfs/cbfs.rom ./
|
||||||
|
rm -rf .cbfs
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd ../
|
if [ "$1"x = "vbox"x ]; then
|
||||||
|
mkdir tmp
|
||||||
|
mkdir -p tmp/images
|
||||||
|
mkdir -p tmp/kernel
|
||||||
|
mkdir -p tmp/isolinux
|
||||||
|
|
||||||
echo "build cbfs"
|
cd tmp
|
||||||
rm -rf .cbfs
|
cp ../vbox/kernel ./kernel/
|
||||||
rm -rf cbfs.rom
|
cp ../hyper-initrd.img ./images/initrd.img
|
||||||
|
cp ../vbox/isolinux/isolinux.bin ./isolinux/
|
||||||
|
cp ../vbox/isolinux/ldlinux.c32 ./isolinux/
|
||||||
|
|
||||||
mkdir .cbfs
|
cat > isolinux/syslinux.cfg <<EOF
|
||||||
dd if=/dev/zero of=.cbfs/boot.bin bs=4096 count=1
|
DEFAULT linux
|
||||||
cbfstool .cbfs/cbfs.rom create -s 4096k -B .cbfs/boot.bin -m x86 0x1000
|
LABEL linux
|
||||||
cbfstool .cbfs/cbfs.rom add -f kernel -n vmlinuz -t raw
|
SAY Now booting the kernel from SYSLINUX...
|
||||||
cbfstool .cbfs/cbfs.rom add -f hyper-initrd.img -n initrd -t raw
|
KERNEL /kernel/kernel
|
||||||
cp .cbfs/cbfs.rom ./
|
APPEND initrd=/images/initrd.img
|
||||||
rm -rf .cbfs
|
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.
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
+24
-10
@@ -2,9 +2,9 @@
|
|||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_PREREQ([2.69])
|
AC_PREREQ([2.69])
|
||||||
AC_INIT([hyperstart], [0.1], [www.hyper.sh])
|
AC_INIT([hyperstart], [0.6.2], [www.hyper.sh])
|
||||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
|
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
|
||||||
AM_EXTRA_RECURSIVE_TARGETS([cbfs])
|
AM_EXTRA_RECURSIVE_TARGETS([initrd cbfs kernel])
|
||||||
AC_CONFIG_SRCDIR([src/init.c])
|
AC_CONFIG_SRCDIR([src/init.c])
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
|
||||||
@@ -32,20 +32,33 @@ AC_TYPE_UINT8_T
|
|||||||
# Checks for library functions.
|
# Checks for library functions.
|
||||||
AC_FUNC_FORK
|
AC_FUNC_FORK
|
||||||
AC_CHECK_FUNCS([dup2 memmove memset mkdir setenv socket strchr strdup strrchr strtoul], [fail=0], [fail=1])
|
AC_CHECK_FUNCS([dup2 memmove memset mkdir setenv socket strchr strdup strrchr strtoul], [fail=0], [fail=1])
|
||||||
|
AC_CHECK_FUNCS([setns])
|
||||||
|
|
||||||
if test "$fail" = "1" ; then
|
if test "$fail" = "1" ; then
|
||||||
AC_MSG_ERROR(Unable to find necessary functions)
|
AC_MSG_ERROR(Unable to find necessary functions)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_ARG_WITH([ttys],
|
AC_ARG_WITH([aarch64],
|
||||||
[AS_HELP_STRING([--with-ttys],
|
[AS_HELP_STRING([--with-aarch64],
|
||||||
[use pci serial device as container tty])],
|
[run hyperstart with 64-bit ARM architecture])],
|
||||||
[],[with_ttys=yes])
|
[],[with_aarch64=no])
|
||||||
|
|
||||||
if test "x$with_ttys" != "xno" ; then
|
if test "x$with_aarch64" != "xno" ; then
|
||||||
AC_DEFINE_UNQUOTED([WITH_TTYS], 1, [where use pci serial device as container tty])
|
AC_DEFINE_UNQUOTED([WITH_AARCH64], 1, [run hyperstart with 64-bit ARM architecture])
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL([WITH_TTYS], [test "x$with_ttys" != "xno"])
|
|
||||||
|
AM_CONDITIONAL([WITH_AARCH64], [test "x$with_aarch64" != "xno"])
|
||||||
|
|
||||||
|
AC_ARG_WITH([vbox],
|
||||||
|
[AS_HELP_STRING([--with-vbox],
|
||||||
|
[run hyperstart on Virtualbox])],
|
||||||
|
[],[with_vbox=no])
|
||||||
|
|
||||||
|
if test "x$with_vbox" != "xno" ; then
|
||||||
|
AC_DEFINE_UNQUOTED([WITH_VBOX], 1, [run hyperstart on Virtualbox])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL([WITH_VBOX], [test "x$with_vbox" != "xno"])
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
@@ -58,7 +71,8 @@ AC_MSG_RESULT([
|
|||||||
${PACKAGE} ${VERSION}
|
${PACKAGE} ${VERSION}
|
||||||
prefix: ${prefix}
|
prefix: ${prefix}
|
||||||
|
|
||||||
with-ttys: ${with_ttys}
|
with-vbox: ${with_vbox}
|
||||||
|
with-aarch64: ${with_aarch64}
|
||||||
|
|
||||||
compiler: ${CC}
|
compiler: ${CC}
|
||||||
cflags: ${CFLAGS}
|
cflags: ${CFLAGS}
|
||||||
|
|||||||
Executable
+22
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
###########################
|
||||||
|
# test hyperstart from hyper
|
||||||
|
|
||||||
|
export HYPER_RUNTIME=/var/lib/hyper
|
||||||
|
sudo mkdir -p ${HYPER_RUNTIME}
|
||||||
|
sudo cp build/kernel ${HYPER_RUNTIME}/kernel
|
||||||
|
sudo cp build/hyper-initrd.img ${HYPER_RUNTIME}/hyper-initrd.img
|
||||||
|
|
||||||
|
mkdir -p ${GOPATH}/src/github.com/hyperhq
|
||||||
|
git clone https://github.com/hyperhq/hyperd.git ${GOPATH}/src/github.com/hyperhq/hyperd
|
||||||
|
cd ${GOPATH}/src/github.com/hyperhq/hyperd
|
||||||
|
./autogen.sh
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
hack/test-cmd.sh
|
||||||
|
|
||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
AM_CFLAGS = -Wall
|
AM_CFLAGS = -Wall -Werror
|
||||||
bin_PROGRAMS=init
|
bin_PROGRAMS=init
|
||||||
init_SOURCES=init.c jsmn.c net.c util.c parse.c container.c exec.c event.c
|
init_SOURCES=init.c jsmn.c net.c util.c parse.c parson.c container.c exec.c event.c portmapping.c
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#ifndef _HYPERSTART_API_H_
|
||||||
|
#define _HYPERSTART_API_H_
|
||||||
|
|
||||||
|
#define APIVERSION 4242
|
||||||
|
|
||||||
|
// control command id
|
||||||
|
enum {
|
||||||
|
GETVERSION,
|
||||||
|
STARTPOD,
|
||||||
|
GETPOD,
|
||||||
|
STOPPOD_DEPRECATED,
|
||||||
|
DESTROYPOD,
|
||||||
|
RESTARTCONTAINER,
|
||||||
|
EXECCMD,
|
||||||
|
CMDFINISHED,
|
||||||
|
READY,
|
||||||
|
ACK,
|
||||||
|
ERROR,
|
||||||
|
WINSIZE,
|
||||||
|
PING,
|
||||||
|
PODFINISHED,
|
||||||
|
NEXT,
|
||||||
|
WRITEFILE,
|
||||||
|
READFILE,
|
||||||
|
NEWCONTAINER,
|
||||||
|
KILLCONTAINER,
|
||||||
|
ONLINECPUMEM,
|
||||||
|
SETUPINTERFACE,
|
||||||
|
SETUPROUTE,
|
||||||
|
REMOVECONTAINER,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* control message format
|
||||||
|
* | ctrl id | length | payload (length-8) |
|
||||||
|
* | . . . . | . . . . | . . . . . . . . . . . . |
|
||||||
|
* 0 4 8 length
|
||||||
|
*/
|
||||||
|
#define CONTROL_HEADER_SIZE 8
|
||||||
|
#define CONTROL_HEADER_LENGTH_OFFSET 4
|
||||||
|
|
||||||
|
/*
|
||||||
|
* stream message format
|
||||||
|
* | stream sequence | length | payload (length-12) |
|
||||||
|
* | . . . . . . . . | . . . . | . . . . . . . . . . . . |
|
||||||
|
* 0 8 12 length
|
||||||
|
*/
|
||||||
|
#define STREAM_HEADER_SIZE 12
|
||||||
|
#define STREAM_HEADER_LENGTH_OFFSET 8
|
||||||
|
|
||||||
|
#endif /* _HYPERSTART_API_H_ */
|
||||||
+534
-266
File diff suppressed because it is too large
Load Diff
+31
-14
@@ -3,45 +3,62 @@
|
|||||||
|
|
||||||
#include "exec.h"
|
#include "exec.h"
|
||||||
|
|
||||||
struct env {
|
|
||||||
char *env;
|
|
||||||
char *value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct volume {
|
struct volume {
|
||||||
char *device;
|
char *device;
|
||||||
|
char *scsiaddr;
|
||||||
char *mountpoint;
|
char *mountpoint;
|
||||||
char *fstype;
|
char *fstype;
|
||||||
int readonly;
|
int readonly;
|
||||||
|
int docker;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fsmap {
|
struct fsmap {
|
||||||
char *source;
|
char *source;
|
||||||
char *path;
|
char *path;
|
||||||
int readonly;
|
int readonly;
|
||||||
|
int docker;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sysctl {
|
||||||
|
char *path;
|
||||||
|
char *value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct port {
|
||||||
|
int host_port;
|
||||||
|
int container_port;
|
||||||
|
char *protocol;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hyper_container {
|
struct hyper_container {
|
||||||
|
struct list_head list;
|
||||||
|
struct hyper_exec exec;
|
||||||
|
int ns;
|
||||||
|
uint32_t code;
|
||||||
|
|
||||||
|
// configs
|
||||||
char *id;
|
char *id;
|
||||||
char *rootfs;
|
char *rootfs;
|
||||||
char *image;
|
char *image;
|
||||||
char *workdir;
|
char *scsiaddr;
|
||||||
char *fstype;
|
char *fstype;
|
||||||
struct volume *vols;
|
struct volume *vols;
|
||||||
struct env *envs;
|
|
||||||
struct fsmap *maps;
|
struct fsmap *maps;
|
||||||
|
struct sysctl *sys;
|
||||||
|
struct port *ports;
|
||||||
int vols_num;
|
int vols_num;
|
||||||
int envs_num;
|
|
||||||
int maps_num;
|
int maps_num;
|
||||||
uint32_t code;
|
int sys_num;
|
||||||
struct hyper_exec exec;
|
int ports_num;
|
||||||
|
int initialize;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hyper_pod;
|
struct hyper_pod;
|
||||||
|
|
||||||
int hyper_start_containers(struct hyper_pod *pod);
|
int hyper_setup_container(struct hyper_container *container, struct hyper_pod *pod);
|
||||||
struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id);
|
struct hyper_container *hyper_find_container(struct hyper_pod *pod, const char *id);
|
||||||
int hyper_restart_containers(struct hyper_pod *pod);
|
void hyper_cleanup_container(struct hyper_container *container, struct hyper_pod *pod);
|
||||||
void hyper_cleanup_container(struct hyper_pod *pod);
|
void hyper_cleanup_containers(struct hyper_pod *pod);
|
||||||
|
void hyper_free_container(struct hyper_container *c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+130
-41
@@ -5,33 +5,45 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "net.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "hyper.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
|
||||||
void hyper_reset_event(struct hyper_event *de)
|
void hyper_reset_event(struct hyper_event *he)
|
||||||
{
|
{
|
||||||
free(de->buf.data);
|
free(he->rbuf.data);
|
||||||
de->buf.data = NULL;
|
free(he->wbuf.data);
|
||||||
memset(de, 0, sizeof(*de));
|
close(he->fd);
|
||||||
|
memset(he, 0, sizeof(*he));
|
||||||
|
he->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hyper_init_event(struct hyper_event *de,
|
int hyper_init_event(struct hyper_event *he, struct hyper_event_ops *ops, void *arg)
|
||||||
struct hyper_event_ops *ops,
|
|
||||||
uint32_t size, int to, void *arg)
|
|
||||||
{
|
{
|
||||||
struct hyper_buf *buf = &de->buf;
|
struct hyper_buf *rbuf = &he->rbuf;
|
||||||
|
struct hyper_buf *wbuf = &he->wbuf;
|
||||||
|
|
||||||
memset(buf, 0, sizeof(*buf));
|
memset(rbuf, 0, sizeof(*rbuf));
|
||||||
|
memset(wbuf, 0, sizeof(*wbuf));
|
||||||
|
|
||||||
de->ops = ops;
|
he->ops = ops;
|
||||||
de->ptr = arg;
|
he->ptr = arg;
|
||||||
de->to = to;
|
rbuf->size = ops->rbuf_size;
|
||||||
buf->size = size;
|
wbuf->size = ops->wbuf_size;
|
||||||
|
|
||||||
if (size) {
|
if (rbuf->size) {
|
||||||
buf->data = malloc(size);
|
rbuf->data = malloc(rbuf->size);
|
||||||
if (buf->data == NULL) {
|
if (rbuf->data == NULL) {
|
||||||
fprintf(stderr, "allocate data for event failed\n");
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,21 +51,22 @@ int hyper_init_event(struct hyper_event *de,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hyper_add_event(int efd, struct hyper_event *de)
|
int hyper_add_event(int efd, struct hyper_event *he, int flag)
|
||||||
{
|
{
|
||||||
struct epoll_event event = {
|
struct epoll_event event = {
|
||||||
.events = EPOLLIN,
|
.events = flag,
|
||||||
.data.ptr = de,
|
.data.ptr = he,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (hyper_setfd_nonblock(de->fd) < 0) {
|
he->flag = flag;
|
||||||
|
if (hyper_setfd_nonblock(he->fd) < 0) {
|
||||||
perror("set fd nonblock failed");
|
perror("set fd nonblock failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stdout, "%s add event fd %d, %p\n", __func__, de->fd, de->ops);
|
fprintf(stdout, "%s add event fd %d, %p\n", __func__, he->fd, he->ops);
|
||||||
|
|
||||||
if (epoll_ctl(efd, EPOLL_CTL_ADD, de->fd, &event) < 0) {
|
if (epoll_ctl(efd, EPOLL_CTL_ADD, he->fd, &event) < 0) {
|
||||||
perror("epoll_ctl fd failed");
|
perror("epoll_ctl fd failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -61,31 +74,107 @@ int hyper_add_event(int efd, struct hyper_event *de)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hyper_event_hup(struct hyper_event *de, int efd)
|
int hyper_modify_event(int efd, struct hyper_event *he, int flag)
|
||||||
{
|
{
|
||||||
if (epoll_ctl(efd, EPOLL_CTL_DEL, de->fd, NULL) < 0)
|
struct epoll_event event = {
|
||||||
|
.events = flag,
|
||||||
|
.data.ptr = he,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (he->flag == flag)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
he->flag = flag;
|
||||||
|
fprintf(stdout, "%s modify event fd %d, %p, event %d\n",
|
||||||
|
__func__, he->fd, he, flag);
|
||||||
|
|
||||||
|
if (epoll_ctl(efd, EPOLL_CTL_MOD, he->fd, &event) < 0) {
|
||||||
|
perror("epoll_ctl fd failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hyper_requeue_event(int efd, struct hyper_event *ev)
|
||||||
|
{
|
||||||
|
struct epoll_event event = {
|
||||||
|
.events = ev->flag,
|
||||||
|
.data.ptr = ev,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (epoll_ctl(efd, EPOLL_CTL_DEL, ev->fd, NULL) < 0) {
|
||||||
|
perror("epoll_ctl del fd failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (epoll_ctl(efd, EPOLL_CTL_ADD, ev->fd, &event) < 0) {
|
||||||
|
perror("epoll_ctl add fd failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hyper_event_write(struct hyper_event *he, int efd)
|
||||||
|
{
|
||||||
|
struct hyper_buf *buf = &he->wbuf;
|
||||||
|
uint32_t len = 0;
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
while (len < buf->get) {
|
||||||
|
size = write(he->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, he, he->flag & ~EPOLLOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hyper_event_hup(struct hyper_event *he, int efd)
|
||||||
|
{
|
||||||
|
if (epoll_ctl(efd, EPOLL_CTL_DEL, he->fd, NULL) < 0)
|
||||||
perror("epoll_ctl del epoll event failed");
|
perror("epoll_ctl del epoll event failed");
|
||||||
close(de->fd);
|
hyper_reset_event(he);
|
||||||
hyper_reset_event(de);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int hyper_handle_event(int efd, struct epoll_event *event)
|
int hyper_handle_event(int efd, struct epoll_event *event)
|
||||||
{
|
{
|
||||||
struct hyper_event *de = event->data.ptr;
|
struct hyper_event *he = event->data.ptr;
|
||||||
|
fprintf(stdout, "%s get event %d, he %p, fd %d. ops %p\n",
|
||||||
|
__func__, event->events, he, he->fd, he->ops);
|
||||||
|
|
||||||
if (event->events & EPOLLHUP) {
|
/* do not handle hup event if have in/out event */
|
||||||
fprintf(stdout, "%s event EPOLLHUP, de %p, fd %d, %p\n",
|
if ((event->events & EPOLLIN) && he->ops->read) {
|
||||||
__func__, de, de->fd, de->ops);
|
fprintf(stdout, "%s event EPOLLIN, he %p, fd %d, %p\n",
|
||||||
if (de->ops->hup)
|
__func__, he, he->fd, he->ops);
|
||||||
de->ops->hup(de, efd);
|
return he->ops->read(he, efd);
|
||||||
return 0;
|
}
|
||||||
} else if (event->events & EPOLLIN) {
|
if ((event->events & EPOLLOUT) && he->ops->write) {
|
||||||
return de->ops->read(de);
|
fprintf(stdout, "%s event EPOLLOUT, he %p, fd %d, %p\n",
|
||||||
} else if (event->events & EPOLLERR) {
|
__func__, he, he->fd, he->ops);
|
||||||
fprintf(stderr, "get epoll err of not epool in event\n");
|
return he->ops->write(he, efd);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stdout, "%s get unknown event %d\n", __func__, event->events);
|
if ((event->events & EPOLLHUP) || (event->events & EPOLLERR)) {
|
||||||
return -1;
|
fprintf(stdout, "%s event EPOLLHUP or EPOLLERR, he %p, fd %d, %x\n",
|
||||||
|
__func__, he, he->fd, event->events);
|
||||||
|
if (he->ops->hup)
|
||||||
|
he->ops->hup(he, efd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-7
@@ -7,10 +7,11 @@
|
|||||||
struct hyper_event;
|
struct hyper_event;
|
||||||
|
|
||||||
struct hyper_event_ops {
|
struct hyper_event_ops {
|
||||||
int (*read)(struct hyper_event *e);
|
int (*read)(struct hyper_event *e, int efd);
|
||||||
int (*getlen)(struct hyper_event *e, uint32_t *len);
|
int (*write)(struct hyper_event *e, int efd);
|
||||||
int (*handle)(struct hyper_event *e, uint32_t len);
|
|
||||||
void (*hup)(struct hyper_event *e, int efd);
|
void (*hup)(struct hyper_event *e, int efd);
|
||||||
|
int rbuf_size;
|
||||||
|
int wbuf_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hyper_buf {
|
struct hyper_buf {
|
||||||
@@ -21,16 +22,23 @@ struct hyper_buf {
|
|||||||
|
|
||||||
struct hyper_event {
|
struct hyper_event {
|
||||||
int fd;
|
int fd;
|
||||||
int to;
|
int flag;
|
||||||
struct hyper_buf buf;
|
struct hyper_buf rbuf;
|
||||||
|
struct hyper_buf wbuf;
|
||||||
struct hyper_event_ops *ops;
|
struct hyper_event_ops *ops;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
int hyper_add_event(int efd, struct hyper_event *de);
|
#define FULL(buf) \
|
||||||
|
(buf->size - buf->get <= 12)
|
||||||
|
|
||||||
|
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_requeue_event(int efd, struct hyper_event *ev);
|
||||||
int hyper_init_event(struct hyper_event *de, struct hyper_event_ops *ops,
|
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);
|
int hyper_handle_event(int efd, struct epoll_event *event);
|
||||||
void hyper_reset_event(struct hyper_event *de);
|
void hyper_reset_event(struct hyper_event *de);
|
||||||
void hyper_event_hup(struct hyper_event *de, int efd);
|
void hyper_event_hup(struct hyper_event *de, int efd);
|
||||||
|
int hyper_event_write(struct hyper_event *de, int efd);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+658
-375
File diff suppressed because it is too large
Load Diff
+31
-15
@@ -4,33 +4,49 @@
|
|||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
|
||||||
|
struct env {
|
||||||
|
char *env;
|
||||||
|
char *value;
|
||||||
|
};
|
||||||
|
|
||||||
struct hyper_exec {
|
struct hyper_exec {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
struct hyper_event e;
|
struct hyper_pod *pod;
|
||||||
char *id;
|
|
||||||
char *pty;
|
struct hyper_event stdinev;
|
||||||
char **argv;
|
struct hyper_event stdoutev;
|
||||||
int argc;
|
struct hyper_event stderrev;
|
||||||
uint64_t seq;
|
|
||||||
int pid;
|
int pid;
|
||||||
int ptyno;
|
int ptyno;
|
||||||
int init;
|
int init;
|
||||||
|
int ptyfd;
|
||||||
|
uint8_t close_stdin_request;
|
||||||
uint8_t code;
|
uint8_t code;
|
||||||
|
uint8_t exit;
|
||||||
|
uint8_t ref;
|
||||||
|
|
||||||
|
// configs
|
||||||
|
char *container_id;
|
||||||
|
char *user;
|
||||||
|
char *group;
|
||||||
|
char **additional_groups;
|
||||||
|
int nr_additional_groups;
|
||||||
|
struct env *envs;
|
||||||
|
int envs_num;
|
||||||
|
char **argv;
|
||||||
|
int argc;
|
||||||
|
int tty; // use tty or not
|
||||||
|
uint64_t seq;
|
||||||
|
uint64_t errseq;
|
||||||
|
char *workdir;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hyper_pod;
|
struct hyper_pod;
|
||||||
|
|
||||||
int hyper_exec_cmd(char *json, int length);
|
int hyper_exec_cmd(char *json, int length);
|
||||||
int hyper_release_exec(struct hyper_exec *, struct hyper_pod *);
|
int hyper_run_process(struct hyper_exec *e);
|
||||||
int hyper_container_execcmd(struct hyper_pod *pod);
|
|
||||||
int hyper_setup_exec_tty(struct hyper_exec *e);
|
|
||||||
int hyper_dup_exec_tty(int fd, struct hyper_exec *e);
|
|
||||||
struct hyper_exec *hyper_find_exec_by_pid(struct list_head *head, int pid);
|
struct hyper_exec *hyper_find_exec_by_pid(struct list_head *head, int pid);
|
||||||
struct hyper_exec *hyper_find_exec_by_seq(struct hyper_pod *pod, uint64_t seq);
|
struct hyper_exec *hyper_find_exec_by_seq(struct hyper_pod *pod, uint64_t seq);
|
||||||
int hyper_send_exec_eof(int to, struct hyper_pod *pod,
|
int hyper_handle_exec_exit(struct hyper_pod *pod, int pid, uint8_t code);
|
||||||
struct list_head *head, int pid,
|
|
||||||
uint8_t code);
|
|
||||||
void hyper_cleanup_exec(struct hyper_pod *pod);
|
|
||||||
|
|
||||||
extern struct hyper_event_ops pts_ops;
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+58
-46
@@ -1,80 +1,92 @@
|
|||||||
#ifndef _DVM_H_
|
#ifndef _HYPER_H_
|
||||||
#define _DVM_H_
|
#define _HYPER_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "api.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "exec.h"
|
#include "exec.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "container.h"
|
#include "container.h"
|
||||||
|
#include "portmapping.h"
|
||||||
|
|
||||||
enum {
|
/* Path to rootfs shared directory */
|
||||||
SETDVM,
|
#define SHARED_DIR "/tmp/hyper/shared"
|
||||||
STARTPOD,
|
|
||||||
GETPOD,
|
|
||||||
STOPPOD,
|
|
||||||
DESTROYPOD,
|
|
||||||
RESTARTCONTAINER,
|
|
||||||
EXECCMD,
|
|
||||||
FINISHCMD,
|
|
||||||
READY,
|
|
||||||
ACK,
|
|
||||||
ERROR,
|
|
||||||
WINSIZE,
|
|
||||||
PING,
|
|
||||||
FINISH,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
POLICY_NEVER,
|
|
||||||
POLICY_ALWAYS,
|
|
||||||
POLICY_ONFAILURE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hyper_pod {
|
struct hyper_pod {
|
||||||
struct hyper_container *c;
|
|
||||||
struct hyper_interface *iface;
|
struct hyper_interface *iface;
|
||||||
struct hyper_route *rt;
|
struct hyper_route *rt;
|
||||||
struct list_head pe_head;
|
struct portmapping_white_list *portmap_white_lists;
|
||||||
struct list_head ce_head;
|
char **dns;
|
||||||
|
struct list_head containers;
|
||||||
|
struct list_head exec_head;
|
||||||
char *hostname;
|
char *hostname;
|
||||||
char *tag;
|
char *share_tag;
|
||||||
char *channel;
|
|
||||||
int init_pid;
|
int init_pid;
|
||||||
uint32_t c_num;
|
|
||||||
uint32_t i_num;
|
uint32_t i_num;
|
||||||
uint32_t r_num;
|
uint32_t r_num;
|
||||||
uint32_t e_num;
|
uint32_t d_num;
|
||||||
uint32_t type;
|
/* how many containers are running */
|
||||||
uint32_t code;
|
|
||||||
uint32_t remains;
|
uint32_t remains;
|
||||||
uint8_t policy;
|
int req_destroy;
|
||||||
int efd;
|
int efd;
|
||||||
struct hyper_event sig;
|
};
|
||||||
struct hyper_event ctl;
|
|
||||||
|
struct portmapping_white_list {
|
||||||
|
char **internal_networks;
|
||||||
|
char **external_networks;
|
||||||
|
uint32_t i_num;
|
||||||
|
uint32_t e_num;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hyper_win_size {
|
struct hyper_win_size {
|
||||||
char *tty;
|
|
||||||
int row;
|
int row;
|
||||||
int column;
|
int column;
|
||||||
uint64_t seq;
|
uint64_t seq;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hyper_ctl {
|
struct file_command {
|
||||||
int efd;
|
char *id;
|
||||||
struct hyper_event sig;
|
char *file;
|
||||||
struct hyper_event tty;
|
|
||||||
struct hyper_event chan;
|
|
||||||
struct hyper_event ctl;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int hyper_mkdir(char *hyper_path);
|
struct hyper_ctl {
|
||||||
|
int efd;
|
||||||
|
struct hyper_event tty;
|
||||||
|
struct hyper_event chan;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int hyper_symlink(char *oldpath, char *newpath)
|
||||||
|
{
|
||||||
|
return symlink(oldpath, newpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int hyper_unlink(char *hyper_path)
|
||||||
|
{
|
||||||
|
return unlink(hyper_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int hyper_create(char *hyper_path)
|
||||||
|
{
|
||||||
|
int fd = creat(hyper_path, 0755);
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int hyper_open_serial(char *tty);
|
int hyper_open_serial(char *tty);
|
||||||
struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id);
|
void hyper_cleanup_pod(struct hyper_pod *pod);
|
||||||
|
int hyper_enter_sandbox(struct hyper_pod *pod, int pidpipe);
|
||||||
|
void hyper_pod_destroyed(int failed);
|
||||||
|
|
||||||
extern struct hyper_pod global_pod;
|
extern struct hyper_pod global_pod;
|
||||||
extern struct hyper_ctl ctl;
|
extern struct hyper_ctl ctl;
|
||||||
extern struct hyper_exec *global_exec;
|
extern sigset_t orig_mask;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+877
-561
File diff suppressed because it is too large
Load Diff
+10
-3
@@ -164,14 +164,18 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
|
|||||||
int i;
|
int i;
|
||||||
jsmntok_t *token;
|
jsmntok_t *token;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
int num = 0;
|
||||||
|
int out = 0;
|
||||||
|
|
||||||
for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
|
for (; parser->pos < len && js[parser->pos] != '\0' && !out; parser->pos++) {
|
||||||
char c;
|
char c;
|
||||||
jsmntype_t type;
|
jsmntype_t type;
|
||||||
|
|
||||||
c = js[parser->pos];
|
c = js[parser->pos];
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '{': case '[':
|
case '{':
|
||||||
|
num++;
|
||||||
|
case '[':
|
||||||
count++;
|
count++;
|
||||||
if (tokens == NULL)
|
if (tokens == NULL)
|
||||||
break;
|
break;
|
||||||
@@ -189,7 +193,10 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
|
|||||||
token->start = parser->pos;
|
token->start = parser->pos;
|
||||||
parser->toksuper = parser->toknext - 1;
|
parser->toksuper = parser->toknext - 1;
|
||||||
break;
|
break;
|
||||||
case '}': case ']':
|
case '}':
|
||||||
|
if (--num <= 0)
|
||||||
|
out = 1;
|
||||||
|
case ']':
|
||||||
if (tokens == NULL)
|
if (tokens == NULL)
|
||||||
break;
|
break;
|
||||||
type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
|
type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
|
||||||
|
|||||||
@@ -7,8 +7,12 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
#include "hyper.h"
|
#include "hyper.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "parse.h"
|
||||||
|
#include "../config.h"
|
||||||
|
|
||||||
void hyper_set_be32(uint8_t *buf, uint32_t val)
|
void hyper_set_be32(uint8_t *buf, uint32_t val)
|
||||||
{
|
{
|
||||||
@@ -44,7 +48,6 @@ int hyper_send_data(int fd, uint8_t *data, uint32_t len)
|
|||||||
|
|
||||||
while (length < len) {
|
while (length < len) {
|
||||||
size = write(fd, data + length, len - length);
|
size = write(fd, data + length, len - length);
|
||||||
|
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
@@ -55,7 +58,9 @@ int hyper_send_data(int fd, uint8_t *data, uint32_t len)
|
|||||||
perror("send hyper data failed");
|
perror("send hyper data failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#if WITH_VBOX
|
||||||
|
tcdrain(fd);
|
||||||
|
#endif
|
||||||
length += size;
|
length += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,14 +91,13 @@ int hyper_send_type(int fd, uint32_t type)
|
|||||||
return hyper_send_msg(fd, type, 0, NULL);
|
return hyper_send_msg(fd, type, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hyper_get_type_block(int fd, uint32_t *type)
|
int hyper_get_type(int fd, uint32_t *type)
|
||||||
{
|
{
|
||||||
int len = 0, size;
|
int len = 0, size;
|
||||||
uint8_t buf[8];
|
uint8_t buf[8];
|
||||||
|
|
||||||
while (len < 8) {
|
while (len < 8) {
|
||||||
size = read(fd, buf + len, 8 - len);
|
size = read(fd, buf + len, 8 - len);
|
||||||
|
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
@@ -107,42 +111,20 @@ int hyper_get_type_block(int fd, uint32_t *type)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hyper_send_type_block(int fd, uint32_t type, int need_ack)
|
int hyper_send_msg_block(int fd, uint32_t type, uint32_t len, uint8_t *data)
|
||||||
{
|
{
|
||||||
int ret = 0, flags;
|
int ret, flags;
|
||||||
uint32_t t;
|
|
||||||
|
|
||||||
flags = fcntl(fd, F_GETFL, 0);
|
flags = hyper_setfd_block(fd);
|
||||||
if (flags < 0) {
|
if (flags < 0) {
|
||||||
fprintf(stderr, "get fd flag failed\n");
|
fprintf(stderr, "%s fail to set fd block\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) < 0) {
|
ret = hyper_send_msg(fd, type, len, data);
|
||||||
perror("set fd BLOCK failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = hyper_send_msg(fd, type, 0, NULL);
|
if (fcntl(fd, F_SETFL, flags) < 0) {
|
||||||
if (ret < 0)
|
perror("restore fd flag failed");
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (need_ack == 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = hyper_get_type_block(fd, &t);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "can not get type\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stdout, "get type %" PRIu32"\n", type);
|
|
||||||
|
|
||||||
if (t != ACK)
|
|
||||||
ret = -1;
|
|
||||||
out:
|
|
||||||
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
|
||||||
perror("set fd BLOCK failed");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +177,7 @@ static int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int a
|
|||||||
static int hyper_get_ifindex(char *nic)
|
static int hyper_get_ifindex(char *nic)
|
||||||
{
|
{
|
||||||
int fd, ifindex = -1;
|
int fd, ifindex = -1;
|
||||||
char path[512], buf[4];
|
char path[512], buf[8];
|
||||||
|
|
||||||
fprintf(stdout, "net device %s\n", nic);
|
fprintf(stdout, "net device %s\n", nic);
|
||||||
sprintf(path, "/sys/class/net/%s/ifindex", nic);
|
sprintf(path, "/sys/class/net/%s/ifindex", nic);
|
||||||
@@ -208,7 +190,7 @@ static int hyper_get_ifindex(char *nic)
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
if (read(fd, buf, sizeof(buf)) <= 0) {
|
if (read(fd, buf, sizeof(buf) - 1) <= 0) {
|
||||||
perror("can read open file");
|
perror("can read open file");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -303,14 +285,17 @@ static int hyper_remove_nic(char *device)
|
|||||||
{
|
{
|
||||||
char path[256], real[128];
|
char path[256], real[128];
|
||||||
int fd;
|
int fd;
|
||||||
|
ssize_t size;
|
||||||
|
|
||||||
sprintf(path, "/sys/class/net/%s", device);
|
sprintf(path, "/sys/class/net/%s", device);
|
||||||
|
|
||||||
if (readlink(path, real, 128) < 0) {
|
size = readlink(path, real, 128);
|
||||||
|
if (size < 0 || size > 127) {
|
||||||
perror("fail to read link directory");
|
perror("fail to read link directory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
real[size] = '\0';
|
||||||
sprintf(path, "/sys/%s/../../../remove", real + 5);
|
sprintf(path, "/sys/%s/../../../remove", real + 5);
|
||||||
|
|
||||||
fprintf(stdout, "get net sys path %s\n", path);
|
fprintf(stdout, "get net sys path %s\n", path);
|
||||||
@@ -443,8 +428,13 @@ static int hyper_setup_route(struct rtnl_handle *rth,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rt->device) {
|
if (rt->device) {
|
||||||
rt->ifindex = hyper_get_ifindex(rt->device);
|
int ifindex = hyper_get_ifindex(rt->device);
|
||||||
if (addattr_l(&req.n, sizeof(req), RTA_OIF, &rt->ifindex, 4)) {
|
if (ifindex < 0) {
|
||||||
|
fprintf(stderr, "failed to get the ifindix of %s\n", rt->device);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addattr_l(&req.n, sizeof(req), RTA_OIF, &ifindex, 4)) {
|
||||||
fprintf(stderr, "setup oif attr failed\n");
|
fprintf(stderr, "setup oif attr failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -526,7 +516,13 @@ static int hyper_cleanup_route(struct rtnl_handle *rth, struct hyper_route *rt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rt->device) {
|
if (rt->device) {
|
||||||
if (addattr_l(&req.n, sizeof(req), RTA_OIF, &rt->ifindex, 4)) {
|
int ifindex = hyper_get_ifindex(rt->device);
|
||||||
|
if (ifindex < 0) {
|
||||||
|
fprintf(stderr, "failed to get the ifindix of %s\n", rt->device);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addattr_l(&req.n, sizeof(req), RTA_OIF, &ifindex, 4)) {
|
||||||
fprintf(stderr, "setup oif attr failed\n");
|
fprintf(stderr, "setup oif attr failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -569,6 +565,44 @@ static int hyper_cleanup_route(struct rtnl_handle *rth, struct hyper_route *rt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hyper_set_interface_name(struct rtnl_handle *rth,
|
||||||
|
int ifindex,
|
||||||
|
char *new_device_name)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
struct nlmsghdr n;
|
||||||
|
struct ifinfomsg i;
|
||||||
|
char buf[1024];
|
||||||
|
} req;
|
||||||
|
|
||||||
|
if (ifindex < 0 || !new_device_name) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||||||
|
req.n.nlmsg_flags = NLM_F_REQUEST;
|
||||||
|
req.n.nlmsg_type = RTM_SETLINK;
|
||||||
|
|
||||||
|
req.i.ifi_family = AF_UNSPEC;
|
||||||
|
req.i.ifi_change = 0xFFFFFFFF;
|
||||||
|
req.i.ifi_index = ifindex;
|
||||||
|
|
||||||
|
if (addattr_l(&req.n, sizeof(req), IFLA_IFNAME,
|
||||||
|
new_device_name,
|
||||||
|
strlen(new_device_name) + 1)) {
|
||||||
|
fprintf(stderr, "setup attr failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtnl_talk(rth, &req.n, 0, 0, NULL) < 0) {
|
||||||
|
perror("rtnl_talk failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int hyper_setup_interface(struct rtnl_handle *rth,
|
static int hyper_setup_interface(struct rtnl_handle *rth,
|
||||||
struct hyper_interface *iface)
|
struct hyper_interface *iface)
|
||||||
{
|
{
|
||||||
@@ -579,6 +613,7 @@ static int hyper_setup_interface(struct rtnl_handle *rth,
|
|||||||
struct ifaddrmsg ifa;
|
struct ifaddrmsg ifa;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
} req;
|
} req;
|
||||||
|
int ifindex;
|
||||||
|
|
||||||
if (!(iface->device && iface->ipaddr && iface->mask)) {
|
if (!(iface->device && iface->ipaddr && iface->mask)) {
|
||||||
fprintf(stderr, "interface information incorrect\n");
|
fprintf(stderr, "interface information incorrect\n");
|
||||||
@@ -591,8 +626,13 @@ static int hyper_setup_interface(struct rtnl_handle *rth,
|
|||||||
req.n.nlmsg_type = RTM_NEWADDR;
|
req.n.nlmsg_type = RTM_NEWADDR;
|
||||||
req.ifa.ifa_family = AF_INET;
|
req.ifa.ifa_family = AF_INET;
|
||||||
|
|
||||||
iface->ifindex = hyper_get_ifindex(iface->device);
|
ifindex = hyper_get_ifindex(iface->device);
|
||||||
req.ifa.ifa_index = iface->ifindex;
|
if (ifindex < 0) {
|
||||||
|
fprintf(stderr, "failed to get the ifindix of %s\n", iface->device);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
req.ifa.ifa_index = ifindex;
|
||||||
req.ifa.ifa_scope = 0;
|
req.ifa.ifa_scope = 0;
|
||||||
|
|
||||||
if (get_addr_ipv4((uint8_t *)&data, iface->ipaddr) <= 0) {
|
if (get_addr_ipv4((uint8_t *)&data, iface->ipaddr) <= 0) {
|
||||||
@@ -617,8 +657,13 @@ static int hyper_setup_interface(struct rtnl_handle *rth,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hyper_up_nic(rth, iface->ifindex) < 0) {
|
if (iface->new_device_name && strcmp(iface->new_device_name, iface->device)) {
|
||||||
fprintf(stderr, "up device %d failed\n", iface->ifindex);
|
fprintf(stdout, "Setting interface name to %s\n", iface->new_device_name);
|
||||||
|
hyper_set_interface_name(rth, ifindex, iface->new_device_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hyper_up_nic(rth, ifindex) < 0) {
|
||||||
|
fprintf(stderr, "up device %d failed\n", ifindex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,6 +680,7 @@ static int hyper_cleanup_interface(struct rtnl_handle *rth,
|
|||||||
struct ifaddrmsg ifa;
|
struct ifaddrmsg ifa;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
} req;
|
} req;
|
||||||
|
int ifindex;
|
||||||
|
|
||||||
if (!(iface->device && iface->ipaddr && iface->mask)) {
|
if (!(iface->device && iface->ipaddr && iface->mask)) {
|
||||||
fprintf(stderr, "interface information incorrect\n");
|
fprintf(stderr, "interface information incorrect\n");
|
||||||
@@ -647,7 +693,13 @@ static int hyper_cleanup_interface(struct rtnl_handle *rth,
|
|||||||
req.n.nlmsg_type = RTM_DELADDR;
|
req.n.nlmsg_type = RTM_DELADDR;
|
||||||
req.ifa.ifa_family = AF_INET;
|
req.ifa.ifa_family = AF_INET;
|
||||||
|
|
||||||
req.ifa.ifa_index = iface->ifindex;
|
ifindex = hyper_get_ifindex(iface->device);
|
||||||
|
if (ifindex < 0) {
|
||||||
|
fprintf(stderr, "failed to get the ifindix of %s\n", iface->device);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
req.ifa.ifa_index = ifindex;
|
||||||
req.ifa.ifa_scope = 0;
|
req.ifa.ifa_scope = 0;
|
||||||
|
|
||||||
if (get_addr_ipv4((uint8_t *)&data, iface->ipaddr) <= 0) {
|
if (get_addr_ipv4((uint8_t *)&data, iface->ipaddr) <= 0) {
|
||||||
@@ -672,8 +724,13 @@ static int hyper_cleanup_interface(struct rtnl_handle *rth,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hyper_down_nic(rth, iface->ifindex) < 0) {
|
/* Don't down&remove lo device */
|
||||||
fprintf(stderr, "up device %d failed\n", iface->ifindex);
|
if (strcmp(iface->device, "lo") == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hyper_down_nic(rth, ifindex) < 0) {
|
||||||
|
fprintf(stderr, "up device %d failed\n", ifindex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,3 +848,130 @@ void hyper_cleanup_network(struct hyper_pod *pod)
|
|||||||
pod->i_num = 0;
|
pod->i_num = 0;
|
||||||
netlink_close(&rth);
|
netlink_close(&rth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hyper_cmd_setup_interface(char *json, int length)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
struct hyper_interface *iface;
|
||||||
|
struct rtnl_handle rth;
|
||||||
|
|
||||||
|
if (hyper_rescan() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (netlink_open(&rth) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
|
iface = hyper_parse_setup_interface(json, length);
|
||||||
|
if (iface == NULL) {
|
||||||
|
fprintf(stderr, "parse interface failed\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
ret = hyper_setup_interface(&rth, iface);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "link up device %s failed\n", iface->device);
|
||||||
|
goto out1;
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
out1:
|
||||||
|
free(iface->device);
|
||||||
|
free(iface->ipaddr);
|
||||||
|
free(iface->mask);
|
||||||
|
free(iface);
|
||||||
|
out:
|
||||||
|
netlink_close(&rth);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hyper_cmd_setup_route(char *json, int length) {
|
||||||
|
struct hyper_route *rts = NULL;
|
||||||
|
int i, ret = -1;
|
||||||
|
uint32_t r_num;
|
||||||
|
struct rtnl_handle rth;
|
||||||
|
|
||||||
|
if (netlink_open(&rth) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (hyper_parse_setup_routes(&rts, &r_num, json, length) < 0) {
|
||||||
|
fprintf(stderr, "parse route failed\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < r_num; i++) {
|
||||||
|
ret = hyper_setup_route(&rth, &rts[i]);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "setup route failed\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
out:
|
||||||
|
netlink_close(&rth);
|
||||||
|
free(rts);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hyper_setup_dns(struct hyper_pod *pod)
|
||||||
|
{
|
||||||
|
int i, fd, ret = -1;
|
||||||
|
char buf[28];
|
||||||
|
|
||||||
|
if (pod->dns == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fd = open("/tmp/hyper/resolv.conf", O_CREAT| O_TRUNC| O_WRONLY, 0644);
|
||||||
|
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("create /tmp/resolv.conf failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < pod->d_num; i++) {
|
||||||
|
int size = snprintf(buf, sizeof(buf), "nameserver %s\n", pod->dns[i]);
|
||||||
|
int len = 0, l;
|
||||||
|
|
||||||
|
if (size < 0) {
|
||||||
|
fprintf(stderr, "sprintf resolv.conf entry failed\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len < size) {
|
||||||
|
l = write(fd, buf + len, size - len);
|
||||||
|
if (l < 0) {
|
||||||
|
perror("fail to write resolv.conf");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
len += l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
out:
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hyper_cleanup_dns(struct hyper_pod *pod)
|
||||||
|
{
|
||||||
|
int fd, i;
|
||||||
|
|
||||||
|
if (pod->dns == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < pod->d_num; i++) {
|
||||||
|
free(pod->dns[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pod->dns);
|
||||||
|
pod->dns = NULL;
|
||||||
|
pod->d_num = 0;
|
||||||
|
|
||||||
|
fd = open("/tmp/hyper/resolv.conf", O_WRONLY| O_TRUNC);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("open /tmp/hyper/resolv.conf failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,26 +18,17 @@ struct rtnl_handle {
|
|||||||
__u32 dump;
|
__u32 dump;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
__u8 family;
|
|
||||||
__u8 bytelen;
|
|
||||||
__s16 bitlen;
|
|
||||||
__u32 flags;
|
|
||||||
__u32 data[8];
|
|
||||||
} inet_prefix;
|
|
||||||
|
|
||||||
struct hyper_interface {
|
struct hyper_interface {
|
||||||
char *device;
|
char *device;
|
||||||
int ifindex;
|
|
||||||
char *ipaddr;
|
char *ipaddr;
|
||||||
char *mask;
|
char *mask;
|
||||||
|
char *new_device_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hyper_route {
|
struct hyper_route {
|
||||||
char *dst;
|
char *dst;
|
||||||
char *gw;
|
char *gw;
|
||||||
char *device;
|
char *device;
|
||||||
int ifindex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hyper_pod;
|
struct hyper_pod;
|
||||||
@@ -47,11 +38,15 @@ uint32_t hyper_get_be32(uint8_t *buf);
|
|||||||
void hyper_set_be64(uint8_t *buf, uint64_t val);
|
void hyper_set_be64(uint8_t *buf, uint64_t val);
|
||||||
uint64_t hyper_get_be64(uint8_t *buf);
|
uint64_t hyper_get_be64(uint8_t *buf);
|
||||||
int hyper_setup_network(struct hyper_pod *pod);
|
int hyper_setup_network(struct hyper_pod *pod);
|
||||||
|
int hyper_cmd_setup_interface(char *json, int length);
|
||||||
|
int hyper_cmd_setup_route(char *json, int length);
|
||||||
void hyper_cleanup_network(struct hyper_pod *pod);
|
void hyper_cleanup_network(struct hyper_pod *pod);
|
||||||
int hyper_get_type_block(int fd, uint32_t *type);
|
int hyper_setup_dns(struct hyper_pod *pod);
|
||||||
|
void hyper_cleanup_dns(struct hyper_pod *pod);
|
||||||
|
int hyper_get_type(int fd, uint32_t *type);
|
||||||
int hyper_send_type(int fd, uint32_t type);
|
int hyper_send_type(int fd, uint32_t type);
|
||||||
int hyper_send_type_block(int fd, uint32_t type, int need_ack);
|
int hyper_send_type_block(int fd, uint32_t type, int need_ack);
|
||||||
int hyper_send_msg(int fd, uint32_t type, uint32_t len,
|
int hyper_send_msg(int fd, uint32_t type, uint32_t len, uint8_t *data);
|
||||||
uint8_t *message);
|
int hyper_send_msg_block(int fd, uint32_t type, uint32_t len, uint8_t *data);
|
||||||
int hyper_send_data(int fd, uint8_t *data, uint32_t len);
|
int hyper_send_data(int fd, uint8_t *data, uint32_t len);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+1017
-223
File diff suppressed because it is too large
Load Diff
+9
-2
@@ -1,13 +1,20 @@
|
|||||||
#ifndef _DVM_JSON_H_
|
#ifndef _PARSE_H_
|
||||||
#define _DVM_JSON_H_
|
#define _PARSE_H_
|
||||||
|
|
||||||
#include "hyper.h"
|
#include "hyper.h"
|
||||||
#include "jsmn.h"
|
#include "jsmn.h"
|
||||||
|
#include "parson.h"
|
||||||
|
|
||||||
int hyper_parse_pod(struct hyper_pod *pod, char *json, int length);
|
int hyper_parse_pod(struct hyper_pod *pod, char *json, int length);
|
||||||
struct hyper_exec *hyper_parse_execcmd(char *json, int length);
|
struct hyper_exec *hyper_parse_execcmd(char *json, int length);
|
||||||
char *json_token_str(char *js, jsmntok_t *t);
|
char *json_token_str(char *js, jsmntok_t *t);
|
||||||
int json_token_streq(char *js, jsmntok_t *t, char *s);
|
int json_token_streq(char *js, jsmntok_t *t, char *s);
|
||||||
int hyper_parse_winsize(struct hyper_win_size *ws, char *json, int length);
|
int hyper_parse_winsize(struct hyper_win_size *ws, char *json, int length);
|
||||||
|
int hyper_parse_file_command(struct file_command *cmd, char *json, int length);
|
||||||
|
struct hyper_container *hyper_parse_new_container(struct hyper_pod *pod, char *json, int length);
|
||||||
|
void hyper_free_container(struct hyper_container *c);
|
||||||
|
struct hyper_interface *hyper_parse_setup_interface(char *json, int length);
|
||||||
|
int hyper_parse_setup_routes(struct hyper_route **routes, uint32_t *r_num, char *json, int length);
|
||||||
|
JSON_Value *hyper_json_parse(char *json, int length);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+2070
File diff suppressed because it is too large
Load Diff
+223
@@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
Parson ( http://kgabis.github.com/parson/ )
|
||||||
|
Copyright (c) 2012 - 2016 Krzysztof Gabis
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef parson_parson_h
|
||||||
|
#define parson_parson_h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
|
/* Types and enums */
|
||||||
|
typedef struct json_object_t JSON_Object;
|
||||||
|
typedef struct json_array_t JSON_Array;
|
||||||
|
typedef struct json_value_t JSON_Value;
|
||||||
|
|
||||||
|
enum json_value_type {
|
||||||
|
JSONError = -1,
|
||||||
|
JSONNull = 1,
|
||||||
|
JSONString = 2,
|
||||||
|
JSONNumber = 3,
|
||||||
|
JSONObject = 4,
|
||||||
|
JSONArray = 5,
|
||||||
|
JSONBoolean = 6
|
||||||
|
};
|
||||||
|
typedef int JSON_Value_Type;
|
||||||
|
|
||||||
|
enum json_result_t {
|
||||||
|
JSONSuccess = 0,
|
||||||
|
JSONFailure = -1
|
||||||
|
};
|
||||||
|
typedef int JSON_Status;
|
||||||
|
|
||||||
|
typedef void * (*JSON_Malloc_Function)(size_t);
|
||||||
|
typedef void (*JSON_Free_Function)(void *);
|
||||||
|
|
||||||
|
/* Call only once, before calling any other function from parson API. If not called, malloc and free
|
||||||
|
from stdlib will be used for all allocations */
|
||||||
|
void json_set_allocation_functions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun);
|
||||||
|
|
||||||
|
/* Parses first JSON value in a file, returns NULL in case of error */
|
||||||
|
JSON_Value * json_parse_file(const char *filename);
|
||||||
|
|
||||||
|
/* Parses first JSON value in a file and ignores comments (/ * * / and //),
|
||||||
|
returns NULL in case of error */
|
||||||
|
JSON_Value * json_parse_file_with_comments(const char *filename);
|
||||||
|
|
||||||
|
/* Parses first JSON value in a string, returns NULL in case of error */
|
||||||
|
JSON_Value * json_parse_string(const char *string);
|
||||||
|
|
||||||
|
/* Parses first JSON value in a string and ignores comments (/ * * / and //),
|
||||||
|
returns NULL in case of error */
|
||||||
|
JSON_Value * json_parse_string_with_comments(const char *string);
|
||||||
|
|
||||||
|
/* Serialization */
|
||||||
|
size_t json_serialization_size(const JSON_Value *value); /* returns 0 on fail */
|
||||||
|
JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes);
|
||||||
|
JSON_Status json_serialize_to_file(const JSON_Value *value, const char *filename);
|
||||||
|
char * json_serialize_to_string(const JSON_Value *value);
|
||||||
|
|
||||||
|
/* Pretty serialization */
|
||||||
|
size_t json_serialization_size_pretty(const JSON_Value *value); /* returns 0 on fail */
|
||||||
|
JSON_Status json_serialize_to_buffer_pretty(const JSON_Value *value, char *buf, size_t buf_size_in_bytes);
|
||||||
|
JSON_Status json_serialize_to_file_pretty(const JSON_Value *value, const char *filename);
|
||||||
|
char * json_serialize_to_string_pretty(const JSON_Value *value);
|
||||||
|
|
||||||
|
void json_free_serialized_string(char *string); /* frees string from json_serialize_to_string and json_serialize_to_string_pretty */
|
||||||
|
|
||||||
|
/* Comparing */
|
||||||
|
int json_value_equals(const JSON_Value *a, const JSON_Value *b);
|
||||||
|
|
||||||
|
/* Validation
|
||||||
|
This is *NOT* JSON Schema. It validates json by checking if object have identically
|
||||||
|
named fields with matching types.
|
||||||
|
For example schema {"name":"", "age":0} will validate
|
||||||
|
{"name":"Joe", "age":25} and {"name":"Joe", "age":25, "gender":"m"},
|
||||||
|
but not {"name":"Joe"} or {"name":"Joe", "age":"Cucumber"}.
|
||||||
|
In case of arrays, only first value in schema is checked against all values in tested array.
|
||||||
|
Empty objects ({}) validate all objects, empty arrays ([]) validate all arrays,
|
||||||
|
null validates values of every type.
|
||||||
|
*/
|
||||||
|
JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* JSON Object
|
||||||
|
*/
|
||||||
|
JSON_Value * json_object_get_value (const JSON_Object *object, const char *name);
|
||||||
|
const char * json_object_get_string (const JSON_Object *object, const char *name);
|
||||||
|
JSON_Object * json_object_get_object (const JSON_Object *object, const char *name);
|
||||||
|
JSON_Array * json_object_get_array (const JSON_Object *object, const char *name);
|
||||||
|
double json_object_get_number (const JSON_Object *object, const char *name); /* returns 0 on fail */
|
||||||
|
int json_object_get_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
|
||||||
|
|
||||||
|
/* dotget functions enable addressing values with dot notation in nested objects,
|
||||||
|
just like in structs or c++/java/c# objects (e.g. objectA.objectB.value).
|
||||||
|
Because valid names in JSON can contain dots, some values may be inaccessible
|
||||||
|
this way. */
|
||||||
|
JSON_Value * json_object_dotget_value (const JSON_Object *object, const char *name);
|
||||||
|
const char * json_object_dotget_string (const JSON_Object *object, const char *name);
|
||||||
|
JSON_Object * json_object_dotget_object (const JSON_Object *object, const char *name);
|
||||||
|
JSON_Array * json_object_dotget_array (const JSON_Object *object, const char *name);
|
||||||
|
double json_object_dotget_number (const JSON_Object *object, const char *name); /* returns 0 on fail */
|
||||||
|
int json_object_dotget_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */
|
||||||
|
|
||||||
|
/* Functions to get available names */
|
||||||
|
size_t json_object_get_count (const JSON_Object *object);
|
||||||
|
const char * json_object_get_name (const JSON_Object *object, size_t index);
|
||||||
|
JSON_Value * json_object_get_value_at(const JSON_Object *object, size_t index);
|
||||||
|
|
||||||
|
/* Creates new name-value pair or frees and replaces old value with a new one.
|
||||||
|
* json_object_set_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||||
|
JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value);
|
||||||
|
JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string);
|
||||||
|
JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number);
|
||||||
|
JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean);
|
||||||
|
JSON_Status json_object_set_null(JSON_Object *object, const char *name);
|
||||||
|
|
||||||
|
/* Works like dotget functions, but creates whole hierarchy if necessary.
|
||||||
|
* json_object_dotset_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||||
|
JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value);
|
||||||
|
JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, const char *string);
|
||||||
|
JSON_Status json_object_dotset_number(JSON_Object *object, const char *name, double number);
|
||||||
|
JSON_Status json_object_dotset_boolean(JSON_Object *object, const char *name, int boolean);
|
||||||
|
JSON_Status json_object_dotset_null(JSON_Object *object, const char *name);
|
||||||
|
|
||||||
|
/* Frees and removes name-value pair */
|
||||||
|
JSON_Status json_object_remove(JSON_Object *object, const char *name);
|
||||||
|
|
||||||
|
/* Works like dotget function, but removes name-value pair only on exact match. */
|
||||||
|
JSON_Status json_object_dotremove(JSON_Object *object, const char *key);
|
||||||
|
|
||||||
|
/* Removes all name-value pairs in object */
|
||||||
|
JSON_Status json_object_clear(JSON_Object *object);
|
||||||
|
|
||||||
|
/*
|
||||||
|
*JSON Array
|
||||||
|
*/
|
||||||
|
JSON_Value * json_array_get_value (const JSON_Array *array, size_t index);
|
||||||
|
const char * json_array_get_string (const JSON_Array *array, size_t index);
|
||||||
|
JSON_Object * json_array_get_object (const JSON_Array *array, size_t index);
|
||||||
|
JSON_Array * json_array_get_array (const JSON_Array *array, size_t index);
|
||||||
|
double json_array_get_number (const JSON_Array *array, size_t index); /* returns 0 on fail */
|
||||||
|
int json_array_get_boolean(const JSON_Array *array, size_t index); /* returns -1 on fail */
|
||||||
|
size_t json_array_get_count (const JSON_Array *array);
|
||||||
|
|
||||||
|
/* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist.
|
||||||
|
* Order of values in array may change during execution. */
|
||||||
|
JSON_Status json_array_remove(JSON_Array *array, size_t i);
|
||||||
|
|
||||||
|
/* Frees and removes from array value at given index and replaces it with given one.
|
||||||
|
* Does nothing and returns JSONFailure if index doesn't exist.
|
||||||
|
* json_array_replace_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||||
|
JSON_Status json_array_replace_value(JSON_Array *array, size_t i, JSON_Value *value);
|
||||||
|
JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char* string);
|
||||||
|
JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number);
|
||||||
|
JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean);
|
||||||
|
JSON_Status json_array_replace_null(JSON_Array *array, size_t i);
|
||||||
|
|
||||||
|
/* Frees and removes all values from array */
|
||||||
|
JSON_Status json_array_clear(JSON_Array *array);
|
||||||
|
|
||||||
|
/* Appends new value at the end of array.
|
||||||
|
* json_array_append_value does not copy passed value so it shouldn't be freed afterwards. */
|
||||||
|
JSON_Status json_array_append_value(JSON_Array *array, JSON_Value *value);
|
||||||
|
JSON_Status json_array_append_string(JSON_Array *array, const char *string);
|
||||||
|
JSON_Status json_array_append_number(JSON_Array *array, double number);
|
||||||
|
JSON_Status json_array_append_boolean(JSON_Array *array, int boolean);
|
||||||
|
JSON_Status json_array_append_null(JSON_Array *array);
|
||||||
|
|
||||||
|
/*
|
||||||
|
*JSON Value
|
||||||
|
*/
|
||||||
|
JSON_Value * json_value_init_object (void);
|
||||||
|
JSON_Value * json_value_init_array (void);
|
||||||
|
JSON_Value * json_value_init_string (const char *string); /* copies passed string */
|
||||||
|
JSON_Value * json_value_init_number (double number);
|
||||||
|
JSON_Value * json_value_init_boolean(int boolean);
|
||||||
|
JSON_Value * json_value_init_null (void);
|
||||||
|
JSON_Value * json_value_deep_copy (const JSON_Value *value);
|
||||||
|
void json_value_free (JSON_Value *value);
|
||||||
|
|
||||||
|
JSON_Value_Type json_value_get_type (const JSON_Value *value);
|
||||||
|
JSON_Object * json_value_get_object (const JSON_Value *value);
|
||||||
|
JSON_Array * json_value_get_array (const JSON_Value *value);
|
||||||
|
const char * json_value_get_string (const JSON_Value *value);
|
||||||
|
double json_value_get_number (const JSON_Value *value);
|
||||||
|
int json_value_get_boolean(const JSON_Value *value);
|
||||||
|
|
||||||
|
/* Same as above, but shorter */
|
||||||
|
JSON_Value_Type json_type (const JSON_Value *value);
|
||||||
|
JSON_Object * json_object (const JSON_Value *value);
|
||||||
|
JSON_Array * json_array (const JSON_Value *value);
|
||||||
|
const char * json_string (const JSON_Value *value);
|
||||||
|
double json_number (const JSON_Value *value);
|
||||||
|
int json_boolean(const JSON_Value *value);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,417 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "hyper.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "../config.h"
|
||||||
|
|
||||||
|
int hyper_init_modules()
|
||||||
|
{
|
||||||
|
int status = hyper_cmd("depmod");
|
||||||
|
if (status != 0) {
|
||||||
|
fprintf(stderr, "depmod failed, status: %d\n", status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hyper_setup_iptables_rule(struct ipt_rule rule)
|
||||||
|
{
|
||||||
|
char check_cmd[512] = {0};
|
||||||
|
char cmd[512] = {0};
|
||||||
|
int check = -1;
|
||||||
|
|
||||||
|
if (rule.rule != NULL) {
|
||||||
|
sprintf(check_cmd, "iptables -t %s -C %s %s", rule.table, rule.chain, rule.rule);
|
||||||
|
sprintf(cmd, "iptables -t %s %s %s %s", rule.table, rule.op, rule.chain, rule.rule);
|
||||||
|
} else {
|
||||||
|
sprintf(cmd, "iptables -t %s %s %s", rule.table, rule.op, rule.chain);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(check_cmd) > 0) {
|
||||||
|
check = hyper_cmd(check_cmd);
|
||||||
|
fprintf(stdout, "check iptables '%s', ret: %d\n", check_cmd, check);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check == 0) {
|
||||||
|
// iptables rule already exist, do not insert it again
|
||||||
|
if (!strncmp(rule.op, "-A", strlen("-A")) ||
|
||||||
|
!strncmp(rule.op, "-I", strlen("-I")) ||
|
||||||
|
!strncmp(rule.op, "-N", strlen("-N"))) {
|
||||||
|
fprintf(stdout, "iptables rule '%s' already exist\n", rule.rule);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int status = hyper_cmd(cmd);
|
||||||
|
fprintf(stdout, "insert iptables '%s', ret: %d\n", cmd, status);
|
||||||
|
if (status != 0) {
|
||||||
|
fprintf(stderr, "insert iptables rule failed, ret: %d\n", status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize modules and iptables chains
|
||||||
|
int hyper_setup_portmapping(struct hyper_pod *pod)
|
||||||
|
{
|
||||||
|
const char *connmax = "10485760";
|
||||||
|
const char *timeout = "300";
|
||||||
|
|
||||||
|
if (pod->portmap_white_lists == NULL || (pod->portmap_white_lists->i_num == 0 &&
|
||||||
|
pod->portmap_white_lists->e_num == 0)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hyper_init_modules() < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iptables -t filter -N hyperstart-INPUT
|
||||||
|
// iptables -t nat -N hyperstart-PREROUTING
|
||||||
|
// iptables -t filter -I INPUT -j hyperstart-INPUT
|
||||||
|
// iptables -t nat -I PREROUTING -j hyperstart-PREROUTING
|
||||||
|
// iptables -t filter -A hyperstart-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
// iptables -t filter -A hyperstart-INPUT -p icmp -j ACCEPT
|
||||||
|
// iptables -t filter -A hyperstart-INPUT -i lo -j ACCEPT
|
||||||
|
// iptables -t filter -A hyperstart-INPUT -j DROP
|
||||||
|
// iptables -t nat -A hyperstart-PREROUTING -j RETURN
|
||||||
|
const struct ipt_rule rules[] = {
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-N",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "nat",
|
||||||
|
.op = "-N",
|
||||||
|
.chain = "hyperstart-PREROUTING",
|
||||||
|
.rule = NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-I",
|
||||||
|
.chain = "INPUT",
|
||||||
|
.rule = "-j hyperstart-INPUT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "nat",
|
||||||
|
.op = "-I",
|
||||||
|
.chain = "PREROUTING",
|
||||||
|
.rule = "-j hyperstart-PREROUTING",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-A",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = "-m state --state RELATED,ESTABLISHED -j ACCEPT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-A",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = "-p icmp -j ACCEPT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-A",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = "-i lo -j ACCEPT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-A",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = "-j DROP",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "nat",
|
||||||
|
.op = "-A",
|
||||||
|
.chain = "hyperstart-PREROUTING",
|
||||||
|
.rule = "-j RETURN",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for(i=0; i< sizeof(rules)/sizeof(struct ipt_rule); i++) {
|
||||||
|
if (hyper_setup_iptables_rule(rules[i])<0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* portmapping enables nf_conntrack by default, should blow up nf_conntack_max to make sure
|
||||||
|
* nf_conntrack is available for connections. */
|
||||||
|
if (hyper_write_file("/proc/sys/net/nf_conntrack_max", connmax, strlen(connmax)) < 0) {
|
||||||
|
fprintf(stderr, "sysctl: setup default nf_conntrack_max(%s) failed\n", connmax);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hyper_write_file("/proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established", timeout, strlen(timeout)) < 0) {
|
||||||
|
fprintf(stderr, "sysctl: setup default nf_conntrack_tcp_timeout_established(%s) failed\n", timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hyper_cleanup_portmapping(struct hyper_pod *pod)
|
||||||
|
{
|
||||||
|
if (pod->portmap_white_lists == NULL || (pod->portmap_white_lists->i_num == 0 &&
|
||||||
|
pod->portmap_white_lists->e_num == 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iptables -t filter -D hyperstart-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
// iptables -t filter -D hyperstart-INPUT -p icmp -j ACCEPT
|
||||||
|
// iptables -t filter -D hyperstart-INPUT -i lo -j ACCEPT
|
||||||
|
// iptables -t filter -D hyperstart-INPUT -j DROP
|
||||||
|
// iptables -t filter -D INPUT -j hyperstart-DNPUT
|
||||||
|
// iptables -t nat -D hyperstart-PREROUTING -j RETURN
|
||||||
|
// iptables -t nat -D PREROUTING -j hyperstart-PREROUTING
|
||||||
|
// iptables -t filter -F hyperstart-INPUT
|
||||||
|
// iptables -t nat -F hyperstart-PREROUTING
|
||||||
|
// iptables -t filter -X hyperstart-INPUT
|
||||||
|
// iptables -t nat -X hyperstart-PREROUTING
|
||||||
|
const struct ipt_rule rules[] = {
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-D",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = "-m state --state RELATED,ESTABLISHED -j ACCEPT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-D",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = "-p icmp -j ACCEPT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-D",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = "-i lo -j ACCEPT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-D",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = "-j DROP",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "nat",
|
||||||
|
.op = "-D",
|
||||||
|
.chain = "hyperstart-PREROUTING",
|
||||||
|
.rule = "-j RETURN",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "nat",
|
||||||
|
.op = "-D",
|
||||||
|
.chain = "PREROUTING",
|
||||||
|
.rule = "-j hyperstart-PREROUTING",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-D",
|
||||||
|
.chain = "INPUT",
|
||||||
|
.rule = "-j hyperstart-INPUT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "nat",
|
||||||
|
.op = "-F",
|
||||||
|
.chain = "hyperstart-PREROUTING",
|
||||||
|
.rule = NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "nat",
|
||||||
|
.op = "-X",
|
||||||
|
.chain = "hyperstart-PREROUTING",
|
||||||
|
.rule = NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-F",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-X",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = NULL,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for(i=0; i< sizeof(rules)/sizeof(struct ipt_rule); i++) {
|
||||||
|
if (hyper_setup_iptables_rule(rules[i])<0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pod->portmap_white_lists->internal_networks);
|
||||||
|
free(pod->portmap_white_lists->external_networks);
|
||||||
|
free(pod->portmap_white_lists);
|
||||||
|
pod->portmap_white_lists = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hyper_setup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod)
|
||||||
|
{
|
||||||
|
if (pod->portmap_white_lists == NULL || (pod->portmap_white_lists->i_num == 0 &&
|
||||||
|
pod->portmap_white_lists->e_num == 0)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only allow network request from internal white list
|
||||||
|
int i = 0, j = 0;
|
||||||
|
char rule[128] = {0};
|
||||||
|
for (j=0; j<pod->portmap_white_lists->i_num; j++) {
|
||||||
|
sprintf(rule, "-s %s -j ACCEPT",
|
||||||
|
pod->portmap_white_lists->internal_networks[j]);
|
||||||
|
struct ipt_rule accept_rule = {
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-I",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = rule,
|
||||||
|
};
|
||||||
|
if (hyper_setup_iptables_rule(accept_rule)<0) {
|
||||||
|
fprintf(stderr, "setup accept_rule '%s' failed\n", rule);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->ports_num == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *network = NULL;
|
||||||
|
for (i=0; i<c->ports_num; i++) {
|
||||||
|
// setup port mapping only if host_port is set
|
||||||
|
if (c->ports[i].host_port > 0) {
|
||||||
|
for (j=0; j<pod->portmap_white_lists->e_num; j++) {
|
||||||
|
network = pod->portmap_white_lists->external_networks[j];
|
||||||
|
|
||||||
|
// redirect host_port to container_port
|
||||||
|
if (c->ports[i].host_port != c->ports[i].container_port) {
|
||||||
|
sprintf(rule, "-s %s -p %s -m %s --dport %d -j REDIRECT --to-ports %d",
|
||||||
|
network,
|
||||||
|
c->ports[i].protocol,
|
||||||
|
c->ports[i].protocol,
|
||||||
|
c->ports[i].host_port,
|
||||||
|
c->ports[i].container_port);
|
||||||
|
struct ipt_rule redirect_rule = {
|
||||||
|
.table = "nat",
|
||||||
|
.op = "-I",
|
||||||
|
.chain = "hyperstart-PREROUTING",
|
||||||
|
.rule = rule,
|
||||||
|
};
|
||||||
|
if (hyper_setup_iptables_rule(redirect_rule)<0) {
|
||||||
|
fprintf(stderr, "setup redirect_rule '%s' failed\n", rule);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// open container_port to external network
|
||||||
|
sprintf(rule, "-s %s -p %s -m %s --dport %d -j ACCEPT",
|
||||||
|
network,
|
||||||
|
c->ports[i].protocol,
|
||||||
|
c->ports[i].protocol,
|
||||||
|
c->ports[i].container_port);
|
||||||
|
struct ipt_rule accept_rule = {
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-I",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = rule,
|
||||||
|
};
|
||||||
|
if (hyper_setup_iptables_rule(accept_rule)<0) {
|
||||||
|
fprintf(stderr, "setup accept_rule '%s' failed\n", rule);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hyper_cleanup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod)
|
||||||
|
{
|
||||||
|
if (pod->portmap_white_lists == NULL || (pod->portmap_white_lists->i_num == 0 &&
|
||||||
|
pod->portmap_white_lists->e_num == 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0, j = 0;
|
||||||
|
char rule[128] = {0};
|
||||||
|
for (j=0; j<pod->portmap_white_lists->i_num; j++) {
|
||||||
|
sprintf(rule, "-s %s -j ACCEPT",
|
||||||
|
pod->portmap_white_lists->internal_networks[j]);
|
||||||
|
struct ipt_rule accept_rule = {
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-D",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = rule,
|
||||||
|
};
|
||||||
|
if (hyper_setup_iptables_rule(accept_rule)<0) {
|
||||||
|
fprintf(stderr, "cleanup accept_rule '%s' failed\n", rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->ports_num == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *network = NULL;
|
||||||
|
for (i=0; i<c->ports_num; i++) {
|
||||||
|
// clean up port mapping only if host_port is set
|
||||||
|
if (c->ports[i].host_port > 0) {
|
||||||
|
for (j=0; j<pod->portmap_white_lists->e_num; j++) {
|
||||||
|
network = pod->portmap_white_lists->external_networks[j];
|
||||||
|
|
||||||
|
// delete rules redirecting host_port to container_port
|
||||||
|
if (c->ports[i].host_port != c->ports[i].container_port) {
|
||||||
|
sprintf(rule, "-s %s -p %s -m %s --dport %d -j REDIRECT --to-ports %d",
|
||||||
|
network,
|
||||||
|
c->ports[i].protocol,
|
||||||
|
c->ports[i].protocol,
|
||||||
|
c->ports[i].host_port,
|
||||||
|
c->ports[i].container_port);
|
||||||
|
struct ipt_rule redirect_rule = {
|
||||||
|
.table = "nat",
|
||||||
|
.op = "-D",
|
||||||
|
.chain = "hyperstart-PREROUTING",
|
||||||
|
.rule = rule,
|
||||||
|
};
|
||||||
|
if (hyper_setup_iptables_rule(redirect_rule)<0) {
|
||||||
|
fprintf(stderr, "cleanup redirect '%s' failed\n", rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// open container_port to external network
|
||||||
|
sprintf(rule, "-s %s -p %s -m %s --dport %d -j ACCEPT",
|
||||||
|
network,
|
||||||
|
c->ports[i].protocol,
|
||||||
|
c->ports[i].protocol,
|
||||||
|
c->ports[i].container_port);
|
||||||
|
struct ipt_rule accept_rule = {
|
||||||
|
.table = "filter",
|
||||||
|
.op = "-D",
|
||||||
|
.chain = "hyperstart-INPUT",
|
||||||
|
.rule = rule,
|
||||||
|
};
|
||||||
|
if (hyper_setup_iptables_rule(accept_rule)<0) {
|
||||||
|
fprintf(stderr, "cleanup accept_rule '%s' failed\n", rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef _PORT_MAPPING_H_
|
||||||
|
#define _PORT_MAPPING_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
struct ipt_rule {
|
||||||
|
char *table;
|
||||||
|
char *op;
|
||||||
|
char *chain;
|
||||||
|
char *rule;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hyper_pod;
|
||||||
|
struct hyper_container;
|
||||||
|
int hyper_setup_portmapping(struct hyper_pod *pod);
|
||||||
|
void hyper_cleanup_portmapping(struct hyper_pod *pod);
|
||||||
|
int hyper_setup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod);
|
||||||
|
void hyper_cleanup_container_portmapping(struct hyper_container *c, struct hyper_pod *pod);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use raw syscall for versions of glibc that don't include it. But this
|
||||||
|
* requires kernel-headers for syscall number hint.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(HAVE_SETNS) && defined(__NR_setns)
|
||||||
|
static inline int setns(int fd, int nstype)
|
||||||
|
{
|
||||||
|
errno = syscall(__NR_setns, fd, nstype);
|
||||||
|
return errno == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
+492
-96
@@ -9,19 +9,42 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <mntent.h>
|
#include <mntent.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
#include "net.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "hyper.h"
|
||||||
|
#include "container.h"
|
||||||
|
#include "../config.h"
|
||||||
|
|
||||||
char *read_cmdline(void)
|
char *read_cmdline(void)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hyper_setup_env(struct env *envs, int num)
|
||||||
|
{
|
||||||
|
int i, ret = 0;
|
||||||
|
struct env *env;
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
env = &envs[i];
|
||||||
|
if (setenv(env->env, env->value, 1) < 0) {
|
||||||
|
perror("fail to setup env");
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int hyper_list_dir(char *path)
|
int hyper_list_dir(char *path)
|
||||||
{
|
{
|
||||||
struct dirent **list;
|
struct dirent **list;
|
||||||
@@ -38,54 +61,447 @@ int hyper_list_dir(char *path)
|
|||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
dir = list[i];
|
dir = list[i];
|
||||||
fprintf(stdout, "%s get %s\n", path, dir->d_name);
|
fprintf(stdout, "%s get %s\n", path, dir->d_name);
|
||||||
|
free(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(list);
|
free(list);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hyper_mkdir(char *hyper_path)
|
int hyper_copy_dir(char *src, char *dest)
|
||||||
|
{
|
||||||
|
char cmd[512];
|
||||||
|
snprintf(cmd, sizeof(cmd), "tar cf - -C %s . | tar fx - -C %s", src, dest);
|
||||||
|
|
||||||
|
return hyper_cmd(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hyper_sync_time_hctosys() {
|
||||||
|
int pid;
|
||||||
|
pid = fork();
|
||||||
|
if (pid < 0) {
|
||||||
|
perror("fail to fork to copy directory");
|
||||||
|
} else if (pid == 0) {
|
||||||
|
execlp("hwclock", "hwclock", "-s", NULL);
|
||||||
|
perror("exec hwclock -s command failed");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int hyper_find_sd(char *addr, char **dev)
|
||||||
|
{
|
||||||
|
struct dirent **list;
|
||||||
|
struct dirent *dir;
|
||||||
|
char path[512];
|
||||||
|
int i, num;
|
||||||
|
|
||||||
|
sprintf(path, "/sys/class/scsi_disk/0:0:%s/device/block/", addr);
|
||||||
|
fprintf(stdout, "orig dev %s, scan path %s\n", *dev, path);
|
||||||
|
|
||||||
|
num = scandir(path, &list, NULL, NULL);
|
||||||
|
if (num < 0) {
|
||||||
|
perror("scan path failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
dir = list[i];
|
||||||
|
if (dir->d_name[0] == '.') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "%s get %s\n", path, dir->d_name);
|
||||||
|
*dev = strdup(dir->d_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++)
|
||||||
|
free(list[i]);
|
||||||
|
|
||||||
|
free(list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long id_or_max(const char *name)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
long id = strtol(name, &ptr, 10);
|
||||||
|
if (name == ptr || id < 0 || (errno != 0 && id == 0) || *ptr != '\0')
|
||||||
|
return ~0UL;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the same as getpwnam(), but it only parses /etc/passwd and allows name to be id string
|
||||||
|
struct passwd *hyper_getpwnam(const char *name)
|
||||||
|
{
|
||||||
|
uid_t uid = (uid_t)id_or_max(name);
|
||||||
|
FILE *file = fopen("/etc/passwd", "r");
|
||||||
|
if (!file) {
|
||||||
|
perror("faile to open /etc/passwd");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
struct passwd *pwd = fgetpwent(file);
|
||||||
|
if (!pwd)
|
||||||
|
break;
|
||||||
|
if (!strcmp(pwd->pw_name, name) || pwd->pw_uid == uid) {
|
||||||
|
fclose(file);
|
||||||
|
return pwd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the same as getgrnam(), but it only parses /etc/group and allows the name to be id string
|
||||||
|
struct group *hyper_getgrnam(const char *name)
|
||||||
|
{
|
||||||
|
gid_t gid = (gid_t)id_or_max(name);
|
||||||
|
FILE *file = fopen("/etc/group", "r");
|
||||||
|
if (!file) {
|
||||||
|
perror("faile to open /etc/group");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
struct group *gr = fgetgrent(file);
|
||||||
|
if (!gr)
|
||||||
|
break;
|
||||||
|
if (!strcmp(gr->gr_name, name) || gr->gr_gid == gid) {
|
||||||
|
fclose(file);
|
||||||
|
return gr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the same as getgrouplist(), but it only parses /etc/group
|
||||||
|
int hyper_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups)
|
||||||
|
{
|
||||||
|
int nr = 0, ret;
|
||||||
|
FILE *file = fopen("/etc/group", "r");
|
||||||
|
if (!file) {
|
||||||
|
perror("faile to open /etc/group");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
struct group *gr = fgetgrent(file);
|
||||||
|
if (!gr)
|
||||||
|
break;
|
||||||
|
int j;
|
||||||
|
for (j = 0; gr->gr_mem && gr->gr_mem[j]; j++) {
|
||||||
|
if (!strcmp(gr->gr_mem[j], user)) {
|
||||||
|
if (nr + 1 < *ngroups)
|
||||||
|
groups[nr] = gr->gr_gid;
|
||||||
|
nr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
if (nr == 0) {
|
||||||
|
if (nr + 1 < *ngroups)
|
||||||
|
groups[nr] = group;
|
||||||
|
nr++;
|
||||||
|
}
|
||||||
|
ret = nr <= *ngroups ? nr : -1;
|
||||||
|
*ngroups = nr;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hyper_write_file(const char *path, const char *value, size_t len)
|
||||||
|
{
|
||||||
|
size_t size = 0, l;
|
||||||
|
int fd = open(path, O_WRONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("open file failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (size < len) {
|
||||||
|
l = write(fd, value + size, len - size);
|
||||||
|
if (l < 0) {
|
||||||
|
perror("fail to write to file");
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
size += l;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Trim all trailing '/' of a hyper_path except for the prefix one. */
|
||||||
|
void hyper_filize(char *hyper_path)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (strlen(hyper_path) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
p = &hyper_path[strlen(hyper_path) - 1];
|
||||||
|
|
||||||
|
for (; *p == '/' && p != hyper_path; p--) {
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hyper_create_parent_dir(const char *hyper_path)
|
||||||
|
{
|
||||||
|
char *p, *path = strdup(hyper_path);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (path == NULL)
|
||||||
|
return -1;
|
||||||
|
p = strrchr(path, '/');
|
||||||
|
if (p != NULL && p != path) {
|
||||||
|
*p = '\0';
|
||||||
|
ret = hyper_mkdir(path, 0777);
|
||||||
|
}
|
||||||
|
free(path);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hyper_path must point to a file rather than a directory, e.g., having trailing '/' */
|
||||||
|
int hyper_create_file(const char *hyper_path)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
if (stat(hyper_path, &stbuf) >= 0) {
|
||||||
|
if (S_ISREG(stbuf.st_mode))
|
||||||
|
return 0;
|
||||||
|
errno = S_ISDIR(stbuf.st_mode) ? EISDIR : EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hyper_create_parent_dir(hyper_path) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
fd = open(hyper_path, O_CREAT|O_WRONLY, 0666);
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
close(fd);
|
||||||
|
fprintf(stdout, "created file %s\n", hyper_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hyper_mkdir(char *hyper_path, mode_t mode)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *p, *path = strdup(hyper_path);
|
char *p, *path = strdup(hyper_path);
|
||||||
|
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stdout, "create directory %s\n", path);
|
|
||||||
if (stat(path, &st) >= 0) {
|
if (stat(path, &st) >= 0) {
|
||||||
if (S_ISDIR(st.st_mode))
|
if (S_ISDIR(st.st_mode))
|
||||||
return 0;
|
goto out;
|
||||||
errno = ENOTDIR;
|
errno = ENOTDIR;
|
||||||
return -1;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
return -1;
|
goto fail;
|
||||||
|
|
||||||
p = strrchr(path, '/');
|
p = strrchr(path, '/');
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p != path) {
|
if (p != path) {
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
if (hyper_mkdir(path) < 0)
|
if (hyper_mkdir(path, mode) < 0)
|
||||||
return -1;
|
goto fail;
|
||||||
|
|
||||||
*p = '/';
|
*p = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mkdir(path, 0755) < 0 && errno != EEXIST)
|
fprintf(stdout, "create directory %s\n", path);
|
||||||
return -1;
|
if (mkdir(path, mode) < 0 && errno != EEXIST) {
|
||||||
|
perror("failed to create directory");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
free(path);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
free(path);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void online_cpu(void)
|
||||||
|
{
|
||||||
|
DIR *dir = opendir("/sys/devices/system/cpu");
|
||||||
|
if (dir == NULL) {
|
||||||
|
fprintf(stderr, "open dir /sys/devices/system/cpu failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("online_cpu()\n");
|
||||||
|
for (;;) {
|
||||||
|
int num;
|
||||||
|
int ret;
|
||||||
|
char path[256];
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
struct dirent *entry = readdir(dir);
|
||||||
|
if (entry == NULL)
|
||||||
|
break;
|
||||||
|
if (entry->d_type != DT_DIR)
|
||||||
|
continue;
|
||||||
|
ret = sscanf(entry->d_name, "cpu%d", &num);
|
||||||
|
if (ret < 1 || num == 0) /* skip none cpu%d and cpu0 */
|
||||||
|
continue;
|
||||||
|
sprintf(path, "/sys/devices/system/cpu/%s/online", entry->d_name);
|
||||||
|
fd = open(path, O_RDWR);
|
||||||
|
if (fd < 0) {
|
||||||
|
fprintf(stderr, "open %s failed\n", path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("try to online %s\n", entry->d_name);
|
||||||
|
ret = write(fd, "1", sizeof("1"));
|
||||||
|
printf("online %s result: %s\n", entry->d_name, ret == 2 ? "success" : "failed");
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void online_memory(void)
|
||||||
|
{
|
||||||
|
DIR *dir = opendir("/sys/devices/system/memory");
|
||||||
|
if (dir == NULL) {
|
||||||
|
fprintf(stderr, "open dir /sys/devices/system/memory failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("online_memory()\n");
|
||||||
|
for (;;) {
|
||||||
|
int num;
|
||||||
|
int ret;
|
||||||
|
char path[256];
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
struct dirent *entry = readdir(dir);
|
||||||
|
if (entry == NULL)
|
||||||
|
break;
|
||||||
|
if (entry->d_type != DT_DIR)
|
||||||
|
continue;
|
||||||
|
ret = sscanf(entry->d_name, "memory%d", &num);
|
||||||
|
if (ret < 1 || num == 0) /* skip none memory%d and memory0 */
|
||||||
|
continue;
|
||||||
|
sprintf(path, "/sys/devices/system/memory/%s/online", entry->d_name);
|
||||||
|
fd = open(path, O_RDWR);
|
||||||
|
if (fd < 0) {
|
||||||
|
fprintf(stderr, "open %s failed\n", path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("try to online %s\n", entry->d_name);
|
||||||
|
ret = write(fd, "1", sizeof("1"));
|
||||||
|
printf("online %s result: %s\n", entry->d_name, ret == 2 ? "success" : "failed");
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("fail to open channel device");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "open %s get %d\n", channel, fd);
|
||||||
|
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);
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
err:
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#else
|
||||||
int hyper_open_channel(char *channel, int mode)
|
int hyper_open_channel(char *channel, int mode)
|
||||||
{
|
{
|
||||||
struct dirent **list;
|
struct dirent **list;
|
||||||
@@ -95,7 +511,7 @@ int hyper_open_channel(char *channel, int mode)
|
|||||||
|
|
||||||
num = scandir("/sys/class/virtio-ports/", &list, NULL, NULL);
|
num = scandir("/sys/class/virtio-ports/", &list, NULL, NULL);
|
||||||
if (num < 0) {
|
if (num < 0) {
|
||||||
perror("scan /sys/calss/virtio-ports/ failed");
|
perror("scan /sys/class/virtio-ports/ failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +537,6 @@ int hyper_open_channel(char *channel, int mode)
|
|||||||
fd = -1;
|
fd = -1;
|
||||||
|
|
||||||
if (strncmp(name, channel, strlen(channel))) {
|
if (strncmp(name, channel, strlen(channel))) {
|
||||||
fprintf(stderr, "channel %s, directory %s\n", channel, name);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +548,7 @@ int hyper_open_channel(char *channel, int mode)
|
|||||||
fprintf(stdout, "open hyper channel %s\n", path);
|
fprintf(stdout, "open hyper channel %s\n", path);
|
||||||
fd = open(path, O_RDWR | O_CLOEXEC | mode);
|
fd = open(path, O_RDWR | O_CLOEXEC | mode);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
perror("fail to open channel deice");
|
perror("fail to open channel device");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -142,33 +557,11 @@ int hyper_open_channel(char *channel, int mode)
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hyper_open_serial_dev(char *tty)
|
int hyper_insmod(char *module)
|
||||||
{
|
{
|
||||||
int fd = open(tty, O_RDWR | O_CLOEXEC | O_NOCTTY);
|
return 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);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int hyper_setfd_cloexec(int fd)
|
int hyper_setfd_cloexec(int fd)
|
||||||
{
|
{
|
||||||
@@ -201,7 +594,7 @@ int hyper_setfd_block(int fd)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hyper_setfd_nonblock(int fd)
|
int hyper_setfd_nonblock(int fd)
|
||||||
@@ -218,10 +611,10 @@ int hyper_setfd_nonblock(int fd)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hyper_unmount_all(void)
|
static void hyper_unmount_all(void)
|
||||||
{
|
{
|
||||||
FILE *mtab;
|
FILE *mtab;
|
||||||
struct mntent *mnt;
|
struct mntent *mnt;
|
||||||
@@ -261,64 +654,67 @@ void hyper_unmount_all(void)
|
|||||||
fprintf(stdout, ("umount %s: %s failed\n"),
|
fprintf(stdout, ("umount %s: %s failed\n"),
|
||||||
filesys, strerror(errno));
|
filesys, strerror(errno));
|
||||||
}
|
}
|
||||||
|
free(filesys);
|
||||||
|
mntlist[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sync();
|
sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hyper_kill_all(void)
|
void hyper_shutdown()
|
||||||
{
|
{
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hyper_shutdown(struct hyper_pod *pod)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
uint8_t *data = calloc(pod->c_num, 4);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
hyper_kill_all();
|
|
||||||
|
|
||||||
hyper_unmount_all();
|
hyper_unmount_all();
|
||||||
|
|
||||||
reboot(LINUX_REBOOT_CMD_POWER_OFF);
|
reboot(LINUX_REBOOT_CMD_POWER_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hyper_cmd(char *cmd)
|
||||||
|
{
|
||||||
|
int pid, status;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid < 0) {
|
||||||
|
perror("fail to fork");
|
||||||
|
return -1;
|
||||||
|
} else if (pid > 0) {
|
||||||
|
if (waitpid(pid, &status, 0) <= 0) {
|
||||||
|
perror("waiting fork cmd failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (WIFEXITED(status)) {
|
||||||
|
int ret = WEXITSTATUS(status);
|
||||||
|
fprintf(stdout, "%s cmd exit normally, status %" PRIu8 "\n", cmd, ret);
|
||||||
|
if (ret == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "cmd %s exit unexpectedly, status %" PRIu8 "\n", cmd, status);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
fprintf(stdout, "executing cmd %s\n", cmd);
|
||||||
|
execlp("sh", "sh", "-c", cmd, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t nonblock_read(int fd, void *buf, size_t count)
|
||||||
|
{
|
||||||
|
ssize_t len = 0, ret = 0;
|
||||||
|
|
||||||
|
while (len < count) {
|
||||||
|
ret = read(fd, buf + len, count - len);
|
||||||
|
if (ret <= 0) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
len += ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len > 0 ? len : ret;
|
||||||
|
}
|
||||||
|
|||||||
+32
-7
@@ -1,18 +1,43 @@
|
|||||||
#ifndef _UTIL_H_
|
#ifndef _UTIL_H_
|
||||||
#define _UTIL_H_
|
#define _UTIL_H_
|
||||||
|
|
||||||
#include "hyper.h"
|
#include <stdio.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include "../config.h"
|
||||||
|
|
||||||
|
struct hyper_pod;
|
||||||
|
struct env;
|
||||||
|
|
||||||
|
#ifdef WITH_DEBUG
|
||||||
|
#define dprintf(fmt, ...) \
|
||||||
|
fprintf(stdout, fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define dprintf(fmr, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
char *read_cmdline(void);
|
char *read_cmdline(void);
|
||||||
|
int hyper_setup_env(struct env *envs, int num);
|
||||||
|
int hyper_find_sd(char *addr, char **dev);
|
||||||
int hyper_list_dir(char *path);
|
int hyper_list_dir(char *path);
|
||||||
int hyper_mkdir(char *path);
|
int hyper_copy_dir(char *src, char *dst);
|
||||||
|
void hyper_sync_time_hctosys();
|
||||||
|
void online_cpu(void);
|
||||||
|
void online_memory(void);
|
||||||
|
int hyper_cmd(char *cmd);
|
||||||
|
int hyper_create_file(const char *hyper_path);
|
||||||
|
void hyper_filize(char *hyper_path);
|
||||||
|
int hyper_mkdir(char *path, mode_t mode);
|
||||||
|
int hyper_write_file(const char *path, const char *value, size_t len);
|
||||||
int hyper_open_channel(char *channel, int mode);
|
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_cloexec(int fd);
|
||||||
int hyper_setfd_block(int fd);
|
int hyper_setfd_block(int fd);
|
||||||
int hyper_setfd_nonblock(int fd);
|
int hyper_setfd_nonblock(int fd);
|
||||||
void hyper_shutdown(struct hyper_pod *pod);
|
int hyper_socketpair(int domain, int type, int protocol, int sv[2]);
|
||||||
void hyper_kill_all(void);
|
void hyper_shutdown();
|
||||||
void hyper_unmount_all(void);
|
int hyper_insmod(char *module);
|
||||||
|
struct passwd *hyper_getpwnam(const char *name);
|
||||||
|
struct group *hyper_getgrnam(const char *name);
|
||||||
|
int hyper_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);
|
||||||
|
ssize_t nonblock_read(int fd, void *buf, size_t count);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user