367 Commits
Author SHA1 Message Date
Gao feng b055f07cbb Merge pull request #222 from laijs/event-hanghup
change policy for event hangup
2016-10-19 13:13:33 +08:00
Lai Jiangshan a615be817c directly hangup the event when read/write-error on process's stdio
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-10-19 12:45:30 +08:00
Lai Jiangshan 4fc7dddb53 do not handle hup event if have in/out event
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-10-19 12:44:32 +08:00
Lai Jiangshan 256c491948 Merge pull request #219 from laijs/flush-stderr
flush stderr also when exit or install new stderr
2016-10-18 10:32:57 +08:00
Lai Jiangshan 9844779c4e Merge pull request #218 from gao-feng/errno
do not call any functions before check errno
2016-10-18 10:32:30 +08:00
Gao feng b6eff45cc4 do not call any functions before check errno
perror changes the errno, result in the errno checking
of execvp incorrect.

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-10-18 10:03:23 +08:00
Lai Jiangshan 6d75e8cc93 flush stderr also when exit or install new stderr
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-10-17 22:54:10 +08:00
Gao feng fcc968a004 Merge pull request #205 from amshinde/set-interface-name
Add ability to change interface name while setting up an interface.
2016-10-15 15:42:32 +08:00
Xu Wang bbb111ea6d Merge pull request #217 from gao-feng/close_stdin_by_container
don't accept any input if stdin is closed by process
2016-10-15 14:08:03 +08:00
Gao feng 88f445ce34 don't accept any input if stdin is closed by process
fix the input after close problem, this will cause
hyperstart panic.

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-10-15 12:28:34 +08:00
Gao feng 3747b03b70 Merge pull request #216 from gao-feng/logs
fix incorrect logs
2016-10-15 12:21:25 +08:00
Gao feng b1d90cf796 fix incorrect logs
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-10-15 12:10:22 +08:00
Lai Jiangshan 0470974773 Merge pull request #212 from laijs/non-error-msg
don't send non-error message to stderr
2016-10-15 11:36:18 +08:00
Gao feng 66bcaedf2a Merge pull request #215 from gao-feng/aarch64
aarch64: update readme
2016-10-14 18:04:58 +08:00
Gao feng 6b4a925945 aarch64: update readme
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-10-14 18:03:22 +08:00
Gao feng ca80a07ede Merge pull request #207 from gao-feng/aarch64
support aarch64
2016-10-14 17:48:44 +08:00
Archana Shinde 467d776b15 Add ability to change interface name while setting up an interface.
Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
2016-10-13 16:17:51 +00:00
Lai Jiangshan 3293eaa34b don't send non-error message to stderr
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-10-11 21:20:59 +08:00
Lai Jiangshan 18235fc443 Merge pull request #211 from laijs/remove-some-dead-code
Remove some dead code
2016-10-11 20:54:22 +08:00
Lai Jiangshan 9a406cc3dd remove unsued struct hyper_writter
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-10-11 18:06:14 +08:00
Lai Jiangshan d39a4a03f1 remove inet_prefix
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-10-11 18:02:55 +08:00
Lai Jiangshan 2878ec5890 remove unused hyper_open_serial_dev()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-10-11 17:33:06 +08:00
Lai Jiangshan b900783a3b Merge pull request #208 from laijs/Werror
add -Werror for build
2016-10-11 16:47:43 +08:00
Lai Jiangshan 9132f7549d Merge pull request #203 from YaoZengzeng/send-fd-CLONE_FILE
read and write file in parent process whose fd sent by its child process-CLONE_FILE
2016-10-11 16:46:19 +08:00
YaoZengzeng 232afc9538 read and write file in parent process whose fd sent by its child process
Signed-off-by: Yao Zengzeng <yaozengzeng@zju.edu.cn>
2016-10-11 16:28:31 +08:00
Lai Jiangshan 3d0f9b1692 add -Werror for build
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-10-11 15:27:18 +08:00
Lai Jiangshan 6afbb02017 Merge pull request #206 from laijs/test-from-hypercontainer
test hyperstart from hypercontainer
2016-10-11 10:42:49 +08:00
Lai Jiangshan 7e64971357 test hyperstart from hypercontainer
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-10-11 10:29:55 +08:00
Lai Jiangshan eb59290a59 Merge pull request #191 from devimc/topic/remove_busybox_dependency
Use binaries from PATH
2016-10-10 10:29:47 +08:00
Gao feng dc46e20caa support aarch64
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-10-09 20:25:05 +08:00
Xu Wang 8fdd03c635 Merge pull request #197 from gao-feng/rbuf
realloc read buffer for control channel
2016-10-09 15:29:54 +08:00
Lai Jiangshan 807ef53908 Merge pull request #200 from laijs/container-exit
move hyper_kill_container_processes() up
2016-10-09 14:56:40 +08:00
Gao feng 1acd0280e8 Merge pull request #201 from feiskyer/open
Open all connections from internal networks
2016-10-09 12:04:16 +08:00
Xu Wang 2e3bc177ea Merge pull request #202 from feiskyer/travis
Add travis
2016-10-08 14:04:13 +08:00
Pengfei Ni ec20f8ab0a Add travis 2016-10-08 13:25:00 +08:00
Pengfei Ni 648d99fa64 Open all ports for internal networks 2016-10-08 13:16:10 +08:00
Gao feng 2621a406cf Merge pull request #196 from devimc/topic/rescan_scsi
hyperstart should not end when rescan scsi fails
2016-10-05 20:09:07 -04:00
Julio Montes 72a049a72d hyperstart should not end when rescan scsi fails
Signed-off-by: Julio Montes <julio.montes@intel.com>
2016-10-03 14:14:06 -05:00
Lai Jiangshan 1fda991fee move hyper_kill_container_processes() up
hyper_kill_container_processes() depends on container->ns,
but hyper_release_exec() may calls hyper_cleanup_pod() which
calls hyper_cleanup_containers() and then hyper_cleanup_container(),
and container->ns is closed in hyper_cleanup_container().
It cause hyper_kill_container_processes() failed to
stat the container->ns.

[root@box ~]# grep 'fail to stat mnt ns' /var/log/hyper/ -rIn -l
/var/log/hyper/hyperd.sbox.root.log.INFO.20160923-231500.17245
/var/log/hyper/hyperd.sbox.root.log.INFO.20160925-100719.3091
/var/log/hyper/hyperd.sbox.root.log.INFO.20160925-104216.3720
/var/log/hyper/hyperd.sbox.root.log.INFO.20160925-195450.8766
/var/log/hyper/hyperd.sbox.root.log.INFO.20160926-150357.7493
/var/log/hyper/hyperd.sbox.root.log.INFO.20160926-151213.10722
/var/log/hyper/hyperd.sbox.root.log.INFO.20160926-151555.13867
/var/log/hyper/hyperd.sbox.root.log.INFO.20160926-152510.22823
/var/log/hyper/hyperd.sbox.root.log.INFO.20160926-171120.2454
/var/log/hyper/hyperd.sbox.root.log.INFO.20160926-174512.3308
/var/log/hyper/hyperd.sbox.root.log.INFO.20160928-153012.27740
/var/log/hyper/hyperd.sbox.root.log.INFO.20160929-214026.17673
/var/log/hyper/hyperd.sbox.root.log.INFO.20160929-222011.18735
/var/log/hyper/hyperd.sbox.root.log.INFO.20161001-004225.5899
[root@box ~]# grep 'fail to stat mnt ns' /var/log/hyper/ -rIn -l | wc
     14      14     875

it can be triggered via 'hyperctl run -t ubuntu' and then 'exit'
in the shell of the container.

so we have to swap the order of hyper_kill_container_processes
and hyper_release_exec().

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-10-02 21:28:14 +08:00
Lai Jiangshan 9077cf47b3 Merge pull request #199 from laijs/rename
rename stdio related functions
2016-10-02 20:36:48 +08:00
Lai Jiangshan ac4d6d8fc7 rename stdio related functions
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-10-01 00:59:42 +08:00
Julio Montes b232c8fcc9 Use binaries from PATH
Link binaries /busybox and /iptables to /bin/ and /sbin/

Signed-off-by: Julio Montes <julio.montes@intel.com>
2016-09-30 11:54:09 -05:00
Lai Jiangshan cb680e280d Merge pull request #195 from laijs/stdio_config
add struct stdio_config for fds
2016-10-01 00:41:25 +08:00
Gao feng 7401981c22 realloc read buffer for control channel
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-09-30 10:43:14 +08:00
Lai Jiangshan 83c3c1d424 add struct stdio_config for fds
directly close init/exec process stdio fds at the end of
hyper_run_process().

move exec->std*ev code into hyper_watch_exec_pty().

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-29 22:28:27 +08:00
Lai Jiangshan 9cd968e2d2 move hyper_watch_exec_pty() after get the process pid
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-29 20:13:53 +08:00
Lai Jiangshan 290217c87a Merge pull request #193 from laijs/remove-unused-hyper_cleanup_exec
Remove unused hyper_cleanup_exec()
2016-09-29 11:49:30 +08:00
Gao feng 39c027e58c Merge pull request #192 from laijs/no-EPOLLPRI
remove the usage of EPOLLPRI
2016-09-28 03:37:30 -04:00
Lai Jiangshan 22cfaea4d2 remove block out from send_exec_finishing()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-28 15:36:59 +08:00
Lai Jiangshan e3704f66ba remove unused hyper_cleanup_exec()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-28 15:36:59 +08:00
Lai Jiangshan 8ac18bf650 remove the usage of EPOLLPRI
partially revert 9a6738d8

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-28 12:17:04 +08:00
Lai Jiangshan d63f716523 Merge pull request #190 from laijs/exec-ref-pod
add pod field in struct hyper_exec
2016-09-27 17:07:04 +08:00
Lai Jiangshan 1973768704 add pod field in struct hyper_exec
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-26 21:04:31 +08:00
Lai Jiangshan 4011640b08 Merge pull request #189 from laijs/symlink-EEXIST
ignore the errno EEXIST when symlink for /dev/fd & /dev/std*
2016-09-26 18:21:14 +08:00
Lai Jiangshan db6f286244 ignore the errno EEXIST when symlink for /dev/fd & /dev/std*
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-26 17:51:49 +08:00
Lai Jiangshan b2e7a0f631 Merge pull request #188 from laijs/check-result
check the return value of the functions declared with warn_unused_result
2016-09-26 15:19:53 +08:00
Lai Jiangshan f4ad330a75 Merge pull request #187 from laijs/exec-cid-cleanup
cleanups for exec-id
2016-09-26 15:15:31 +08:00
Lai Jiangshan 54f5362a03 check the return value of the functions declared with warn_unused_result
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-25 19:58:29 +08:00
Lai Jiangshan 45967cc8b8 rename exec->id to exec->container_id
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-25 10:28:21 +08:00
Lai Jiangshan 728d02983e remove local variable path
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-25 10:12:31 +08:00
Lai Jiangshan 4e830d77b4 check exec->seq and exec->id earlier
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-25 10:08:21 +08:00
Lai Jiangshan 2a669f0558 Merge pull request #186 from laijs/stdio-cleanup
save ptymaster on exec->ptyfd and do some cleanups for stdio
2016-09-24 23:26:13 +08:00
Lai Jiangshan 5ed9195bf8 move setsid() out from hyper_install_process_stdio()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-23 23:25:13 +08:00
Lai Jiangshan 064879ff0a rename hyper_dup_exec_tty() to hyper_install_process_stdio()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-23 23:25:13 +08:00
Lai Jiangshan 2360c4dc3f use ptyslave instead of e->ptyfd to make code clean
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-23 23:25:13 +08:00
Lai Jiangshan da72799c96 close ptymaster when failed
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-23 23:25:13 +08:00
Lai Jiangshan 56198c3acd save ptymaster on ptyfd rather than pty slave
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-23 23:25:13 +08:00
Lai Jiangshan a07cabf2d0 Merge pull request #184 from gao-feng/status
shutdown vm immediately if no container remained
2016-09-23 14:36:35 +08:00
Lai Jiangshan 440e14cde4 Merge pull request #183 from laijs/check-close
check close before discarding the data
2016-09-23 13:21:21 +08:00
Lai Jiangshan 5b1b29593e check close before discarding the data
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-23 12:06:52 +08:00
Gao feng 519db047fb shutdown vm immediately if no container remained
Hyperstart may receive destroy-event after all of the
containers are exited, then hyper_destroy_pod will still
try to term all processes, but there are no container will
exit and trigger the sending out podfinished-event/ack-event
logic in hyper_release_exec.

Add exec to global list only after process is running,
And add remains after container is running.

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-09-23 11:39:24 +08:00
Lai Jiangshan 504218c41f Merge pull request #179 from laijs/event-read
event read handling refactor part1
2016-09-22 23:21:08 +08:00
Lai Jiangshan c0e8d92d9a Merge pull request #180 from crook/master
remove unexpectedly cd ..
2016-09-21 21:34:10 +08:00
Lai Jiangshan be7654b416 remove the unused struct hyper_event_ops::len_offset
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-21 21:26:09 +08:00
Lai Jiangshan 1cf932a784 introduce CONTROL_HEADER_SIZE & CONTROL_HEADER_LENGTH_OFFSET
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-21 21:24:56 +08:00
Lai Jiangshan 5c30a49c27 introduce STREAM_HEADER_SIZE & STREAM_HEADER_LENGTH_OFFSET
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-21 20:41:02 +08:00
Ray Chen 4b662dd4fa remove unexpectedly cd .. 2016-09-21 20:34:06 +08:00
Lai Jiangshan 13a58d6531 Merge pull request #178 from gao-feng/rename
some cleanup
2016-09-21 20:18:13 +08:00
Lai Jiangshan ecf00fc578 remove the unused struct hyper_event_ops::handle
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-21 18:38:17 +08:00
Lai Jiangshan 819f639334 directly call hyper_channel_handle() in hyper_channel_read()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-21 18:36:10 +08:00
Lai Jiangshan cdc84ecb4b remove the unused struct hyper_event_ops::ack
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-21 18:33:22 +08:00
Lai Jiangshan 9d7a6c0a0f remove hyper_event_read()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-21 18:22:04 +08:00
Lai Jiangshan d9e871409e introduce hyper_channel_read()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-21 18:13:36 +08:00
Lai Jiangshan bb5c2c5744 call hyper_ttyfd_handle() directly in hyper_ttyfd_read()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-21 17:08:43 +08:00
Lai Jiangshan 2f2be98cff introduce hyper_ttyfd_read()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-21 16:59:33 +08:00
Lai Jiangshan 28ea806216 introduce nonblock_read()
and call it in hyper_event_read()

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-21 16:59:18 +08:00
Gao feng 8c45a5d6fe rename type to req_destroy
The only usage of type is to identify if the pod
is destroyed by manually.

set the req_destroy inside the switch, this prevents
the other events overwriting this field.

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-09-20 21:22:53 +08:00
Gao feng 98262e7e50 cleanup: do not send reply message in hyper_shutdown
make hyper_shutdown interface more clearer.
Do the reply in hyper_pod_destroyed.

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-09-20 21:22:51 +08:00
Gao feng ff845ee371 cleanup: remove restart policy type
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-09-20 21:17:34 +08:00
Lai Jiangshan 6224d6b779 Merge pull request #173 from gao-feng/cleanup
typo: fix debug message
2016-09-20 10:49:39 +08:00
Gao feng 2fb3ad7474 Merge pull request #175 from laijs/ifindex
remove ifindex from configs
2016-09-19 22:45:15 -04:00
Lai Jiangshan 82c1ecd25a Merge pull request #174 from laijs/null-terminated
ensure the read buf is null-terminated
2016-09-20 10:36:31 +08:00
Lai Jiangshan b46bc34498 Merge pull request #172 from gao-feng/stoppod
cleanup stoppod
2016-09-20 10:36:02 +08:00
Lai Jiangshan 0c5335b8d5 remove ifindex from configs
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-20 10:33:44 +08:00
Lai Jiangshan dca1bd6aaa ensure the read buf is null-terminated
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-20 10:00:14 +08:00
Gao feng c4f06c3fcd rename STOPPOD to STOPPOD_DEPRECATED
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-09-20 09:53:14 +08:00
Gao feng 92fc1d65a5 typo: fix debug message
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-09-20 09:18:03 +08:00
Gao feng e0bc511a97 Don't support STOPPOD event any more
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-09-20 08:06:39 +08:00
Gao feng 46fd62cafd remove hyper_stop_pod
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-09-20 09:22:08 +08:00
Gao feng 41438d40d6 remove unnecessary stopping pod if setup pod failed
already has hyper_destroy_pod when start pod failed.

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-09-20 08:05:29 +08:00
Lai Jiangshan 7294253548 Merge pull request #171 from gao-feng/init-fail
setup init_pid of pod until pod started successfully
2016-09-19 15:32:27 +08:00
Gao feng 41366ae88a setup init_pid of pod until pod started successfully
In this case, there is no container init running, we cannot expect
hyper_release_exec will be called after terminating all processes.

With this patch, the destroy event will not try to kill running
container processes, it will call shutdown immediately.

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-09-19 14:57:47 +08:00
Lai Jiangshan 5edb81f783 Merge pull request #160 from jcvenegas/use-shared-dir-macro
Use macro SHARED_DIR for /tmp/hyper/shared path
2016-09-16 13:46:00 +08:00
Jose Carlos Venegas Munoz eea9702389 Use macro SHARED_DIR for /tmp/hyper/shared path
Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2016-09-16 00:37:25 -05:00
Peng Tao 7acbc5e288 Merge pull request #165 from hyperhq/revert-154-mntinit
Revert "handle volume special fstype"
2016-09-14 17:38:45 +08:00
Peng Tao 34ec350357 Revert "handle volume special fstype" 2016-09-14 17:35:48 +08:00
Gao feng b58b03874d Merge pull request #163 from laijs/c-string
enable using api command data as c-string inplace
2016-09-14 05:25:14 -04:00
Gao feng 02b777058d Merge pull request #164 from laijs/file-command
use file_command for reader_file&write_file command
2016-09-14 05:10:25 -04:00
Lai Jiangshan 17f9f7b4cf use file_command for write_file command
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-14 11:33:01 +08:00
Lai Jiangshan 4fa99f7a5b rename hyper_reader to file_command
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-14 11:27:20 +08:00
Gao feng 6efb8d2638 Merge pull request #162 from laijs/consume-all-the-data-in-handle
Consume all the data in handle()
2016-09-14 10:51:06 +08:00
Lai Jiangshan e2b79425f1 enable using api command data as c-string inplace
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-14 10:40:03 +08:00
Lai Jiangshan 21cb97d970 always comsume the date after handle()
even handle() failed.

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-14 10:17:06 +08:00
Lai Jiangshan f06259b0b9 direct set the buf->get to zero after consume
the handle() had consumed all the read data,
and we don't need to move the leftover data.

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-14 10:12:41 +08:00
Lai Jiangshan 70dd9f1447 Merge pull request #161 from laijs/api-header
move constants of API to src/api.h
2016-09-14 10:02:01 +08:00
Lai Jiangshan 8b674e78f5 move constants of API to src/api.h
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-13 23:47:00 +08:00
Lai Jiangshan de59d91bc2 Merge pull request #159 from dlespiau/20160912-trivial
A few trivial changes
2016-09-13 07:49:11 +08:00
Damien Lespiau 6824ff3d2e util: Fix 'calss' type in the virtio-ports scanning code
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
2016-09-12 18:23:03 +01:00
Damien Lespiau ffd28a721c container: Fix error message in hyper_rescan_scsi()
The message needs to mention scanning scsi, not virtio-ports.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
2016-09-12 18:23:03 +01:00
Damien Lespiau 6f73ec97e3 init: Fix copy/paste typo in mount error string
The error message should mention devtmpfs and not sysfs in that case.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
2016-09-12 18:23:03 +01:00
Damien Lespiau f01a9f4081 all: Fix the directroy typo
That typo crept in a few places.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
2016-09-12 18:23:03 +01:00
Damien Lespiau 79d066d847 gitignore: Ignore tags files
Running "make tags" generates tags to jump around the code easily.
Let's ignore the generated files though.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
2016-09-12 18:23:03 +01:00
Lai Jiangshan 9089ec3f25 Merge pull request #158 from dlespiau/20160912-autogen-hyperstart
build: Change hyperinit strings in autogen.sh to say hyperstart
2016-09-12 20:37:14 +08:00
Damien Lespiau 6e8bc85878 build: Change hyperinit strings in autogen.sh to say hyperstart
I'm guessing that's a previous name for the project.

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
2016-09-12 13:36:54 +01:00
Gao feng 4c0887f131 Merge pull request #153 from bergwolf/volmode
set umask when setting up container rootfs
2016-09-09 12:45:51 +08:00
Peng Tao 3d942a45bb set umask when setting up container rootfs
So that we can truly create files and directories in any mode.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-09-09 10:32:54 +08:00
Lai Jiangshan 83223f6832 Merge pull request #154 from bergwolf/mntinit
handle volume special fstype
2016-09-02 22:45:57 +08:00
Gao feng a2202183fb Merge pull request #155 from laijs/fix-order-bug
ensure the mnt_ns opened before the process exit
2016-09-02 15:08:30 +08:00
Lai Jiangshan 37856283d5 ensure the mnt_ns opened before the process exit
quote of the log:
> open container mount ns failed: No such file or directory
> start containers failed

the process exits when hyper_enter_sandbox(), so we have
to move the wait before hyper_enter_sandbox().

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-09-02 14:50:47 +08:00
Peng Tao bb7ebdaadd handle volume special fstype
We can use INIT_VOLUME_MOUNTPOINT_FSTYPE to tell hyperstart that
current volume is a fake volume that only needs mountpoint to be present.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-09-02 14:26:15 +08:00
Gao feng fe5c9a9d9c Merge pull request #152 from laijs/api-version
add version API
2016-09-01 14:37:59 +08:00
Lai Jiangshan 62ef95ba93 add version API
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-08-31 13:37:00 +08:00
Lai Jiangshan d8fb6c1af3 Merge pull request #143 from YaoZengzeng/parson-winsize
hyper_set_win_size with parson
2016-08-31 09:29:25 +08:00
Pengfei Ni 2ccac3fa9c Merge pull request #151 from gao-feng/conntrack
portmapping: blow up nf_conntrack_max
2016-08-30 09:48:43 +08:00
Gao feng 52c87dc016 portmapping: blow up nf_conntrack_max
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-08-30 09:45:49 +08:00
Lai Jiangshan f359cb9468 Merge pull request #150 from laijs/v0.6.2
bump version to 0.6.2
2016-08-29 17:27:01 +08:00
Lai Jiangshan 3de74e927c bump version to 0.6.2
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-08-29 17:18:06 +08:00
Lai Jiangshan 7b54d5c9da Merge pull request #149 from gao-feng/limit
setup Limit by default
2016-08-29 16:55:35 +08:00
Gao feng 1e4711d898 setup file-max by default
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-08-29 16:06:14 +08:00
Gao feng cb71f43ed1 blow up rlimit of process
NOFILE: 1000000:1000000
NPROC: 30604:30604
SIGPENGING: 30604:30604

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-08-29 16:05:15 +08:00
Gao feng c72276b004 Merge pull request #146 from bergwolf/mkdir-for-file-volume-only
do not create _data dir without checking first
2016-08-14 14:49:17 +08:00
Peng Tao 5735f9f674 free scandir list in non file volumes case
Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-08-14 13:54:06 +08:00
Peng Tao de0c2c97e4 do not create _data dir without checking first
container_populate_volume() checks _data existance to determine if it
should populate old data. We only need to create new _data with 0777
mode if there is no existing one. That includes two cases:
1. before populating old data in container_populate_volume()
2. mount an empty volume for the fist time

For file volume case, we need to chmod it instead, to make sure any user
is able to read/write the file.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-08-14 11:00:45 +08:00
Lai Jiangshan 8a86dd1f51 Merge pull request #144 from bergwolf/file-vol
fix up file volume binding handling
2016-08-10 22:41:48 +08:00
Peng Tao 5ba9b2550d handle directory destination for a file volume binding
If the destination directoroy does not exist in the base image,
create it as a file instead, following docker's practice.

[hyperpublic@hyperhq]$docker run -t -i -v /home/bergwolf/bin/procmuttmail:/vol/data/ busybox
/ # ls -l /vol/data
-rwxr-xr-x    1 1000     1000            28 Apr 17 05:38 /vol/data
/ #

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-08-10 18:03:52 +08:00
Peng Tao da986b4a3a create file volume's parent directory when necessary
Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-08-10 18:02:05 +08:00
YaoZengzeng 5b21370efd hyper_set_win_size with parson
Signed-off-by: Yao Zengzeng <yaozengzeng@zju.edu.cn>
2016-08-10 14:01:24 +08:00
Gao feng 2f4626dde2 Merge pull request #142 from laijs/enter-sandbox
enter the sandbox when hyper_setup_container_rootfs()
2016-08-02 22:30:03 +08:00
Lai Jiangshan bf61d6306e enter the sandbox when hyper_setup_container_rootfs()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-08-02 11:15:45 +08:00
Lai Jiangshan 74f6930073 add hyper_enter_sandbox()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-08-02 11:15:45 +08:00
Lai Jiangshan 0c05c999e3 remove tty from struct hyper_win_size
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-08-02 11:15:45 +08:00
Lai Jiangshan 97099eb46e declare functions to static
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-08-02 11:15:45 +08:00
Lai Jiangshan b28a02fa0d Merge pull request #140 from gao-feng/event2
[RFC]  handle ttyfd out event priorly when write buffer is full
2016-08-01 09:39:50 +08:00
Gao feng 9a6738d84d handle ttyfd out event priorly when write buffer is full
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-07-29 15:57:45 +08:00
Lai Jiangshan d3cfa23dde Merge pull request #139 from gao-feng/revert
Revert "move mount /proc to hyper_container_final_init()"
2016-07-21 10:07:15 +08:00
Gao feng 9bfb3be414 Revert "move mount /proc to hyper_container_final_init()"
running in child process, fail to setup finalinit

This reverts commit b0a601793e.
2016-07-21 10:02:58 +08:00
Gao feng ae2d491c20 Merge pull request #138 from laijs/mount-proc
Mount proc when first exec
2016-07-20 17:15:57 +08:00
Lai Jiangshan b0a601793e move mount /proc to hyper_container_final_init()
exec can be run earlier than start container.

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-20 16:58:44 +08:00
Lai Jiangshan 19f1dc012e refactor struct hyper_container
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-20 15:28:55 +08:00
Lai Jiangshan 87b1a5c29a add missing pod->remains++
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-20 12:24:48 +08:00
Lai Jiangshan 4a63bceb67 Merge pull request #137 from bergwolf/volume_mode
create volume _data dir with 0777 mode
2016-07-19 09:13:15 +08:00
Peng Tao b2f6b89ea6 move hyper_create_file to util.h
Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-07-18 20:55:52 +08:00
Peng Tao db4f364510 create volume _data dir with 0777 mode
So that any user is able to write to the new volume.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-07-18 20:55:32 +08:00
Gao feng 2ccea842bd Merge pull request #136 from bergwolf/hyper_cp
hyper_copy_dir should use hyper_cmd
2016-07-18 13:24:44 +08:00
Peng Tao 3197bcad45 hyper_copy_dir should use hyper_cmd
Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-07-16 16:01:24 +08:00
Lai Jiangshan 3bed96c176 Merge pull request #133 from gao-feng/env
env: setup envs of container for exec
2016-07-15 16:40:43 +08:00
Gao feng eecb4c5612 env: setup envs of container for exec
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-07-15 15:07:27 +08:00
Gao feng c015887bb6 Merge pull request #132 from gao-feng/bug
cleanup & fix zombie process bug
2016-07-14 22:55:38 +08:00
Gao feng 2169309145 exec: restore sigmask of child process
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-07-14 19:37:21 +08:00
Gao feng c5d25b6f5f event: rename de to he
dvm_event has been removed long long ago.

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-07-14 19:26:37 +08:00
Gao feng da6b36411a remove useless var global_exec
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-07-14 19:22:09 +08:00
Lai Jiangshan 06d10f2844 Merge pull request #130 from gao-feng/proc
mount proc filesystem of container in enter_container
2016-07-07 21:08:46 +08:00
Gao feng 70d35640b9 mount proc filesystem of container in enter_container
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-07-07 18:50:47 +08:00
Gao feng 1f501c5417 Merge pull request #129 from bergwolf/shutdown_on_error
send ERROR to runv when shutting down upon errors
2016-07-07 09:14:46 +08:00
Gao feng 1c21bb2e6f Merge pull request #128 from laijs/open-ns
wait until mount namespace fd is opened
2016-07-07 09:14:07 +08:00
Lai Jiangshan b6c6e1f991 wait until mount namespace fd is opened
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-06 19:28:55 +08:00
Peng Tao 98059369b8 send ERROR to runv when shutting down upon errors
Otherwise ACK might let runv think its command succeeds.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-07-06 19:19:06 +08:00
Gao feng 03187117e1 Merge pull request #127 from laijs/container-and-exec-operations
split container operation to hyper_setup_container() and hyper_run_process()
2016-07-06 19:04:23 +08:00
Lai Jiangshan 54aed5efc5 split container operation to hyper_setup_container() and hyper_run_process()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-06 17:15:42 +08:00
Lai Jiangshan 98b8211ddc move hyper_start_containers() to hyper_start_pod()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-06 15:55:07 +08:00
Lai Jiangshan cd9a8f4306 set early env for exec
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-06 14:05:46 +08:00
Lai Jiangshan bb550c2444 do not apply the container's env on exec
let the hyperd do it. (merge the envs)

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-06 14:05:33 +08:00
Lai Jiangshan 00308d00b5 split hyper_exec_cmd()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-06 11:39:27 +08:00
Gao feng e255de660d Merge pull request #126 from laijs/exec-fork
Exec:  use fork() instead of the fragile clone(CLONE_VM|CLONE_FILES)
2016-07-05 12:58:25 +08:00
Lai Jiangshan ca004ec273 use fork() instead of fragile clone(CLONE_VM|CLONE_FILES)
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-05 10:49:08 +08:00
Lai Jiangshan 52aca5a860 Merge pull request #125 from laijs/rootfs
use /tmp/hyperstart-rootfs as temporary rootfs
2016-07-05 09:50:12 +08:00
Lai Jiangshan 5fcac6f0bb move the call of hyper_watch_exec_pty() to parent(init) process
so we don't need to touch the parent's memory nor file table.

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-04 22:46:50 +08:00
Lai Jiangshan 216bce6fe0 don't wait hyper_do_exec_cmd() via waitpid()
wait it via hyper_get_type()

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-04 22:36:52 +08:00
Lai Jiangshan e8381942d4 send pid back to parent rather than touch the parent's memory directly
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-04 22:12:21 +08:00
Lai Jiangshan 51dc391bc0 all exec should have container id
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-04 21:58:05 +08:00
Lai Jiangshan 73a9c3e8e9 use /tmp/hyperstart-rootfs as temporary rootfs
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-07-04 20:56:00 +08:00
Gao feng 505ad4ddb0 Merge pull request #121 from YaoZengzeng/delete-container
Support for removing container
2016-07-01 11:23:44 +08:00
YaoZengzeng 20158b9033 Support for removing container
Signed-off-by: Yao Zengzeng <yaozengzeng@foxmail.com>
2016-06-30 19:59:18 -07:00
Gao feng 1e6dffd36f Merge pull request #123 from laijs/introduce-parson
Introduce parson
2016-06-30 15:30:48 +08:00
Lai Jiangshan d919414192 use parson to parse kill command
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-06-30 12:09:15 +08:00
Lai Jiangshan b15d771a56 add const to container id in hyper_find_container()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-06-30 12:05:01 +08:00
Lai Jiangshan b99768db28 add parson(github.com/kgabis/parson)
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-06-30 11:17:44 +08:00
Lai Jiangshan 1a612982e8 Merge pull request #122 from gao-feng/cleanup
remove useless field in hyper_pod
2016-06-29 17:13:48 +08:00
Gao feng 3f034fec04 remove useless field in hyper_pod
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-06-29 14:25:41 +08:00
Lai Jiangshan 831113b7d0 Merge pull request #118 from bergwolf/kvm-nested
enable kvm and devmem in guest kernel
2016-06-27 12:18:56 +08:00
Lai Jiangshan 64aeb1ceca Merge pull request #120 from bergwolf/file-vol
support file destination volume
2016-06-27 12:10:59 +08:00
Peng Tao 11c7507eed support file destination volume
If a volume source contains only one file named ".hyper_file_volume_data_do_not_create_on_your_own",
bind mount it as a file to the specified mountpoint inside container's namespace, rather than
mounting its parent directory.

The special name .hyper_file_volume_data_do_not_create_on_your_own is
agreed upon with client which would save a file as this name if it wants
to bind mount a single file rather than a directory.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-06-22 17:36:49 +08:00
Peng Tao 828204c1cf enable kvm and devmem in guest kernel
Also rebase to 4.4.12 release.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-06-08 11:33:02 +08:00
Gao feng 94720f4ace Merge pull request #116 from laijs/exec_process
introduce hyper_exec_process()
2016-06-06 10:34:04 +08:00
Gao feng 12a797cb9e Merge pull request #117 from feiskyer/redirect
Do not add redirect rule if hostport is equal to containerport
2016-06-06 10:26:55 +08:00
Pengfei Ni 7856628d8a Do not add redirect rule if hostport is equal to containerport 2016-06-06 10:06:18 +08:00
Lai Jiangshan 193c1cc97e introduce hyper_exec_process()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-06-05 23:25:21 +08:00
Lai Jiangshan c3eee6616f remove container_setup_tty()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-06-05 23:21:24 +08:00
Lai Jiangshan 3d57690daa send READY a little earlier when creating container
the flush(stdout) is removed, because it is also called
in the following code hyper_dup_exec_tty().

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-06-05 23:21:24 +08:00
Lai Jiangshan 9ca23869fc split container_setup_workdir()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-06-05 23:21:24 +08:00
Lai Jiangshan 72996cd5e8 make hyper_enter_container() static
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-06-05 23:21:24 +08:00
Lai Jiangshan ab6ff1d2bd setup the exec env in hyper_do_exec_cmd()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-06-05 23:21:08 +08:00
Lai Jiangshan 40f04580ec chdir to the specific dir
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-06-05 23:20:15 +08:00
Gao feng 286e0f9c8f Merge pull request #114 from feiskyer/pm
Add external network white list for port mapping
2016-06-03 16:42:07 +08:00
Pengfei Ni 6aa71c3bd9 Fix syntax errors 2016-06-03 16:39:54 +08:00
Pengfei Ni 01a958b209 add external network white list for port mapping 2016-06-03 16:03:02 +08:00
Lai Jiangshan bbba8776ff Merge pull request #113 from ptptptptptpt/cp_kernel_config
cp kernel_config out after making kernel
2016-06-03 14:40:20 +08:00
Pei Tong 34b6af632a cp kernel_config out after making kernel 2016-06-03 14:20:51 +08:00
Lai Jiangshan 99c593a8be Merge pull request #110 from ptptptptptpt/update-kernel
update kernel to 4.4.11; add more kernel modules
2016-05-31 22:54:09 +08:00
Pei Tong 57b130adbb update kernel to 4.4.11; add more kernel modules: netfilter, overlayfs, dm_thin, etc.. 2016-05-31 10:42:03 +00:00
Pengfei Ni 558adb04ab Merge pull request #109 from laijs/modules_directory
add missing modules/ directory
2016-05-30 16:55:36 +08:00
Lai Jiangshan 684dd342d7 add missing modules/ directory
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-05-30 15:04:42 +08:00
Lai Jiangshan 53bdafd2c5 Merge pull request #107 from gao-feng/route
handle null route json message
2016-05-30 11:11:28 +08:00
Gao feng f54f77ccaa Merge pull request #100 from feiskyer/port-mapping
Add port mapping
2016-05-30 09:27:22 +08:00
Pengfei Ni 6065205cb2 tiny fix 2016-05-29 09:19:06 +00:00
Pengfei Ni 071a0c2b30 Enable icmp by default 2016-05-29 09:19:06 +00:00
Pengfei Ni c4f9764556 Reduce size of iptables command 2016-05-29 09:19:06 +00:00
Pengfei Ni 99fe992d31 Use tcp/udp module instead of multiport 2016-05-29 09:19:06 +00:00
Pengfei Ni 837016a417 Compare string by strncmp 2016-05-29 09:19:06 +00:00
Pengfei Ni d7dd250195 Config protocol for redirect rules 2016-05-29 09:19:06 +00:00
Pengfei Ni 8626dfc79e Add libm for iptables cmd 2016-05-29 09:19:06 +00:00
Pengfei Ni 75e23882bf Setup port mapping for containers 2016-05-29 09:18:30 +00:00
Pengfei Ni 95394c8e5a Add iptables setup for port mapping 2016-05-29 09:18:30 +00:00
Pengfei Ni 623d667fa0 Add iptables cmd 2016-05-29 09:18:30 +00:00
Pengfei Ni 7279227474 Add white cidrs for port-mapping 2016-05-29 09:17:12 +00:00
Gao feng d2daea2927 Merge pull request #108 from laijs/kernel-build
update kernel build
2016-05-27 19:25:34 +08:00
Lai Jiangshan f4493e59f9 update kernel build
build kernel/modules in the hyperstart-dev:latest container
remove build/modules/ directroy and add modules.tar instead

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-05-27 18:29:03 +08:00
Gao feng 9cca6ef2f9 handle null route json message
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-05-26 15:38:00 +08:00
Lai Jiangshan aea6029ba1 Merge pull request #105 from gao-feng/route
support setup routes separately
2016-05-25 21:23:20 +08:00
Xu Wang fcc973cda6 Merge pull request #106 from gnawux/release_06
bump version to 0.6.0
2016-05-25 19:35:33 +08:00
Gao feng 0896a874c7 fix incorrect error message
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-05-25 15:31:36 +08:00
Gao feng 53ffb48e0a support setup routes separately
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-05-25 15:31:34 +08:00
Xu Wang a70c3cfb54 bump version to 0.6.0 2016-05-25 14:44:33 +08:00
Xu Wang 1a4a6794e0 Merge pull request #86 from bergwolf/9p-getattr
9p getattr hack
2016-05-25 12:53:31 +08:00
Lai Jiangshan 8024730027 Merge pull request #104 from gao-feng/fd
close fd in hyper_create
2016-05-24 16:08:35 +08:00
Gao feng 211eb96eb6 close fd in hyper_create
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-05-24 15:59:17 +08:00
Lai Jiangshan 5b7069c8b4 Merge pull request #102 from laijs/HOME-env
set the HOME env correctly when it is not configured
2016-05-20 07:57:27 +08:00
Lai Jiangshan ece6aa1a79 set the HOME env correctly when it is not configured
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-05-19 20:36:04 +08:00
Lai Jiangshan 185cfb9fe4 Merge pull request #95 from gao-feng/interface
support setup interface command
2016-05-19 14:02:38 +08:00
Gao feng c8b2fee21c Merge pull request #99 from gao-feng/fix
podinit: wait until container environment is ready
2016-05-18 14:56:00 +08:00
Gao feng 9ce56b757e podinit: wait until container environment is ready
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-05-18 14:48:11 +08:00
Gao feng 72fc9ade82 Merge pull request #98 from gao-feng/exit
use _exit replace exit
2016-05-18 12:33:02 +08:00
Gao feng 05c85499bc use _exit replace exit
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-05-18 12:32:11 +08:00
Lai Jiangshan 3785a4d02c Merge pull request #94 from gao-feng/exit
make exit code of exec/container consist with docker
2016-05-17 23:17:13 +08:00
Gao feng d74aaa326d make exit code of exec/container consist with docker
The exit code from `docker run` gives information about why the container
failed to run or why it exited.  When `docker run` exits with a non-zero code,
the exit codes follow the `chroot` standard, see below:

**_125_** if the error is with Docker daemon **_itself_**

    $ docker run --foo busybox; echo $?
    # flag provided but not defined: --foo
      See 'docker run --help'.
      125

**_126_** if the **_contained command_** cannot be invoked

    $ docker run busybox /etc; echo $?
    # docker: Error response from daemon: Container command '/etc' could not be invoked.
      126

**_127_** if the **_contained command_** cannot be found

    $ docker run busybox foo; echo $?
    # docker: Error response from daemon: Container command 'foo' not found or does not exist.
      127

**_Exit code_** of **_contained command_** otherwise

    $ docker run busybox /bin/sh -c 'exit 3'; echo $?
    # 3

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-05-17 15:33:24 +08:00
Gao feng 9615c24fca reagrd exec/start-container success after fork/clone success
If fork/clone failed, return ERROR message to outside.
otherwise ragard exec/start-container success, add
container/exec to exec list, waitpid in init will get
the exec status.

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-05-17 15:33:01 +08:00
Lai Jiangshan 783d711be1 Merge pull request #96 from gao-feng/init-exit
kill processes in container if container init exited
2016-05-17 15:08:11 +08:00
Gao feng 30b3bf772b kill processes in container if container init exited
consist with docker behavior.

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-05-17 11:13:20 +08:00
Lai Jiangshan d69a74be22 Merge pull request #90 from laijs/user
enable the user config
2016-05-16 22:31:19 +08:00
Lai Jiangshan 908797e672 enable the user config
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-05-13 16:34:40 +08:00
Gao feng cf2267cff2 support setup interface command
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-05-12 16:40:56 +08:00
Lai Jiangshan 42ba6daf6d Merge pull request #91 from WeiZhang555/typo
Fix typo
2016-05-10 18:11:06 +08:00
Zhang Wei 61b2963d0d Fix typo
Signed-off-by: Zhang Wei <zhangwei555@huawei.com>
2016-05-10 16:36:50 +08:00
Peng Tao c92d2d6430 Merge pull request #87 from laijs/fix-double-free
fix double free bug
2016-05-05 09:26:24 +08:00
Lai Jiangshan 274fa5cd84 fix double free bug
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-05-05 00:33:05 +08:00
Peng Tao baa07ce3f9 9p getattr hack
Update kernel to include 9p's getattr hack to make
fstat after unlink work.

The extra patch is in the kernel_patch directory.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-05-04 23:21:51 +08:00
Peng Tao 402a930af0 Merge pull request #85 from bergwolf/strdup
fix a few strdup memory leaks
2016-04-29 15:37:57 +08:00
Peng Tao 4475e2db1b fix possible memory leak
We are overriding container->image when passed container->scsiaddr. Make
sure we also free its memory if caller also passes the image field.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-04-29 15:36:28 +08:00
Peng Tao 2c12120713 fix two strdup memory leak
Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-04-29 15:36:14 +08:00
Gao feng 84207a3f97 Merge pull request #84 from laijs/allow-container_setup_modules-failed
Allow container_setup_modules() failed
2016-04-29 00:43:50 -05:00
Lai Jiangshan ab1c293818 extend the stack for hyper_container_init()
container_setup_modules() needs a large stack

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-27 21:46:03 +08:00
Lai Jiangshan 3fbba94a0f ignore error of setup modules
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-27 20:22:42 +08:00
Gao feng a9b7fed072 Merge pull request #81 from laijs/sync-time
sync hardware time to system time when start pod
2016-04-26 21:36:40 -05:00
Gao feng ad196e2fe3 Merge pull request #83 from bergwolf/xfs
xfs needs nouuid mount option
2016-04-25 21:09:35 -05:00
Peng Tao 0c3b80fdbd xfs needs nouuid mount option
Otherwise devicemapper/rbd mount might fail due to device UUID
conflicts on snapshot/clone devices.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-04-25 22:08:43 +08:00
Lai Jiangshan c835eb9dfe sync hardware time to system time when start pod
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-25 18:17:06 +08:00
Gao feng 99319c29a6 Merge pull request #79 from gao-feng/module
Add useful modules for hyper container
2016-04-22 20:43:38 -05:00
Gao feng 354c4f44b6 Add useful modules for hyper container
Add cgroup, netfilter, tun, veth and rtc driver.

Note: In some case, kernel will try to use userspace modprobe to
load module, so make sure init mntns has modprobe and modules.

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-04-20 17:46:32 +08:00
Gao feng 048ee7ba27 Merge pull request #75 from gao-feng/volume
fix fail to populate volume created by sharefs
2016-04-19 23:37:30 -05:00
Xu Wang 9eef10d3c3 Merge pull request #78 from laijs/hyperd-address
update the github address of the hypercontainer
2016-04-19 00:13:50 +08:00
Lai Jiangshan ecdc3cd339 update the github address of the hypercontainer
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-19 00:07:24 +08:00
Xu Wang 4f5b747c2b Merge pull request #76 from bergwolf/setup_dns
recreate /etc/resolv.conf iff specified in pod spec
2016-04-18 18:28:25 +08:00
Peng Tao a0bc0851d6 recreate /etc/resolv.conf iif specified in pod spec
hyperd would inject a default DNS server if user did not specify
it in pod spec. If we recreate resolv.conf here, the injected file
will be lost.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-04-17 17:37:52 +08:00
Gao feng c68c7b76d1 fix fail to populate volume created by sharefs
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-04-16 13:46:13 +08:00
Gao feng 9590958aae Merge pull request #70 from laijs/fix-exec-part2-update-API-between-runv-and-hyperstart
Fix exec part2 update api between runv and hyperstart
2016-04-07 21:03:54 -05:00
Lai Jiangshan d3199fcc60 remove defautl setting on tty when exec
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-07 16:45:56 +08:00
Lai Jiangshan 4b45b28122 use VmProcess and hyper_parse_process() for exec
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-07 15:11:38 +08:00
Lai Jiangshan e458707966 add hyper_parse_process() for parsing VmProcess
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-07 14:26:13 +08:00
Gao feng 3554b8ef0b Merge pull request #69 from laijs/fix-exec-part1-cleanup
Fix exec part1 cleanup
2016-04-07 00:44:25 -05:00
Lai Jiangshan 48e7b27737 rename container_parse_cmd() to container_parse_argv()
and take struct hyper_exec as its first argument.

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-07 12:17:50 +08:00
Lai Jiangshan 1cff207e67 kill all exec rather than only container in hyper_term_all()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-06 15:03:52 +08:00
Lai Jiangshan aa50e5812b move envs to struct hyper_exec
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-06 14:59:08 +08:00
Lai Jiangshan 64cbfd2a0b move workdir to struct hyper_exec
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-06 14:19:15 +08:00
Lai Jiangshan e487303205 rename container_free_cmd() to container_cleanup_exec()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-06 13:56:11 +08:00
Lai Jiangshan 5a91148a37 remove unused var path
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-06 12:52:25 +08:00
Lai Jiangshan 6a56562120 require exec->seq be set, we can't handle zero seq well
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-06 12:06:04 +08:00
Lai Jiangshan 8803fa8ccb move symlink of devices to container_setup_mount()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-06 10:35:50 +08:00
Lai Jiangshan 90998a9b21 Merge pull request #67 from bergwolf/no-init
recreate docker init layer files
2016-04-05 10:56:17 +08:00
Peng Tao 5e945d507e recreate docker init layer files
So that it is possible for the container creation code to skip
the init layer all together.

Signed-off-by: Peng Tao <bergwolf@gmail.com>
2016-04-05 03:09:53 +08:00
Lai Jiangshan c1023f414f Merge pull request #68 from gao-feng/copy
Copy
2016-04-04 23:58:21 +08:00
Gao feng e737392fc4 copy: symlink sh and tar to busybox
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-04-04 23:22:42 +08:00
Gao feng 01a09c9b8f copy: remove .oldroot prefix for busybox path
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-04-04 23:20:56 +08:00
Gao feng a524b04f8c copy: return error when exec copy failed
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-04-04 23:20:23 +08:00
Gao feng 2332d39620 Merge pull request #66 from laijs/setup-rootfs-before-chroot
Setup mounts&rootfs before chroot
2016-04-04 10:18:19 -05:00
Lai Jiangshan bc28dfedf8 remove prefix from hyper_find_sd()
we always use the intial /sys, so we don't need prefix

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-03 22:47:09 +08:00
Lai Jiangshan 09c0a1b41b remove oldroot
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-03 22:41:27 +08:00
Lai Jiangshan b441c1bffe do container_setup_dns() before move the rootfs
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-03 19:09:11 +08:00
Lai Jiangshan 5be2a71a84 do container_setup_volume() before move the rootfs
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-03 16:52:14 +08:00
Lai Jiangshan 8766f77f24 do container_setup_mount() before move the rootfs
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-03 16:34:08 +08:00
Lai Jiangshan e4beaad672 Merge pull request #65 from gao-feng/nondocker
create volume directory for non docker volume
2016-04-03 13:39:42 +08:00
Gao feng 7f6056fc4c create volume directory for non docker volume
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-04-03 12:26:24 +08:00
Lai Jiangshan 5ceb9b8906 Merge pull request #64 from gao-feng/volume
don't copy data to volume if volume alreay has data
2016-04-02 22:09:35 +08:00
Gao feng 2ace93e881 don't copy data to volume if volume alreay has data
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-04-02 20:22:51 +08:00
Gao feng abd52a4ae2 Merge pull request #63 from laijs/remove-oldroot-from-mount-source
Remove '/.oldroot' from mount source
2016-04-02 05:22:59 -05:00
Lai Jiangshan 76bccbd261 remove "/.oldroot" from mount source
before patch:
root@test-container-multi:/# mount
/dev/sdb on / type xfs (rw,relatime,attr2,inode64,logbsize=64k,sunit=128,swidth=128,noquota)
/.oldroot/dev/sda on /var/log type ext4 (rw,relatime,stripe=16,data=ordered)

after patch:
root@test-container-multi:/# mount
/dev/sdb on / type xfs (rw,relatime,attr2,inode64,logbsize=64k,sunit=128,swidth=128,noquota)
/dev/sda on /var/log type ext4 (rw,relatime,stripe=16,data=ordered)

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-02 17:52:25 +08:00
Lai Jiangshan 8f70de4d49 change the order of basic mount and volume mount
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-02 17:46:51 +08:00
Lai Jiangshan ea196f786d move mount of fsmap into container_setup_volume()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-02 17:41:55 +08:00
Gao feng ced3b9dc53 Merge pull request #62 from laijs/mkdir
print mkdir info in correct order
2016-04-02 01:04:35 -05:00
Gao feng 5ca0595e4f Merge pull request #61 from laijs/ptys
fix symlink leek
2016-04-02 01:04:19 -05:00
Gao feng 53cd58a121 Merge pull request #60 from laijs/msmove
Set the rootfs of the namespace to be the rootfs of the container
2016-04-01 23:05:40 -05:00
Lai Jiangshan 0a86f73869 Set the rootfs of the namespace to be the rootfs of the container
we use MS_MOVE to move the container rootfs to /, so that the rootfs
of the namespace and the rootfs of the container are the same.

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-02 11:54:14 +08:00
Lai Jiangshan 12ba0a42b2 print mkdir info in correct order
and only print it when it is needed to be maked.

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-02 11:37:06 +08:00
Lai Jiangshan 1ad3ffcf63 close ptymaster before exec
ptymaster is dup-ed without close-on-exec, we need to colse it.

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-02 11:29:15 +08:00
Lai Jiangshan 5f9a7ee0a2 reopen slave ptyfd for correcting the symlink path of the /dev/fd/1
before patch:
root@ubuntu-4562002641:/# readlink /dev/fd/1
/tmp/hyper/656f914cd9c030214bf95aff8f3bf418c1c277f5b82a661a27a174c9c8ce901b/devpts/3

after patch:
root@ubuntu-5512501784:/# readlink /dev/fd/1
/dev/pts/1

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-02 11:10:48 +08:00
Gao feng b0c0255148 Merge pull request #58 from gao-feng/initialize
support to initialize container environment
2016-04-01 21:48:51 -05:00
Gao feng 6b67c6a296 Merge pull request #59 from laijs/mount-rootfs
ensure the container see the mount point of the rootfs
2016-04-01 05:54:48 -05:00
Lai Jiangshan 0017a6110f ensure the container see the mount point of the rootfs
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-04-01 18:28:32 +08:00
Gao feng 6bbb9ac512 support to initialize container environment
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-04-01 16:48:26 +08:00
Xu Wang 6feb864e30 Merge pull request #57 from feiskyer/fix-cache
Do not cache for shared volumes
2016-03-29 11:34:50 +08:00
feisky 6ff04bf83d Do not cache for shared volumes 2016-03-28 17:45:00 +08:00
Lai Jiangshan 80778ddd25 Merge pull request #56 from laijs/pipe2
convert hyper_socketpair() to pipe2
2016-03-28 08:15:03 +08:00
Lai Jiangshan c455e8bc75 convert hyper_socketpair() to pipe2
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-26 18:23:03 +08:00
feisky 411cffdeec Merge pull request #55 from laijs/env
fix up default environment
2016-03-26 12:12:01 +08:00
Lai Jiangshan 04689c4138 set HOSTNAME environment
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-26 12:03:15 +08:00
Lai Jiangshan 50928fc1ef set/unset TERM environment based on tty config
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-26 11:44:37 +08:00
Lai Jiangshan 20c34a4312 set HOME environment
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-26 11:39:36 +08:00
Gao feng fdd2634721 Merge pull request #54 from liusdu/typo
fix a tiny typo to avoid compile error
2016-03-19 14:23:00 +00:00
Liu Hua b043ac88e1 fix a tiny typo to avoid compile error
Signed-off-by: Liu Hua <sdu.liu@huawei.com>
2016-03-19 22:03:28 +08:00
Gao feng 5c18914f2a Merge pull request #53 from laijs/handle-eof
Handle eof
2016-03-18 22:25:14 -05:00
Lai Jiangshan a0e1ecb2ba handle eof request of stdin
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-19 10:28:19 +08:00
Lai Jiangshan 5279ef3f96 send eof of stdout back to runv ony when release_exec()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-19 10:27:42 +08:00
feisky 36fb6e6877 Merge pull request #52 from gao-feng/tty
request to setup tty for exec by default
2016-03-15 12:02:54 +08:00
Gao feng 6632db44ae request to setup tty for exec by default
Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-03-15 11:36:11 +08:00
feisky 613a5a19db Merge pull request #51 from laijs/pipes-stdio
use pipes for stdio when non tty
2016-03-10 17:13:32 +08:00
Lai Jiangshan 21d63485b1 use pipes for stdio when non tty
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-10 00:14:03 +08:00
Lai Jiangshan eaae1ae3fb split exec.e into exec.stdinev and exec.stdoutev
and rename exec.errev to exec.stderrev
and make stdinev.fd stdoutev.fd stderrev.fd are valid but different
and register all these event

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-09 23:53:59 +08:00
Lai Jiangshan 333263b344 pass @exec to pts_hup()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-09 16:07:53 +08:00
Lai Jiangshan 50db29c634 add stdinfd/stdoutfd and rename errfd to stderrfd
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-09 16:01:17 +08:00
Lai Jiangshan fe5c6c29e1 use e->errfd directly to create stderr
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-09 15:46:04 +08:00
Lai Jiangshan 34d842901d always setup exec->errfd
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-09 15:45:48 +08:00
Lai Jiangshan a94833c482 open /dev/null for ptyfd in hyper_setup_exec_tty() when seq=0
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-09 15:45:37 +08:00
Gao feng 0676ed3227 Merge pull request #50 from laijs/enable-non-tty-stdio
Enable non tty stdio
2016-03-09 10:42:48 +08:00
Lai Jiangshan e12e480f79 change VmContainer's stdio's protocal
VmContainer.Tty: allocate tty or not
VmContainer.Stdio: Stdio sequence number
VmContainer.Stderr: Stderr sequence number if stderr is not share with
stdout (currently used when VmContainer.Tty is false)

And new stdio allocation code which respects the VmContainer.Tty.

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-08 21:03:34 +08:00
Lai Jiangshan 3fa27e7464 handle eof for the stdio handling
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-08 21:02:42 +08:00
Lai Jiangshan 013cbb7e1a Merge pull request #49 from laijs/pause
pause() in the pod_init loop
2016-03-07 23:22:52 +08:00
Lai Jiangshan 97aee2acb0 pause() in the pod_init loop
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-07 23:00:17 +08:00
Gao feng 43c2336d7f Merge pull request #48 from laijs/sigchld
Simplify SIGCHLD handling and make it exclusive with event handling
2016-03-07 22:50:44 +08:00
Lai Jiangshan 220677d76d simplify SIGCHLD handling of hyper_init
It uses epoll_pwait() instead of epoll_wait(), and ensures that
the SIGCHLD handling and the events handling are exclusive.

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-07 21:42:25 +08:00
Lai Jiangshan 0f396470ff simplify SIGCHLD handling of pod_init
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-07 21:38:52 +08:00
Xu Wang 94266c5111 Merge pull request #47 from laijs/no-nonblock-stderr
remove O_NONBLOCK from stderr
2016-03-06 07:29:56 +08:00
Lai Jiangshan 0b3370f6fa remove O_NONBLOCK from stderr
step1: start a container without tty
	hyper run ubuntu
step2: get the fdinfo of the stderr
	cat /proc/self/fdinfo/2
	pos:	0
	flags:	04001
	mnt_id:	8
it shows that the stderr has the O_NONBLOCK flags,
we should remove it.

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-03-05 21:49:38 +08:00
Lai Jiangshan c5abeccb65 Merge pull request #46 from laijs/missing-exit
add missing exit(0) to hyper_cmd_online_cpu_mem()
2016-02-29 23:00:12 +08:00
Lai Jiangshan aa7772b36c add missing exit(0) to hyper_cmd_online_cpu_mem()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-02-29 22:59:05 +08:00
Lai Jiangshan f47d84cf24 Merge pull request #45 from gao-feng/fix-free
free stack after cloned children finished
2016-02-29 18:58:51 +08:00
Gao feng d97485cfc0 free stack after cloned children finished
avoid children using the freed memory.

Signed-off-by: Gao feng <omarapazanadi@gmail.com>
2016-02-26 14:53:40 +08:00
Lai Jiangshan 4fc4ac0c46 Merge pull request #44 from laijs/online-cpu-mem
add ONLINECPUMEM command
2016-02-22 10:04:34 +08:00
Lai Jiangshan bd41fcfbe6 add ONLINECPUMEM command
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
2016-02-19 13:31:07 +08:00
41 changed files with 8517 additions and 2007 deletions
+3
View File
@@ -7,6 +7,8 @@
.#* .#*
.git .git
.deps .deps
TAGS
tags
init init
build/hyper_daemon build/hyper_daemon
build/hyper-initrd.img build/hyper-initrd.img
@@ -14,6 +16,7 @@ build/cbfs.rom
build/root/* build/root/*
build/*iso build/*iso
build/daemon build/daemon
build/kernel_config.old
build/.* build/.*
src/.* src/.*
Makefile Makefile
+24
View File
@@ -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
+2
View File
@@ -4,3 +4,5 @@ initrd-local:
@echo finish make initrd @echo finish make initrd
cbfs-local: cbfs-local:
@echo finish make cbfs @echo finish make cbfs
kernel-local:
@echo finish make kernel
+7 -2
View File
@@ -1,6 +1,6 @@
# The init Task for Hyper # The init Task for HyperContainer
You can get the 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
@@ -12,6 +12,11 @@ clone this repo, and make sure you have build-essentials installed. Go into the
Then you can find `hyper-initrd.img` in the build directory, together with a pre-built 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, If you want to get the boot disk file for VirtualBox, please reconfigure with flag --with-vbox,
> ./configure --with-vbox > ./configure --with-vbox
+5 -5
View File
@@ -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
} }
+29
View File
@@ -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
+12
View File
@@ -4,9 +4,21 @@ if WITH_VBOX
initrd-local: initrd-local:
bash ./make-initrd.sh vbox bash ./make-initrd.sh vbox
else else
if WITH_AARCH64
initrd-local:
bash ./make-initrd.sh aarch64
else
initrd-local: initrd-local:
bash ./make-initrd.sh bash ./make-initrd.sh
endif 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
View File
Binary file not shown.
Executable
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+730 -168
View File
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
-2
View File
@@ -1,2 +0,0 @@
# v4.4
afd2ff9b7e1b367172f18ba7f693dfb62bdcb2dc
BIN
View File
Binary file not shown.
+40 -9
View File
@@ -1,18 +1,50 @@
#!/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
@@ -21,13 +53,12 @@ done
if [ "$1"x = "vbox"x ]; then if [ "$1"x = "vbox"x ]; then
echo "build initrd for vbox" echo "build initrd for vbox"
cp ./vbox/driver/* ./root cp ./vbox/driver/* /tmp/hyperstart-rootfs
fi fi
cd ./root && find . | cpio -H newc -o | gzip -9 > ../hyper-initrd.img ( cd /tmp/hyperstart-rootfs && find . | cpio -H newc -o | gzip -9 ) > ./hyper-initrd.img
cd ../ rm -rf /tmp/hyperstart-rootfs
rm -rf ./root
if [ "$1"x = "cbfs"x ]; then if [ "$1"x = "cbfs"x ]; then
echo "build cbfs" echo "build cbfs"
BIN
View File
Binary file not shown.
Binary file not shown.
+14 -2
View File
@@ -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.5.0], [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([initrd 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])
@@ -38,6 +38,17 @@ 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([aarch64],
[AS_HELP_STRING([--with-aarch64],
[run hyperstart with 64-bit ARM architecture])],
[],[with_aarch64=no])
if test "x$with_aarch64" != "xno" ; then
AC_DEFINE_UNQUOTED([WITH_AARCH64], 1, [run hyperstart with 64-bit ARM architecture])
fi
AM_CONDITIONAL([WITH_AARCH64], [test "x$with_aarch64" != "xno"])
AC_ARG_WITH([vbox], AC_ARG_WITH([vbox],
[AS_HELP_STRING([--with-vbox], [AS_HELP_STRING([--with-vbox],
[run hyperstart on Virtualbox])], [run hyperstart on Virtualbox])],
@@ -61,6 +72,7 @@ AC_MSG_RESULT([
prefix: ${prefix} prefix: ${prefix}
with-vbox: ${with_vbox} with-vbox: ${with_vbox}
with-aarch64: ${with_aarch64}
compiler: ${CC} compiler: ${CC}
cflags: ${CFLAGS} cflags: ${CFLAGS}
+22
View File
@@ -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
View File
@@ -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
+51
View File
@@ -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_ */
+425 -246
View File
@@ -7,6 +7,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/utsname.h>
#include <unistd.h> #include <unistd.h>
#include <mntent.h> #include <mntent.h>
#include <signal.h> #include <signal.h>
@@ -19,6 +20,79 @@
#include "parse.h" #include "parse.h"
#include "syscall.h" #include "syscall.h"
static int container_populate_volume(char *src, char *dest)
{
struct stat st;
fprintf(stdout, "populate volumes from %s to %s\n", src, dest);
/* FIXME: check if has data in volume, (except lost+found) */
if (stat(dest, &st) == 0) {
if (!S_ISDIR(st.st_mode)) {
fprintf(stderr, "the _data in volume %s is not directory\n", dest);
return -1;
}
return 0;
}
if (errno != ENOENT) {
perror("access to volume failed\n");
return -1;
}
if (hyper_mkdir(dest, 0777) < 0) {
fprintf(stderr, "fail to create directory %s\n", dest);
return -1;
}
return hyper_copy_dir(src, dest);
}
const char *INIT_VOLUME_FILENAME = ".hyper_file_volume_data_do_not_create_on_your_own";
static int container_check_file_volume(char *hyper_path, const char **filename)
{
struct dirent **list;
struct stat stbuf;
int i, num, found = 0;
char path[PATH_MAX];
*filename = NULL;
num = scandir(hyper_path, &list, NULL, NULL);
if (num < 0) {
/* No data in the volume yet, treat as non-file-volume */
if (errno == ENOENT) {
return 0;
}
perror("scan path failed");
return -1;
} else if (num != 3) {
fprintf(stdout, "%s has %d files/dirs\n", hyper_path, num - 2);
for (i = 0; i < num; i++) {
free(list[i]);
}
free(list);
return 0;
}
sprintf(path, "%s/%s", hyper_path, INIT_VOLUME_FILENAME);
for (i = 0; i < num; i++) {
if (strcmp(list[i]->d_name, ".") != 0 &&
strcmp(list[i]->d_name, "..") != 0 &&
strcmp(list[i]->d_name, INIT_VOLUME_FILENAME) == 0 &&
stat(path, &stbuf) == 0 && S_ISREG(stbuf.st_mode)) {
found++;
}
free(list[i]);
}
free(list);
fprintf(stdout, "%s %s a file volume\n", hyper_path, found > 0?"is":"is not");
*filename = found > 0 ? INIT_VOLUME_FILENAME : NULL;
return 0;
}
static int container_setup_volume(struct hyper_container *container) static int container_setup_volume(struct hyper_container *container)
{ {
int i; int i;
@@ -26,140 +100,113 @@ static int container_setup_volume(struct hyper_container *container)
struct volume *vol; struct volume *vol;
for (i = 0; i < container->vols_num; i++) { for (i = 0; i < container->vols_num; i++) {
char volume[512];
char mountpoint[512];
char *options = NULL;
const char *filevolume = NULL;
vol = &container->vols[i]; vol = &container->vols[i];
if (vol->scsiaddr) if (vol->scsiaddr)
hyper_find_sd("/.oldroot", vol->scsiaddr, &vol->device); hyper_find_sd(vol->scsiaddr, &vol->device);
sprintf(dev, "/.oldroot/dev/%s", vol->device); sprintf(dev, "/dev/%s", vol->device);
sprintf(path, "/tmp/%s", vol->mountpoint); sprintf(path, "/tmp/%s", vol->mountpoint);
sprintf(mountpoint, "./%s", vol->mountpoint);
fprintf(stdout, "mount %s to %s, tmp path %s\n", fprintf(stdout, "mount %s to %s, tmp path %s\n",
dev, vol->mountpoint, path); dev, vol->mountpoint, path);
if (hyper_mkdir(path) < 0 || hyper_mkdir(vol->mountpoint) < 0) { if (hyper_mkdir(path, 0755) < 0) {
perror("create volume dir failed"); perror("create volume dir failed");
return -1; return -1;
} }
if (mount(dev, path, vol->fstype, 0, NULL) < 0) { if (!strncmp(vol->fstype, "xfs", strlen("xfs")))
perror("mount volume device faled"); options = "nouuid";
if (mount(dev, path, vol->fstype, 0, options) < 0) {
perror("mount volume device failed");
return -1; return -1;
} }
if (mount(path, vol->mountpoint, NULL, MS_BIND, NULL) < 0) { sprintf(volume, "/%s/_data", path);
perror("mount volume device faled"); if (container_check_file_volume(volume, &filevolume) < 0)
return -1;
if (filevolume == NULL) {
if (hyper_mkdir(mountpoint, 0755) < 0) {
perror("create volume dir failed");
return -1;
}
if (vol->docker) {
if (container->initialize &&
(container_populate_volume(mountpoint, volume) < 0)) {
fprintf(stderr, "fail to populate volume %s\n", mountpoint);
return -1;
}
} else if (hyper_mkdir(volume, 0777) < 0) {
/* First time mounting an empty volume */
perror("create _data dir failed");
return -1;
}
} else {
hyper_filize(mountpoint);
if (hyper_create_file(mountpoint) < 0) {
perror("create volume file failed");
return -1;
}
sprintf(volume, "/%s/_data/%s", path, filevolume);
/* 0777 so that any user can read/write the new file volume */
if (chmod(volume, 0777) < 0) {
fprintf(stderr, "fail to chmod directory %s\n", volume);
return -1;
}
}
if (mount(volume, mountpoint, NULL, MS_BIND, NULL) < 0) {
perror("mount volume device failed");
return -1; return -1;
} }
if (vol->readonly && if (vol->readonly &&
mount(path, vol->mountpoint, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0) { mount(volume, mountpoint, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0) {
perror("mount fsmap faled"); perror("mount fsmap failed");
return -1; return -1;
} }
umount(path); umount(path);
} }
return 0;
}
static void container_unmount_oldroot(char *path)
{
FILE *mtab;
struct mntent *mnt;
char *mntlist[128];
int i;
int n = 0;
char *filesys;
mtab = setmntent("/proc/mounts", "r");
if (mtab == NULL) {
fprintf(stderr, "cannot open /proc/mount");
return;
}
while (n < 128 && (mnt = getmntent(mtab))) {
if (strncmp(mnt->mnt_dir, path, strlen(path)))
continue;
mntlist[n++] = strdup(mnt->mnt_dir);
}
endmntent(mtab);
for (i = n - 1; i >= 0; i--) {
filesys = mntlist[i];
fprintf(stdout, "umount %s\n", filesys);
if (umount(mntlist[i]) < 0 && umount2(mntlist[i],
MNT_DETACH) < 0) {
fprintf(stdout, "umount %s: %s failed\n",
filesys, strerror(errno));
}
}
}
static int container_setup_mount(struct hyper_container *container)
{
int i, fd;
char src[512];
struct fsmap *map;
hyper_mkdir("/proc");
hyper_mkdir("/sys");
hyper_mkdir("/dev");
if (mount("proc", "/proc", "proc", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 ||
mount("sysfs", "/sys", "sysfs", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 ||
mount("devtmpfs", "/dev", "devtmpfs", MS_NOSUID, NULL) < 0) {
perror("mount basic filesystem for container failed");
return -1;
}
if (hyper_mkdir("/dev/shm") < 0) {
fprintf(stderr, "create /dev/shm failed\n");
return -1;
}
if (mount("tmpfs", "/dev/shm/", "tmpfs", MS_NOSUID| MS_NODEV, NULL) < 0) {
perror("mount shm failed");
return -1;
}
if (hyper_mkdir("/dev/pts") < 0) {
fprintf(stderr, "create /dev/pts failed\n");
return -1;
}
if (sprintf(src, "/.oldroot/tmp/hyper/%s/devpts", container->id) < 0) {
fprintf(stderr, "get container devpts failed\n");
return -1;
}
if (mount(src, "/dev/pts/", NULL, MS_BIND, NULL) < 0) {
perror("move pts to /dev/pts failed");
return -1;
}
if (unlink("/dev/ptmx") < 0)
perror("remove /dev/ptmx failed");
if (symlink("/dev/pts/ptmx", "/dev/ptmx") < 0)
perror("link /dev/pts/ptmx to /dev/ptmx failed");
for (i = 0; i < container->maps_num; i++) { for (i = 0; i < container->maps_num; i++) {
struct stat st; struct stat st;
char *src, path[512], volume[512];
struct fsmap *map = &container->maps[i];
char mountpoint[512];
map = &container->maps[i]; sprintf(path, "%s/%s", SHARED_DIR, map->source);
sprintf(mountpoint, "./%s", map->path);
sprintf(src, "/.oldroot/tmp/hyper/shared/%s", map->source); fprintf(stdout, "mount %s to %s\n", path, mountpoint);
fprintf(stdout, "mount %s to %s\n", src, map->path);
src = path;
stat(src, &st); stat(src, &st);
if (st.st_mode & S_IFDIR) { if (st.st_mode & S_IFDIR) {
if (hyper_mkdir(map->path) < 0) { if (hyper_mkdir(mountpoint, 0755) < 0) {
perror("create map dir failed"); perror("create map dir failed");
continue; continue;
} }
if (map->docker) {
/* converted from volume */
sprintf(volume, "%s/_data", path);
src = volume;
if (container->initialize &&
(container_populate_volume(mountpoint, volume) < 0)) {
fprintf(stderr, "fail to populate volume %s\n", mountpoint);
continue;
}
}
} else { } else {
fd = open(map->path, O_CREAT|O_WRONLY, 0755); int fd = open(mountpoint, O_CREAT|O_WRONLY, 0755);
if (fd < 0) { if (fd < 0) {
perror("create map file failed"); perror("create map file failed");
continue; continue;
@@ -167,65 +214,209 @@ static int container_setup_mount(struct hyper_container *container)
close(fd); close(fd);
} }
if (mount(src, map->path, NULL, MS_BIND, NULL) < 0) { if (mount(src, mountpoint, NULL, MS_BIND, NULL) < 0) {
perror("mount fsmap faled"); perror("mount fsmap failed");
continue; continue;
} }
if (map->readonly == 0) if (map->readonly == 0)
continue; continue;
if (mount(src, map->path, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0) if (mount(src, mountpoint, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0)
perror("mount fsmap faled"); perror("mount fsmap failed");
} }
return 0; return 0;
} }
static int container_setup_modules(struct hyper_container *container)
{
struct stat st;
struct utsname uts;
char src[512], dst[512];
if (uname(&uts) < 0) {
perror("fail to call uname");
return -1;
}
sprintf(src, "/lib/modules/%s", uts.release);
sprintf(dst, "./%s", src);
if (stat(dst, &st) == 0) {
struct dirent **list;
int num;
if (!S_ISDIR(st.st_mode)) {
return -1;
}
num = scandir(dst, &list, NULL, NULL);
if (num > 2) {
fprintf(stdout, "%s is not null, %d", dst, num);
return 0;
}
} else if (errno == ENOENT) {
if (hyper_mkdir(dst, 0755) < 0)
return -1;
} else {
return -1;
}
if (mount(src, dst, NULL, MS_BIND, NULL) < 0) {
perror("mount bind modules failed");
return -1;
}
return 0;
}
static int container_setup_mount(struct hyper_container *container)
{
char src[512];
// current dir is container rootfs, the operations on "./PATH" are the operations on container's "/PATH"
hyper_mkdir("./proc", 0755);
hyper_mkdir("./sys", 0755);
hyper_mkdir("./dev", 0755);
hyper_mkdir("./lib/modules", 0755);
if (mount("proc", "./proc", "proc", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 ||
mount("sysfs", "./sys", "sysfs", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 ||
mount("devtmpfs", "./dev", "devtmpfs", MS_NOSUID, NULL) < 0) {
perror("mount basic filesystem for container failed");
return -1;
}
if (hyper_mkdir("./dev/shm", 0755) < 0) {
fprintf(stderr, "create /dev/shm failed\n");
return -1;
}
if (mount("tmpfs", "./dev/shm/", "tmpfs", MS_NOSUID| MS_NODEV, NULL) < 0) {
perror("mount shm failed");
return -1;
}
if (hyper_mkdir("./dev/pts", 0755) < 0) {
fprintf(stderr, "create /dev/pts failed\n");
return -1;
}
if (sprintf(src, "/tmp/hyper/%s/devpts", container->id) < 0) {
fprintf(stderr, "get container devpts failed\n");
return -1;
}
if (mount(src, "./dev/pts/", NULL, MS_BIND, NULL) < 0) {
perror("move pts to /dev/pts failed");
return -1;
}
if (unlink("./dev/ptmx") < 0) {
perror("remove /dev/ptmx failed");
return -1;
}
if (symlink("/dev/pts/ptmx", "./dev/ptmx") < 0) {
perror("link /dev/pts/ptmx to /dev/ptmx failed");
return -1;
}
/* all containers share the same devtmpfs, so we need to ignore the errno EEXIST */
if ((symlink("/proc/self/fd", "./dev/fd") < 0 && errno != EEXIST) ||
(symlink("/proc/self/fd/0", "./dev/stdin") < 0 && errno != EEXIST) ||
(symlink("/proc/self/fd/1", "./dev/stdout") < 0 && errno != EEXIST) ||
(symlink("/proc/self/fd/2", "./dev/stderr") < 0 && errno != EEXIST)) {
perror("failed to symlink for /dev/fd, /dev/stdin, /dev/stdout or /dev/stderr");
return -1;
}
return 0;
}
static int container_recreate_file(char *filename)
{
struct stat stbuf;
fprintf(stdout, "recreate file %s\n", filename);
if (stat(filename, &stbuf) < 0) {
if (errno != ENOENT) {
fprintf(stderr, "failed to stat %s: %d\n", filename, errno);
return -1;
}
return hyper_create(filename);
}
if (stbuf.st_mode & S_IFREG && stbuf.st_size == 0)
return 0;
hyper_unlink(filename);
return hyper_create(filename);
}
static int container_recreate_symlink(char *oldpath, char *newpath)
{
fprintf(stdout, "recreate symlink %s to %s\n", newpath, oldpath);
hyper_unlink(newpath);
return hyper_symlink(oldpath, newpath);
}
/*
* Docker uses the init layer to protect against unwanted side effects on
* the rw layer. We recreate the same files here to have similar effect.
* Docker also creates directories like /dev/pts, /dev/shm, /proc, /sys,
* which we have over ridden in container_setup_mount, so no need to create
* them here.
*/
static int container_setup_init_layer(struct hyper_container *container,
int setup_dns)
{
if (!container->initialize)
return 0;
hyper_mkdir("./etc/", 0755);
if (setup_dns && container_recreate_file("./etc/resolv.conf") < 0)
return -1;
if (container_recreate_file("./etc/hosts") < 0)
return -1;
if (container_recreate_file("./etc/hostname") < 0)
return -1;
if (container_recreate_symlink("/proc/mounts", "./etc/mtab") < 0)
return -1;
return 0;
}
static int container_setup_sysctl(struct hyper_container *container) static int container_setup_sysctl(struct hyper_container *container)
{ {
int i, size, len, l, fd; int i;
struct sysctl *sys; struct sysctl *sys;
for (i = 0; i < container->sys_num; i++) { for (i = 0; i < container->sys_num; i++) {
char path[256]; char path[256];
len = 0;
sys = &container->sys[i]; sys = &container->sys[i];
size = strlen(sys->value);
sprintf(path, "/proc/sys/%s", sys->path); sprintf(path, "/proc/sys/%s", sys->path);
fprintf(stdout, "sysctl %s value %s\n", sys->path, sys->value); fprintf(stdout, "sysctl %s value %s\n", sys->path, sys->value);
fd = open(path, O_WRONLY); if (hyper_write_file(path, sys->value, strlen(sys->value)) < 0) {
if (fd < 0) { fprintf(stderr, "sysctl: write %s to %s failed\n", sys->value, path);
perror("open file failed"); return -1;
goto out;
} }
while (len < size) {
l = write(fd, sys->value + len, size - len);
if (l < 0) {
perror("fail to write sysctl");
close(fd);
goto out;
}
len += l;
}
close(fd);
} }
return 0; return 0;
out:
return -1;
} }
static int container_setup_dns(struct hyper_container *container) static int container_setup_dns(struct hyper_container *container)
{ {
int fd; int fd;
struct stat st; struct stat st;
char *src = "/.oldroot/tmp/hyper/resolv.conf"; char *src = "/tmp/hyper/resolv.conf";
if (stat(src, &st) < 0) { if (stat(src, &st) < 0) {
if (errno == ENOENT) { if (errno == ENOENT) {
@@ -237,16 +428,16 @@ static int container_setup_dns(struct hyper_container *container)
return -1; return -1;
} }
hyper_mkdir("/etc"); hyper_mkdir("./etc", 0755);
fd = open("/etc/resolv.conf", O_CREAT| O_WRONLY, 0644); fd = open("./etc/resolv.conf", O_CREAT| O_WRONLY, 0644);
if (fd < 0) { if (fd < 0) {
perror("create /etc/resolv.conf failed"); perror("create /etc/resolv.conf failed");
return -1; return -1;
} }
close(fd); close(fd);
if (mount(src, "/etc/resolv.conf", NULL, MS_BIND, NULL) < 0) { if (mount(src, "./etc/resolv.conf", NULL, MS_BIND, NULL) < 0) {
perror("bind to /etc/resolv.conf failed"); perror("bind to /etc/resolv.conf failed");
return -1; return -1;
} }
@@ -256,19 +447,14 @@ static int container_setup_dns(struct hyper_container *container)
static int container_setup_workdir(struct hyper_container *container) static int container_setup_workdir(struct hyper_container *container)
{ {
if (container->workdir && chdir(container->workdir) < 0) { if (container->initialize) {
perror("change work directory failed"); // create workdir
return -1; return hyper_mkdir(container->exec.workdir, 0755);
} }
return 0; return 0;
} }
static int container_setup_tty(int fd, struct hyper_container *container)
{
return hyper_dup_exec_tty(fd, &container->exec);
}
static int hyper_rescan_scsi(void) static int hyper_rescan_scsi(void)
{ {
struct dirent **list; struct dirent **list;
@@ -278,7 +464,7 @@ static int hyper_rescan_scsi(void)
num = scandir("/sys/class/scsi_host/", &list, NULL, NULL); num = scandir("/sys/class/scsi_host/", &list, NULL, NULL);
if (num < 0) { if (num < 0) {
perror("scan /sys/calss/virtio-ports/ failed"); perror("scan /sys/class/scsi_host/ failed");
return -1; return -1;
} }
@@ -316,43 +502,38 @@ static int hyper_rescan_scsi(void)
struct hyper_container_arg { struct hyper_container_arg {
struct hyper_container *c; struct hyper_container *c;
int ipcns; struct hyper_pod *pod;
int utsns;
int pipe[2]; int pipe[2];
int pipens[2];
}; };
static int hyper_container_init(void *data) static int hyper_setup_container_rootfs(void *data)
{ {
struct hyper_container_arg *arg = data; struct hyper_container_arg *arg = data;
struct hyper_container *container = arg->c; struct hyper_container *container = arg->c;
char root[512], oldroot[512]; char root[512], rootfs[512];
int setup_dns;
uint32_t type;
fprintf(stdout, "%s in\n", __func__); /* wait for ns-opened ready message */
if (container->exec.argv == NULL) { if (hyper_get_type(arg->pipens[0], &type) < 0 || type != READY) {
fprintf(stdout, "no cmd!\n"); fprintf(stderr, "wait for /proc/self/ns/mnt opened failed\n");
goto fail; goto fail;
} }
if (setns(arg->ipcns, CLONE_NEWIPC) < 0) { if (hyper_enter_sandbox(arg->pod, -1) < 0) {
perror("setns to ipcns of pod init faild"); perror("enter sandbox failed");
goto fail; goto fail;
} }
if (setns(arg->utsns, CLONE_NEWUTS) < 0) { /* To create files/directories accessible for all users. */
perror("setns to ipcns of pod init faild"); umask(0);
goto fail;
}
if (hyper_rescan_scsi() < 0) { if (container->fstype && hyper_rescan_scsi() < 0) {
fprintf(stdout, "rescan scsi failed\n"); fprintf(stdout, "rescan scsi failed\n");
goto fail; goto fail;
} }
if (hyper_setup_env(container->envs, container->envs_num) < 0) {
fprintf(stdout, "setup env failed\n");
goto fail;
}
if (mount("", "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) { if (mount("", "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
perror("mount SLAVE failed"); perror("mount SLAVE failed");
goto fail; goto fail;
@@ -364,8 +545,8 @@ static int hyper_container_init(void *data)
} }
sprintf(root, "/tmp/hyper/%s/root/", container->id); sprintf(root, "/tmp/hyper/%s/root/", container->id);
if (hyper_mkdir(root) < 0) { if (hyper_mkdir(root, 0755) < 0) {
perror("make root directroy failed"); perror("make root directory failed");
goto fail; goto fail;
} }
@@ -373,21 +554,28 @@ static int hyper_container_init(void *data)
if (container->fstype) { if (container->fstype) {
char dev[128]; char dev[128];
char *options = NULL;
if (container->scsiaddr) if (container->scsiaddr) {
hyper_find_sd("", container->scsiaddr, &container->image); free(container->image);
container->image = NULL;
hyper_find_sd(container->scsiaddr, &container->image);
}
sprintf(dev, "/dev/%s", container->image); sprintf(dev, "/dev/%s", container->image);
fprintf(stdout, "device %s\n", dev); fprintf(stdout, "device %s\n", dev);
if (mount(dev, root, container->fstype, 0, NULL) < 0) { if (!strncmp(container->fstype, "xfs", strlen("xfs")))
options = "nouuid";
if (mount(dev, root, container->fstype, 0, options) < 0) {
perror("mount device failed"); perror("mount device failed");
goto fail; goto fail;
} }
} else { } else {
char path[512]; char path[512];
sprintf(path, "/tmp/hyper/shared/%s/", container->image); sprintf(path, "%s/%s/", SHARED_DIR, container->image);
fprintf(stdout, "src directory %s\n", path); fprintf(stdout, "src directory %s\n", path);
if (mount(path, root, NULL, MS_BIND, NULL) < 0) { if (mount(path, root, NULL, MS_BIND, NULL) < 0) {
@@ -399,26 +587,23 @@ static int hyper_container_init(void *data)
fprintf(stdout, "root directory for container is %s/%s, init task %s\n", fprintf(stdout, "root directory for container is %s/%s, init task %s\n",
root, container->rootfs, container->exec.argv[0]); root, container->rootfs, container->exec.argv[0]);
sprintf(oldroot, "%s/%s/.oldroot", root, container->rootfs); sprintf(rootfs, "%s/%s/", root, container->rootfs);
if (hyper_mkdir(oldroot) < 0) { if (mount(rootfs, rootfs, NULL, MS_BIND|MS_REC, NULL) < 0) {
perror("make oldroot directroy failed"); perror("failed to bind rootfs");
goto fail;
}
if (chdir(rootfs) < 0) {
perror("failed to change the root to path of the container root(before manipulating)");
goto fail; goto fail;
} }
if (mount("/", oldroot, NULL, MS_BIND|MS_REC, NULL) < 0) { /*
perror("bind oldroot failed"); * Recreate dns resolver iif configured by pod spec. Other cases
goto fail; * are handled by hyperd instead.
} */
/* reuse oldroot array */ setup_dns = arg->pod->dns != NULL && arg->pod->d_num > 0;
sprintf(oldroot, "%s/%s/", root, container->rootfs); if (container_setup_init_layer(container, setup_dns) < 0) {
/* pivot_root won't work, see fprintf(stderr, "container sets up init layer failed\n");
* Documention/filesystem/ramfs-rootfs-initramfs.txt */
chroot(oldroot);
chdir("/");
if (container_setup_volume(container) < 0) {
fprintf(stderr, "container sets up voulme failed\n");
goto fail; goto fail;
} }
@@ -427,8 +612,11 @@ static int hyper_container_init(void *data)
goto fail; goto fail;
} }
if (container_setup_sysctl(container) < 0) { // ignore error of setup modules
fprintf(stderr, "container sets up sysctl failed\n"); container_setup_modules(container);
if (container_setup_volume(container) < 0) {
fprintf(stderr, "container sets up voulme failed\n");
goto fail; goto fail;
} }
@@ -437,33 +625,40 @@ static int hyper_container_init(void *data)
goto fail; goto fail;
} }
// manipulate the rootfs of the container/namespace: move the prepared path @rootfs to /
if (mount(rootfs, "/", NULL, MS_MOVE, NULL) < 0) {
perror("failed to move rootfs");
goto fail;
}
/* pivot_root won't work, see
* Documention/filesystem/ramfs-rootfs-initramfs.txt */
if (chroot(".") < 0) {
perror("failed to setup the root for the mount namepsace");
goto fail;
}
if (chdir("/") < 0) {
perror("failed chdir to the new root");
goto fail;
}
if (container_setup_sysctl(container) < 0) {
fprintf(stderr, "container sets up sysctl failed\n");
goto fail;
}
if (container_setup_workdir(container) < 0) { if (container_setup_workdir(container) < 0) {
fprintf(stderr, "container sets up work directory failed\n"); fprintf(stderr, "container sets up work directory failed\n");
goto fail; goto fail;
} }
container_unmount_oldroot("/.oldroot"); hyper_send_type(arg->pipe[1], READY);
fflush(NULL);
fflush(stdout); _exit(0);
if (container_setup_tty(arg->pipe[1], container) < 0) {
fprintf(stdout, "setup tty failed\n");
goto fail;
}
symlink("/proc/self/fd", "/dev/fd");
symlink("/proc/self/fd/0", "/dev/stdin");
symlink("/proc/self/fd/1", "/dev/stdout");
symlink("/proc/self/fd/2", "/dev/stderr");
execvp(container->exec.argv[0], container->exec.argv);
perror("exec container command failed");
_exit(-1);
fail: fail:
hyper_send_type(arg->pipe[1], ERROR); hyper_send_type(arg->pipe[1], ERROR);
_exit(-1); _exit(125);
} }
static int hyper_setup_pty(struct hyper_container *c) static int hyper_setup_pty(struct hyper_container *c)
@@ -472,8 +667,8 @@ static int hyper_setup_pty(struct hyper_container *c)
sprintf(root, "/tmp/hyper/%s/devpts/", c->id); sprintf(root, "/tmp/hyper/%s/devpts/", c->id);
if (hyper_mkdir(root) < 0) { if (hyper_mkdir(root, 0755) < 0) {
perror("make container pts directroy failed"); perror("make container pts directory failed");
return -1; return -1;
} }
@@ -483,33 +678,33 @@ static int hyper_setup_pty(struct hyper_container *c)
return -1; return -1;
} }
if (hyper_setup_exec_tty(&c->exec) < 0) {
fprintf(stderr, "setup container pts failed\n");
return -1;
}
return 0; return 0;
} }
int hyper_start_container(struct hyper_container *container, int hyper_setup_container(struct hyper_container *container, struct hyper_pod *pod)
int utsns, int ipcns, struct hyper_pod *pod)
{ {
int stacksize = getpagesize() * 4; int stacksize = getpagesize() * 42;
struct hyper_container_arg arg = { struct hyper_container_arg arg = {
.c = container, .c = container,
.utsns = utsns, .pod = pod,
.ipcns = ipcns,
.pipe = {-1, -1}, .pipe = {-1, -1},
.pipens = {-1, -1},
}; };
int flags = CLONE_NEWNS | SIGCHLD; int flags = CLONE_NEWNS | SIGCHLD;
char path[128]; char path[128];
uint32_t type;
void *stack; void *stack;
uint32_t type;
int pid; int pid;
if (container->image == NULL || container->exec.argv == NULL) { container->exec.pod = pod;
fprintf(stdout, "container root image %s, argv %p\n",
container->image, container->exec.argv); if (pipe2(arg.pipe, O_CLOEXEC) < 0 || pipe2(arg.pipens, O_CLOEXEC) < 0) {
perror("create pipe between pod init execcmd failed");
goto fail;
}
if (hyper_setup_container_portmapping(container, pod) < 0) {
perror("fail to setup port mapping for container");
goto fail; goto fail;
} }
@@ -518,66 +713,49 @@ int hyper_start_container(struct hyper_container *container,
goto fail; goto fail;
} }
if (pipe2(arg.pipe, O_CLOEXEC) < 0) {
perror("create pipe between pod init execcmd failed");
goto fail;
}
if (hyper_watch_exec_pty(&container->exec, pod) < 0) {
fprintf(stderr, "faile to watch container pty\n");
goto fail;
}
stack = malloc(stacksize); stack = malloc(stacksize);
if (stack == NULL) { if (stack == NULL) {
perror("fail to allocate stack for container init"); perror("fail to allocate stack for container init");
goto fail; goto fail;
} }
pid = clone(hyper_container_init, stack + stacksize, flags, &arg); pid = clone(hyper_setup_container_rootfs, stack + stacksize, flags, &arg);
free(stack); free(stack);
if (pid < 0) { if (pid < 0) {
perror("create child process failed"); perror("create child process failed");
goto fail; goto fail;
} }
sprintf(path, "/proc/%d/ns/mnt", pid);
sprintf(path, "/proc/%d/ns/mnt", pid);
container->ns = open(path, O_RDONLY | O_CLOEXEC); container->ns = open(path, O_RDONLY | O_CLOEXEC);
if (container->ns < 0) { if (container->ns < 0) {
perror("open container mount ns failed"); perror("open container mount ns failed");
goto fail; goto fail;
} }
hyper_send_type(arg.pipens[1], READY);
/* wait for ready message */ /* wait for ready message */
if (hyper_get_type(arg.pipe[0], &type) < 0 || type != READY) { if (hyper_get_type(arg.pipe[0], &type) < 0 || type != READY) {
fprintf(stderr, "wait for container started failed\n"); fprintf(stderr, "wait for setup container rootfs failed\n");
goto fail; goto fail;
} }
container->exec.pid = pid;
list_add_tail(&container->exec.list, &pod->exec_head);
container->exec.ref++;
close(arg.pipe[0]); close(arg.pipe[0]);
close(arg.pipe[1]); close(arg.pipe[1]);
close(arg.pipens[0]);
fprintf(stdout, "container %s,init pid %d,ref %d\n", container->id, pid, container->exec.ref); close(arg.pipens[1]);
return 0; return 0;
fail: fail:
close(container->ns);
container->ns = -1;
close(arg.pipe[0]); close(arg.pipe[0]);
close(arg.pipe[1]); close(arg.pipe[1]);
close(container->ns); close(arg.pipens[0]);
hyper_reset_event(&container->exec.e); close(arg.pipens[1]);
hyper_reset_event(&container->exec.errev);
container->ns = -1;
fprintf(stdout, "container %s init exit code %d\n", container->id, -1);
container->exec.code = -1;
container->exec.seq = 0;
container->exec.ref = 0;
return -1; return -1;
} }
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)
{ {
struct hyper_container *c; struct hyper_container *c;
@@ -594,7 +772,7 @@ struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id)
return NULL; return NULL;
} }
void hyper_cleanup_container(struct hyper_container *c) void hyper_cleanup_container(struct hyper_container *c, struct hyper_pod *pod)
{ {
char root[512]; char root[512];
@@ -603,6 +781,7 @@ void hyper_cleanup_container(struct hyper_container *c)
perror("umount devpts failed"); perror("umount devpts failed");
close(c->ns); close(c->ns);
hyper_cleanup_container_portmapping(c, pod);
hyper_free_container(c); hyper_free_container(c);
} }
@@ -611,7 +790,7 @@ void hyper_cleanup_containers(struct hyper_pod *pod)
struct hyper_container *c, *n; struct hyper_container *c, *n;
list_for_each_entry_safe(c, n, &pod->containers, list) list_for_each_entry_safe(c, n, &pod->containers, list)
hyper_cleanup_container(c); hyper_cleanup_container(c, pod);
pod->remains = 0; pod->remains = 0;
} }
+20 -16
View File
@@ -3,23 +3,20 @@
#include "exec.h" #include "exec.h"
struct env {
char *env;
char *value;
};
struct volume { struct volume {
char *device; char *device;
char *scsiaddr; 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 { struct sysctl {
@@ -27,33 +24,40 @@ struct sysctl {
char *value; 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 *scsiaddr; char *scsiaddr;
char *workdir;
char *fstype; char *fstype;
struct volume *vols; struct volume *vols;
struct env *envs;
struct fsmap *maps; struct fsmap *maps;
struct sysctl *sys; struct sysctl *sys;
struct port *ports;
int vols_num; int vols_num;
int envs_num;
int maps_num; int maps_num;
int sys_num; int sys_num;
int ns; int ports_num;
uint32_t code; int initialize;
struct list_head list;
struct hyper_exec exec;
}; };
struct hyper_pod; struct hyper_pod;
int hyper_start_container(struct hyper_container *container, int hyper_setup_container(struct hyper_container *container, struct hyper_pod *pod);
int utsns, int ipcns, struct hyper_pod *pod); struct hyper_container *hyper_find_container(struct hyper_pod *pod, const char *id);
struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id); void hyper_cleanup_container(struct hyper_container *container, struct hyper_pod *pod);
void hyper_cleanup_container(struct hyper_container *container);
void hyper_cleanup_containers(struct hyper_pod *pod); void hyper_cleanup_containers(struct hyper_pod *pod);
void hyper_free_container(struct hyper_container *c); void hyper_free_container(struct hyper_container *c);
+61 -140
View File
@@ -10,25 +10,25 @@
#include "hyper.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->rbuf.data); free(he->rbuf.data);
free(de->wbuf.data); free(he->wbuf.data);
close(de->fd); close(he->fd);
memset(de, 0, sizeof(*de)); memset(he, 0, sizeof(*he));
de->fd = -1; he->fd = -1;
} }
int hyper_init_event(struct hyper_event *de, struct hyper_event_ops *ops, void *arg) int hyper_init_event(struct hyper_event *he, struct hyper_event_ops *ops, void *arg)
{ {
struct hyper_buf *rbuf = &de->rbuf; struct hyper_buf *rbuf = &he->rbuf;
struct hyper_buf *wbuf = &de->wbuf; struct hyper_buf *wbuf = &he->wbuf;
memset(rbuf, 0, sizeof(*rbuf)); memset(rbuf, 0, sizeof(*rbuf));
memset(wbuf, 0, sizeof(*wbuf)); memset(wbuf, 0, sizeof(*wbuf));
de->ops = ops; he->ops = ops;
de->ptr = arg; he->ptr = arg;
rbuf->size = ops->rbuf_size; rbuf->size = ops->rbuf_size;
wbuf->size = ops->wbuf_size; wbuf->size = ops->wbuf_size;
@@ -51,22 +51,22 @@ int hyper_init_event(struct hyper_event *de, struct hyper_event_ops *ops, void *
return 0; return 0;
} }
int hyper_add_event(int efd, struct hyper_event *de, int flag) int hyper_add_event(int efd, struct hyper_event *he, int flag)
{ {
struct epoll_event event = { struct epoll_event event = {
.events = flag, .events = flag,
.data.ptr = de, .data.ptr = he,
}; };
de->flag = flag; he->flag = flag;
if (hyper_setfd_nonblock(de->fd) < 0) { 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;
} }
@@ -74,21 +74,21 @@ int hyper_add_event(int efd, struct hyper_event *de, int flag)
return 0; return 0;
} }
int hyper_modify_event(int efd, struct hyper_event *de, int flag) int hyper_modify_event(int efd, struct hyper_event *he, int flag)
{ {
struct epoll_event event = { struct epoll_event event = {
.events = flag, .events = flag,
.data.ptr = de, .data.ptr = he,
}; };
if (de->flag == flag) if (he->flag == flag)
return 0; return 0;
de->flag = flag; he->flag = flag;
fprintf(stdout, "%s modify event fd %d, %p, event %d\n", fprintf(stdout, "%s modify event fd %d, %p, event %d\n",
__func__, de->fd, de, flag); __func__, he->fd, he, flag);
if (epoll_ctl(efd, EPOLL_CTL_MOD, de->fd, &event) < 0) { if (epoll_ctl(efd, EPOLL_CTL_MOD, he->fd, &event) < 0) {
perror("epoll_ctl fd failed"); perror("epoll_ctl fd failed");
return -1; return -1;
} }
@@ -96,106 +96,34 @@ int hyper_modify_event(int efd, struct hyper_event *de, int flag)
return 0; return 0;
} }
static int hyper_getmsg_len(struct hyper_event *de, uint32_t *len) int hyper_requeue_event(int efd, struct hyper_event *ev)
{ {
struct hyper_buf *buf = &de->rbuf; struct epoll_event event = {
.events = ev->flag,
.data.ptr = ev,
};
if (buf->get < de->ops->len_offset + 4) if (epoll_ctl(efd, EPOLL_CTL_DEL, ev->fd, NULL) < 0) {
perror("epoll_ctl del fd failed");
return -1; return -1;
}
if (epoll_ctl(efd, EPOLL_CTL_ADD, ev->fd, &event) < 0) {
perror("epoll_ctl add fd failed");
return -1;
}
*len = hyper_get_be32(buf->data + de->ops->len_offset);
return 0; return 0;
} }
int hyper_event_read(struct hyper_event *de) int hyper_event_write(struct hyper_event *he, int efd)
{ {
struct hyper_buf *buf = &de->rbuf; struct hyper_buf *buf = &he->wbuf;
uint32_t len = 4;
uint8_t data[4];
int offset = de->ops->len_offset;
int end = offset + 4;
int size;
fprintf(stdout, "%s\n", __func__);
while (hyper_getmsg_len(de, &len) < 0) {
size = read(de->fd, buf->data + buf->get, end - buf->get);
if (size > 0) {
buf->get += size;
fprintf(stdout, "already read %" PRIu32 " bytes data\n",
buf->get);
if (de->ops->ack) {
/* control channel, need ack */
hyper_set_be32(data, size);
hyper_send_msg(de->fd, NEXT, 4, data);
}
continue;
}
if (errno == EINTR)
continue;
if (errno != EAGAIN && size != 0) {
perror("fail to read");
return -1;
}
return 0;
}
fprintf(stdout, "get length %" PRIu32"\n", len);
if (len > buf->size) {
fprintf(stderr, "get length %" PRIu32", too long\n", len);
return -1;
}
while (buf->get < len) {
size = read(de->fd, buf->data + buf->get, len - buf->get);
if (size > 0) {
buf->get += size;
fprintf(stdout, "read %d bytes data, total data %" PRIu32 "\n",
size, buf->get);
if (de->ops->ack) {
/* control channel, need ack */
hyper_set_be32(data, size);
hyper_send_msg(de->fd, NEXT, 4, data);
}
continue;
}
if (errno == EINTR)
continue;
if (errno != EAGAIN && size != 0) {
perror("fail to read");
return -1;
}
/* size == 0 : No one connect to qemu socket */
return 0;
}
/* get the whole data */
if (de->ops->handle(de, len) != 0)
return -1;
/* len: length of the already get new data */
buf->get -= len;
memmove(buf->data, buf->data + len, buf->get);
return 0;
}
int hyper_event_write(struct hyper_event *de)
{
struct hyper_buf *buf = &de->wbuf;
uint32_t len = 0; uint32_t len = 0;
int size = 0; int size = 0;
while (len < buf->get) { while (len < buf->get) {
size = write(de->fd, buf->data + len, buf->get - len); size = write(he->fd, buf->data + len, buf->get - len);
if (size <= 0) { if (size <= 0) {
if (errno == EINTR) if (errno == EINTR)
continue; continue;
@@ -210,49 +138,42 @@ int hyper_event_write(struct hyper_event *de)
memmove(buf->data, buf->data + len, buf->get); memmove(buf->data, buf->data + len, buf->get);
if (buf->get == 0) { if (buf->get == 0) {
hyper_modify_event(ctl.efd, de, EPOLLIN); hyper_modify_event(ctl.efd, he, he->flag & ~EPOLLOUT);
} }
return 0; return 0;
} }
void hyper_event_hup(struct hyper_event *de, int efd) void hyper_event_hup(struct hyper_event *he, int efd)
{ {
if (epoll_ctl(efd, EPOLL_CTL_DEL, de->fd, NULL) < 0) 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");
hyper_reset_event(de); hyper_reset_event(he);
} }
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, de %p, fd %d. ops %p\n", fprintf(stdout, "%s get event %d, he %p, fd %d. ops %p\n",
__func__, event->events, de, de->fd, de->ops); __func__, event->events, he, he->fd, he->ops);
/* do not handle hup event if have in event */ /* do not handle hup event if have in/out event */
if (event->events & EPOLLIN) { if ((event->events & EPOLLIN) && he->ops->read) {
fprintf(stdout, "%s event EPOLLIN, de %p, fd %d, %p\n", fprintf(stdout, "%s event EPOLLIN, he %p, fd %d, %p\n",
__func__, de, de->fd, de->ops); __func__, he, he->fd, he->ops);
if (de->ops->read(de) < 0) return he->ops->read(he, efd);
return -1; }
} else if (event->events & EPOLLHUP) { if ((event->events & EPOLLOUT) && he->ops->write) {
fprintf(stdout, "%s event EPOLLHUP, de %p, fd %d, %p\n", fprintf(stdout, "%s event EPOLLOUT, he %p, fd %d, %p\n",
__func__, de, de->fd, de->ops); __func__, he, he->fd, he->ops);
if (de->ops->hup) return he->ops->write(he, efd);
de->ops->hup(de, efd);
return 0;
} }
if (event->events & EPOLLOUT) { if ((event->events & EPOLLHUP) || (event->events & EPOLLERR)) {
fprintf(stdout, "%s event EPOLLOUT, de %p, fd %d, %p\n", fprintf(stdout, "%s event EPOLLHUP or EPOLLERR, he %p, fd %d, %x\n",
__func__, de, de->fd, de->ops); __func__, he, he->fd, event->events);
if (de->ops->write && de->ops->write(de) < 0) if (he->ops->hup)
return -1; he->ops->hup(he, efd);
}
if (event->events & EPOLLERR) {
fprintf(stderr, "get epoll err of not epool in event\n");
return -1;
} }
return 0; return 0;
+7 -7
View File
@@ -7,14 +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 (*write)(struct hyper_event *e); 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 rbuf_size;
int wbuf_size; int wbuf_size;
int len_offset;
int ack;
}; };
struct hyper_buf { struct hyper_buf {
@@ -32,13 +29,16 @@ struct hyper_event {
void *ptr; void *ptr;
}; };
#define FULL(buf) \
(buf->size - buf->get <= 12)
int hyper_add_event(int efd, struct hyper_event *de, int flag); 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_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,
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_read(struct hyper_event *de); int hyper_event_write(struct hyper_event *de, int efd);
int hyper_event_write(struct hyper_event *de);
#endif #endif
+467 -325
View File
File diff suppressed because it is too large Load Diff
+27 -15
View File
@@ -4,37 +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;
struct hyper_event errev;
char *id; struct hyper_event stdinev;
char **argv; struct hyper_event stdoutev;
int argc; struct hyper_event stderrev;
uint64_t seq;
uint64_t errseq;
int pid; int pid;
int ptyno; int ptyno;
int init; int init;
int ptyfd; int ptyfd;
int errfd; uint8_t close_stdin_request;
uint8_t code; uint8_t code;
uint8_t exit; uint8_t exit;
uint8_t ref; 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_handle_exec_exit(struct hyper_pod *pod, int pid, uint8_t code); int hyper_handle_exec_exit(struct hyper_pod *pod, int pid, uint8_t code);
int hyper_watch_exec_pty(struct hyper_exec *exec, struct hyper_pod *pod);
void hyper_cleanup_exec(struct hyper_pod *pod);
extern struct hyper_event_ops pts_ops;
#endif #endif
+41 -51
View File
@@ -2,45 +2,26 @@
#define _HYPER_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 */
RESERVED, #define SHARED_DIR "/tmp/hyper/shared"
STARTPOD,
GETPOD,
STOPPOD,
DESTROYPOD,
RESTARTCONTAINER,
EXECCMD,
CMDFINISHED,
READY,
ACK,
ERROR,
WINSIZE,
PING,
PODFINISHED,
NEXT,
WRITEFILE,
READFILE,
NEWCONTAINER,
KILLCONTAINER,
};
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 portmapping_white_list *portmap_white_lists;
char **dns; char **dns;
struct list_head containers; struct list_head containers;
struct list_head exec_head; struct list_head exec_head;
@@ -49,54 +30,63 @@ struct hyper_pod {
int init_pid; int init_pid;
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 d_num;
uint32_t type;
/* how many containers are running */ /* how many containers are running */
uint32_t remains; uint32_t remains;
uint8_t policy; int req_destroy;
int efd; int efd;
struct hyper_event sig; };
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_killer { struct file_command {
char *id;
int signal;
};
struct hyper_reader {
char *id; char *id;
char *file; char *file;
}; };
struct hyper_writter {
char *id;
char *file;
uint8_t *data;
int len;
};
struct hyper_ctl { struct hyper_ctl {
int efd; int efd;
struct hyper_event sig;
struct hyper_event tty; struct hyper_event tty;
struct hyper_event chan; struct hyper_event chan;
}; };
int hyper_mkdir(char *hyper_path); 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);
int hyper_start_containers(struct hyper_pod *pod);
void hyper_cleanup_pod(struct hyper_pod *pod); 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
+505 -551
View File
File diff suppressed because it is too large Load Diff
+146 -14
View File
@@ -11,6 +11,7 @@
#include "hyper.h" #include "hyper.h"
#include "util.h" #include "util.h"
#include "parse.h"
#include "../config.h" #include "../config.h"
void hyper_set_be32(uint8_t *buf, uint32_t val) void hyper_set_be32(uint8_t *buf, uint32_t val)
@@ -47,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;
@@ -98,7 +98,6 @@ int hyper_get_type(int fd, uint32_t *type)
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;
@@ -178,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);
@@ -191,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;
} }
@@ -429,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;
} }
@@ -512,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;
} }
@@ -555,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)
{ {
@@ -565,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");
@@ -577,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) {
@@ -603,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;
} }
@@ -621,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");
@@ -633,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) {
@@ -663,8 +729,8 @@ static int hyper_cleanup_interface(struct rtnl_handle *rth,
return 0; return 0;
} }
if (hyper_down_nic(rth, iface->ifindex) < 0) { if (hyper_down_nic(rth, ifindex) < 0) {
fprintf(stderr, "up device %d failed\n", iface->ifindex); fprintf(stderr, "up device %d failed\n", ifindex);
return -1; return -1;
} }
@@ -783,6 +849,69 @@ void hyper_cleanup_network(struct hyper_pod *pod)
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 hyper_setup_dns(struct hyper_pod *pod)
{ {
int i, fd, ret = -1; int i, fd, ret = -1;
@@ -827,6 +956,9 @@ void hyper_cleanup_dns(struct hyper_pod *pod)
{ {
int fd, i; int fd, i;
if (pod->dns == NULL)
return;
for (i = 0; i < pod->d_num; i++) { for (i = 0; i < pod->d_num; i++) {
free(pod->dns[i]); free(pod->dns[i]);
} }
+3 -10
View File
@@ -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,6 +38,8 @@ 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_setup_dns(struct hyper_pod *pod); int hyper_setup_dns(struct hyper_pod *pod);
void hyper_cleanup_dns(struct hyper_pod *pod); void hyper_cleanup_dns(struct hyper_pod *pod);
+561 -380
View File
File diff suppressed because it is too large Load Diff
+5 -3
View File
@@ -3,16 +3,18 @@
#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_kill_container(struct hyper_killer *killer, char *json, int length); int hyper_parse_file_command(struct file_command *cmd, char *json, int length);
int hyper_parse_write_file(struct hyper_writter *writter, char *json, int length);
int hyper_parse_read_file(struct hyper_reader *reader, char *json, int length);
struct hyper_container *hyper_parse_new_container(struct hyper_pod *pod, 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); 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
View File
File diff suppressed because it is too large Load Diff
+223
View File
@@ -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
+417
View File
@@ -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);
}
}
}
}
}
+23
View File
@@ -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
+267 -45
View File
@@ -9,11 +9,15 @@
#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/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 "util.h" #include "util.h"
#include "hyper.h" #include "hyper.h"
@@ -64,13 +68,34 @@ int hyper_list_dir(char *path)
return 0; return 0;
} }
int hyper_find_sd(char *prefix, char *addr, char **dev) { 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 **list;
struct dirent *dir; struct dirent *dir;
char path[512]; char path[512];
int i, num; int i, num;
sprintf(path, "%s/sys/class/scsi_disk/0:0:%s/device/block/", prefix, addr); sprintf(path, "/sys/class/scsi_disk/0:0:%s/device/block/", addr);
fprintf(stdout, "orig dev %s, scan path %s\n", *dev, path); fprintf(stdout, "orig dev %s, scan path %s\n", *dev, path);
num = scandir(path, &list, NULL, NULL); num = scandir(path, &list, NULL, NULL);
@@ -86,7 +111,6 @@ int hyper_find_sd(char *prefix, char *addr, char **dev) {
} }
fprintf(stdout, "%s get %s\n", path, dir->d_name); fprintf(stdout, "%s get %s\n", path, dir->d_name);
free(*dev);
*dev = strdup(dir->d_name); *dev = strdup(dir->d_name);
break; break;
} }
@@ -98,46 +122,218 @@ int hyper_find_sd(char *prefix, char *addr, char **dev) {
return 0; return 0;
} }
int hyper_mkdir(char *hyper_path) 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) void online_cpu(void)
@@ -219,13 +415,12 @@ int hyper_open_channel(char *channel, int mode)
{ {
struct termios term; struct termios term;
int fd = open(channel, O_RDWR | O_CLOEXEC | mode); int fd = open(channel, O_RDWR | O_CLOEXEC | mode);
fprintf(stdout, "open %s get %d\n", channel, fd);
if (fd < 0) { if (fd < 0) {
perror("fail to open channel device"); perror("fail to open channel device");
return -1; return -1;
} }
fprintf(stdout, "open %s get %d\n", channel, fd);
bzero(&term, sizeof(term)); bzero(&term, sizeof(term));
cfmakeraw(&term); cfmakeraw(&term);
@@ -316,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;
} }
@@ -342,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;
} }
@@ -369,16 +563,6 @@ int hyper_insmod(char *module)
} }
#endif #endif
int hyper_open_serial_dev(char *tty)
{
int fd = open(tty, O_RDWR | O_CLOEXEC | O_NOCTTY);
if (fd < 0)
perror("fail to open tty device");
return fd;
}
int hyper_setfd_cloexec(int fd) int hyper_setfd_cloexec(int fd)
{ {
int flags = fcntl(fd, F_GETFD); int flags = fcntl(fd, F_GETFD);
@@ -430,21 +614,6 @@ int hyper_setfd_nonblock(int fd)
return flags; return flags;
} }
int hyper_socketpair(int domain, int type, int protocol, int sv[2])
{
if (socketpair(domain, type, protocol, sv) < 0) {
perror("socketpair failed");
return -1;
}
if (hyper_setfd_cloexec(sv[0]) < 0 ||
hyper_setfd_cloexec(sv[1]) < 0) {
return -1;
}
return 0;
}
static void hyper_unmount_all(void) static void hyper_unmount_all(void)
{ {
FILE *mtab; FILE *mtab;
@@ -485,6 +654,8 @@ static 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();
@@ -492,7 +663,58 @@ static void hyper_unmount_all(void)
void hyper_shutdown() void hyper_shutdown()
{ {
hyper_send_msg_block(ctl.chan.fd, ACK, 0, NULL);
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;
}
+16 -5
View File
@@ -2,6 +2,8 @@
#define _UTIL_H_ #define _UTIL_H_
#include <stdio.h> #include <stdio.h>
#include <grp.h>
#include <pwd.h>
#include "../config.h" #include "../config.h"
struct hyper_pod; struct hyper_pod;
@@ -9,24 +11,33 @@ struct env;
#ifdef WITH_DEBUG #ifdef WITH_DEBUG
#define dprintf(fmt, ...) \ #define dprintf(fmt, ...) \
fprintf(stdout, fmt, ##_VA_ARGS__) fprintf(stdout, fmt, ##__VA_ARGS__)
#else #else
#define dprintf(fmr, ...) #define dprintf(fmr, ...)
#endif #endif
char *read_cmdline(void); char *read_cmdline(void);
int hyper_setup_env(struct env *envs, int num); int hyper_setup_env(struct env *envs, int num);
int hyper_find_sd(char *prefix, char *addr, char **dev); int hyper_find_sd(char *addr, char **dev);
int hyper_list_dir(char *path); int hyper_list_dir(char *path);
int hyper_copy_dir(char *src, char *dst);
void hyper_sync_time_hctosys();
void online_cpu(void); void online_cpu(void);
void online_memory(void); void online_memory(void);
int hyper_mkdir(char *path); 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_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);
int hyper_socketpair(int domain, int type, int protocol, int sv[2]); int hyper_socketpair(int domain, int type, int protocol, int sv[2]);
void hyper_shutdown(void); void hyper_shutdown();
int hyper_insmod(char *module); 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