├── .travis.yml ├── .travis_build_config.rb ├── .travis_build_config.rb.lock ├── LICENSE ├── README.md ├── example ├── dump.rb ├── restore.rb └── restore_child.rb ├── mrbgem.rake ├── mrblib └── mrb_criu.rb ├── src ├── mrb_criu.c └── mrb_criu.h ├── tasks ├── criu_a.patch └── staticify.rb └── test └── mrb_criu.rb /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | compiler: 3 | - gcc 4 | - clang 5 | before_install: 6 | - sudo apt-get -qq update 7 | install: 8 | - sudo apt-get -qq install rake bison git gperf 9 | before_script: 10 | - cd ../ 11 | - git clone https://github.com/mruby/mruby.git 12 | - cd mruby 13 | - cp -fp ../mruby-criu/.travis_build_config.rb build_config.rb 14 | script: 15 | - make all test 16 | -------------------------------------------------------------------------------- /.travis_build_config.rb: -------------------------------------------------------------------------------- 1 | MRuby::Build.new do |conf| 2 | toolchain :gcc 3 | 4 | # If you want to link libcriu.a statically to your app, uncomment 5 | # conf.cc.defines << "MRB_CRIU_USE_STATIC" 6 | 7 | conf.gembox 'default' 8 | conf.gem '../mruby-criu' 9 | conf.cc.defines << "MRB_CRIU_USE_STATIC" 10 | end 11 | -------------------------------------------------------------------------------- /.travis_build_config.rb.lock: -------------------------------------------------------------------------------- 1 | --- 2 | mruby_version: 3 | version: 2.1.0 4 | release_no: 20100 5 | git_commit: 57a56ddaa26d1bb7d67c8dde435b2e08dc17290f 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | mruby-criu 2 | 3 | Copyright (c) MATSUMOTO Ryosuke 2014 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | [ MIT license: http://www.opensource.org/licenses/mit-license.php ] 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mruby-criu 2 | [CRIU, Checkpoint Restart In Userspace for Linux](http://criu.org/Main_Page), binding for mruby. 3 | ## install by mrbgems 4 | - add conf.gem line to `build_config.rb` 5 | 6 | ```ruby 7 | MRuby::Build.new do |conf| 8 | 9 | # ... (snip) ... 10 | 11 | conf.gem :git => 'https://github.com/matsumoto-r/mruby-criu.git' 12 | end 13 | ``` 14 | ## Dump and Restore Process 15 | ### Isolated process run 16 | ##### loop.sh 17 | ```bash 18 | #!/bin/bash 19 | cont=0 20 | while :; do 21 | sleep 1 22 | cont=`expr $cont + 1` 23 | echo $cont 24 | done 25 | ``` 26 | ##### run 27 | ```bash 28 | setsid ./loop.sh < /dev/null &> loop_log.txt & 29 | ``` 30 | ##### get pid 31 | ```bash 32 | ps -C loop.sh 33 | PID TTY TIME CMD 34 | 4823 ? 00:00:00 loop.sh 35 | [1]+ Done setsid ./loop.sh < /dev/null &>loop_log.txt 36 | ``` 37 | ##### check log 38 | ```bash 39 | tail -f loop_log.txt 40 | 1 41 | 2 42 | 3 43 | ... 44 | ``` 45 | ### Dump(Checkpoint) 46 | ```ruby 47 | socket = "/var/run/criu_service.socket" 48 | images = "/tmp/dump_test" 49 | log = "dump.log" 50 | pid = 4823 51 | 52 | c = CRIU.new 53 | c.set_pid pid 54 | c.set_images_dir images 55 | c.set_service_address socket 56 | c.set_log_file log 57 | 58 | c.dump 59 | ``` 60 | ##### dump loop.sh 61 | ``` 62 | ./bin/mruby dump.rb 63 | ``` 64 | then, ``loop.sh`` was killed. 65 | ```bash 66 | tail -f loop_log.txt 67 | 1 68 | 2 69 | 3 70 | 71 | (stopped) 72 | ``` 73 | ### Restore 74 | ```ruby 75 | socket = "/var/run/criu_service.socket" 76 | images = "/tmp/dump_test" 77 | log = "restore.log" 78 | 79 | c = CRIU.new 80 | c.set_service_address socket 81 | c.set_images_dir images 82 | c.set_log_file log 83 | 84 | c.restore 85 | ``` 86 | ##### restore loop.sh 87 | ``` 88 | ./bin/mruby restore.rb 89 | ``` 90 | then, loop.sh was restored 91 | ```bash 92 | tail -f loop_log.txt 93 | (restored) 94 | 4 95 | 5 96 | 6 97 | ... 98 | ``` 99 | ## License 100 | under the MIT License: 101 | - see LICENSE file 102 | -------------------------------------------------------------------------------- /example/dump.rb: -------------------------------------------------------------------------------- 1 | socket = "/var/run/criu_service.socket" 2 | images = "/var/cache/criu_dump" 3 | log = "dump.log" 4 | # need iij/mruby-env 5 | pid = ENV["PID"].to_i 6 | 7 | c = CRIU.new 8 | p c.set_pid pid 9 | p c.set_images_dir images 10 | p c.set_service_address socket 11 | #p c.set_ext_unix_sk true 12 | #p c.set_tcp_established true 13 | p c.set_log_file log 14 | 15 | p c.dump 16 | -------------------------------------------------------------------------------- /example/restore.rb: -------------------------------------------------------------------------------- 1 | socket = "/var/run/criu_service.socket" 2 | images = "/var/cache/criu_dump" 3 | log = "restore.log" 4 | 5 | c = CRIU.new 6 | p c.set_service_address socket 7 | p c.set_images_dir images 8 | p c.set_log_file log 9 | #p c.set_ext_unix_sk true 10 | #p c.set_tcp_established true 11 | 12 | p c.restore 13 | -------------------------------------------------------------------------------- /example/restore_child.rb: -------------------------------------------------------------------------------- 1 | # swrk mode example 2 | 3 | images = "/tmp/criu/images" 4 | log = "-" 5 | 6 | c = CRIU.new 7 | p c.set_service_binary "/usr/local/sbin/criu" 8 | p c.set_images_dir images 9 | p c.set_log_file log 10 | p c.set_shell_job true 11 | 12 | # Can wait restored process here / when using patched criu... 13 | p(Process.waitpid2 c.restore_child) 14 | -------------------------------------------------------------------------------- /mrbgem.rake: -------------------------------------------------------------------------------- 1 | module CRIU 2 | unless CRIU.const_defined? :CRIU_VERSION 3 | CRIU_VERSION = "3.13" 4 | end 5 | end 6 | 7 | require_relative 'tasks/staticify' 8 | 9 | MRuby::Gem::Specification.new('mruby-criu') do |spec| 10 | spec.license = 'MIT' 11 | spec.authors = 'MATSUMOTO Ryosuke' 12 | 13 | if spec.build.cc.defines.flatten.include?("MRB_CRIU_USE_STATIC") 14 | spec.extend CRIU::Staticify 15 | spec.bundle_libcriu 16 | else 17 | spec.linker.libraries << 'criu' 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /mrblib/mrb_criu.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matsumotory/mruby-criu/d6660ece5148ba9759339b6f61797f7ad12fea73/mrblib/mrb_criu.rb -------------------------------------------------------------------------------- /src/mrb_criu.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** mrb_criu.c - CRIU class 3 | ** 4 | ** Copyright (c) MATSUMOTO Ryosuke 2014 5 | ** 6 | ** See Copyright Notice in LICENSE 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "mruby.h" 17 | #include "mruby/data.h" 18 | #include "mruby/class.h" 19 | #include "mrb_criu.h" 20 | 21 | #define DONE mrb_gc_arena_restore(mrb, 0); 22 | 23 | typedef struct { 24 | char *socket_file; 25 | char *images_dir; 26 | char *work_dir; 27 | mrb_int pid; 28 | bool leave_running; 29 | bool evasive_devices; 30 | bool shell_job; 31 | bool tcp_established; 32 | bool ext_unix_sk; 33 | bool file_locks; 34 | mrb_int log_level; 35 | mrb_int images_fd; 36 | mrb_int work_fd; 37 | char *log_file; 38 | } mrb_criu_data; 39 | 40 | static void mrb_criu_data_free(mrb_state *mrb, void *p) 41 | { 42 | mrb_criu_data *data = (mrb_criu_data *)p; 43 | close(data->images_fd); 44 | close(data->work_fd); 45 | mrb_free(mrb, data); 46 | } 47 | 48 | static const struct mrb_data_type mrb_criu_data_type = { 49 | "mrb_criu_data", mrb_criu_data_free, 50 | }; 51 | 52 | static void mrb_criu_error(mrb_state *mrb, int ret) 53 | { 54 | switch (ret) { 55 | case -EBADE: 56 | mrb_raise(mrb, E_RUNTIME_ERROR, "RPC has returned fail"); 57 | case -ECONNREFUSED: 58 | mrb_raise(mrb, E_RUNTIME_ERROR, "Unable to connect to CRIU"); 59 | case -ECOMM: 60 | mrb_raise(mrb, E_RUNTIME_ERROR, "Unable to send/recv msg to/from CRIU"); 61 | case -EINVAL: 62 | mrb_raise(mrb, E_RUNTIME_ERROR, "CRIU doesn't support this type of request." 63 | "You should probably update CRIU"); 64 | case -EBADMSG: 65 | mrb_raise(mrb, E_RUNTIME_ERROR, "Unexpected response from CRIU." 66 | "You should probably update CRIU"); 67 | default: 68 | mrb_raise(mrb, E_RUNTIME_ERROR, "Unknown error type code." 69 | "You should probably update CRIU"); 70 | } 71 | } 72 | 73 | static mrb_value mrb_criu_init(mrb_state *mrb, mrb_value self) 74 | { 75 | mrb_criu_data *data; 76 | 77 | data = (mrb_criu_data *)DATA_PTR(self); 78 | if (data) { 79 | mrb_free(mrb, data); 80 | } 81 | DATA_TYPE(self) = &mrb_criu_data_type; 82 | DATA_PTR(self) = NULL; 83 | 84 | data = (mrb_criu_data *)mrb_malloc(mrb, sizeof(mrb_criu_data)); 85 | data->socket_file = NULL; 86 | data->images_dir = NULL; 87 | data->work_dir = NULL; 88 | data->log_level = -1; 89 | data->log_file = NULL; 90 | DATA_PTR(self) = data; 91 | 92 | criu_init_opts(); 93 | 94 | return self; 95 | } 96 | 97 | static mrb_value mrb_criu_dump(mrb_state *mrb, mrb_value self) 98 | { 99 | int ret; 100 | ret = criu_dump(); 101 | if (ret < 0) { 102 | mrb_criu_error(mrb, ret); 103 | } 104 | return mrb_fixnum_value(ret); 105 | } 106 | 107 | static mrb_value mrb_criu_restore(mrb_state *mrb, mrb_value self) 108 | { 109 | int ret; 110 | 111 | ret = criu_restore(); 112 | if (ret < 0) { 113 | mrb_criu_error(mrb, ret); 114 | } 115 | return mrb_fixnum_value(ret); 116 | } 117 | 118 | static mrb_value mrb_criu_restore_child(mrb_state *mrb, mrb_value self) 119 | { 120 | int ret; 121 | ret = criu_restore_child(); 122 | if (ret < 0) { 123 | mrb_criu_error(mrb, ret); 124 | } 125 | return mrb_fixnum_value(ret); 126 | } 127 | 128 | static mrb_value mrb_criu_check(mrb_state *mrb, mrb_value self) 129 | { 130 | int ret; 131 | ret = criu_check(); 132 | if (ret < 0) { 133 | mrb_criu_error(mrb, ret); 134 | } 135 | return mrb_fixnum_value(ret); 136 | } 137 | 138 | static mrb_value mrb_criu_set_service_address(mrb_state *mrb, mrb_value self) 139 | { 140 | mrb_criu_data *data = DATA_PTR(self); 141 | char *socket_file; 142 | 143 | mrb_get_args(mrb, "z", &socket_file); 144 | 145 | criu_set_service_address(socket_file); 146 | data->socket_file = socket_file; 147 | 148 | return mrb_str_new_cstr(mrb, data->socket_file); 149 | } 150 | 151 | static mrb_value mrb_criu_set_images_dir(mrb_state *mrb, mrb_value self) 152 | { 153 | mrb_criu_data *data = DATA_PTR(self); 154 | char *images_dir; 155 | int fd; 156 | 157 | mrb_get_args(mrb, "z", &images_dir); 158 | fd = open(images_dir, O_DIRECTORY); 159 | if (fd == -1) { 160 | mrb_raise(mrb, E_ARGUMENT_ERROR, "not found image directory."); 161 | } 162 | 163 | criu_set_images_dir_fd(fd); 164 | data->images_dir = images_dir; 165 | data->images_fd = fd; 166 | 167 | return mrb_fixnum_value(data->images_fd); 168 | } 169 | 170 | static mrb_value mrb_criu_set_work_dir(mrb_state *mrb, mrb_value self) 171 | { 172 | mrb_criu_data *data = DATA_PTR(self); 173 | char *work_dir; 174 | mrb_int fd; 175 | 176 | mrb_get_args(mrb, "z", &work_dir); 177 | fd = open(work_dir, O_DIRECTORY); 178 | if (fd == -1) { 179 | mrb_raise(mrb, E_ARGUMENT_ERROR, "not found work directory."); 180 | } 181 | 182 | criu_set_work_dir_fd(fd); 183 | data->work_dir = work_dir; 184 | data->work_fd = fd; 185 | 186 | return mrb_fixnum_value(data->work_fd); 187 | } 188 | 189 | static mrb_value mrb_criu_set_pid(mrb_state *mrb, mrb_value self) 190 | { 191 | mrb_criu_data *data = DATA_PTR(self); 192 | mrb_int pid; 193 | 194 | mrb_get_args(mrb, "i", &pid); 195 | criu_set_pid(pid); 196 | data->pid = pid; 197 | 198 | return mrb_fixnum_value(pid); 199 | } 200 | 201 | static mrb_value mrb_criu_set_shell_job(mrb_state *mrb, mrb_value self) 202 | { 203 | mrb_criu_data *data = DATA_PTR(self); 204 | mrb_bool shell_job; 205 | 206 | mrb_get_args(mrb, "b", &shell_job); 207 | criu_set_shell_job(shell_job); 208 | data->shell_job = shell_job; 209 | 210 | return mrb_bool_value(data->shell_job); 211 | } 212 | 213 | static mrb_value mrb_criu_set_tcp_established(mrb_state *mrb, mrb_value self) 214 | { 215 | mrb_criu_data *data = DATA_PTR(self); 216 | mrb_bool tcp_established; 217 | 218 | mrb_get_args(mrb, "b", &tcp_established); 219 | criu_set_tcp_established(tcp_established); 220 | data->tcp_established = tcp_established; 221 | 222 | return mrb_bool_value(data->tcp_established); 223 | } 224 | 225 | static mrb_value mrb_criu_set_ext_unix_sk(mrb_state *mrb, mrb_value self) 226 | { 227 | mrb_criu_data *data = DATA_PTR(self); 228 | mrb_bool ext_unix_sk; 229 | 230 | mrb_get_args(mrb, "b", &ext_unix_sk); 231 | criu_set_ext_unix_sk(ext_unix_sk); 232 | data->ext_unix_sk = ext_unix_sk; 233 | 234 | return mrb_bool_value(data->ext_unix_sk); 235 | } 236 | 237 | static mrb_value mrb_criu_set_leave_running(mrb_state *mrb, mrb_value self) 238 | { 239 | mrb_criu_data *data = DATA_PTR(self); 240 | mrb_bool leave_running; 241 | 242 | mrb_get_args(mrb, "b", &leave_running); 243 | criu_set_leave_running(leave_running); 244 | data->leave_running = leave_running; 245 | 246 | return mrb_bool_value(data->leave_running); 247 | } 248 | 249 | static mrb_value mrb_criu_set_evasive_devices(mrb_state *mrb, mrb_value self) 250 | { 251 | mrb_criu_data *data = DATA_PTR(self); 252 | mrb_bool evasive_devices; 253 | 254 | mrb_get_args(mrb, "b", &evasive_devices); 255 | criu_set_evasive_devices(evasive_devices); 256 | data->evasive_devices= evasive_devices; 257 | 258 | return mrb_bool_value(data->evasive_devices); 259 | } 260 | 261 | static mrb_value mrb_criu_set_log_file(mrb_state *mrb, mrb_value self) 262 | { 263 | mrb_criu_data *data = DATA_PTR(self); 264 | char *log_file; 265 | 266 | mrb_get_args(mrb, "z", &log_file); 267 | criu_set_log_file(log_file); 268 | data->log_file = log_file; 269 | 270 | if (data->log_level == -1) { 271 | data->log_level = 4; 272 | criu_set_log_level(data->log_level); 273 | } 274 | 275 | return mrb_str_new_cstr(mrb, data->log_file); 276 | } 277 | 278 | static mrb_value mrb_criu_set_log_level(mrb_state *mrb, mrb_value self) 279 | { 280 | mrb_criu_data *data = DATA_PTR(self); 281 | mrb_int log_level; 282 | 283 | mrb_get_args(mrb, "i", &log_level); 284 | criu_set_log_level(log_level); 285 | data->log_level = log_level; 286 | 287 | return mrb_fixnum_value(data->log_level); 288 | } 289 | 290 | static mrb_value mrb_criu_set_service_binary(mrb_state *mrb, mrb_value self) 291 | { 292 | char *bin; 293 | 294 | mrb_get_args(mrb, "z", &bin); 295 | criu_set_service_binary(bin); 296 | 297 | return mrb_str_new_cstr(mrb, bin); 298 | } 299 | 300 | static mrb_value mrb_criu_add_external(mrb_state *mrb, mrb_value self) 301 | { 302 | char *external; 303 | 304 | mrb_get_args(mrb, "z", &external); 305 | criu_add_external(external); 306 | 307 | return mrb_str_new_cstr(mrb, external); 308 | } 309 | 310 | void mrb_mruby_criu_gem_init(mrb_state *mrb) 311 | { 312 | struct RClass *criu; 313 | criu = mrb_define_class(mrb, "CRIU", mrb->object_class); 314 | MRB_SET_INSTANCE_TT(criu, MRB_TT_DATA); 315 | 316 | mrb_define_method(mrb, criu, "initialize", mrb_criu_init, MRB_ARGS_NONE()); 317 | mrb_define_method(mrb, criu, "dump", mrb_criu_dump, MRB_ARGS_NONE()); 318 | mrb_define_method(mrb, criu, "restore", mrb_criu_restore, MRB_ARGS_NONE()); 319 | mrb_define_method(mrb, criu, "restore_child", mrb_criu_restore_child, MRB_ARGS_NONE()); 320 | mrb_define_method(mrb, criu, "check", mrb_criu_check, MRB_ARGS_NONE()); 321 | mrb_define_method(mrb, criu, "set_service_address", mrb_criu_set_service_address, MRB_ARGS_REQ(1)); 322 | mrb_define_method(mrb, criu, "set_images_dir", mrb_criu_set_images_dir, MRB_ARGS_REQ(1)); 323 | mrb_define_method(mrb, criu, "set_work_dir", mrb_criu_set_work_dir, MRB_ARGS_REQ(1)); 324 | mrb_define_method(mrb, criu, "set_pid", mrb_criu_set_pid, MRB_ARGS_REQ(1)); 325 | mrb_define_method(mrb, criu, "set_shell_job", mrb_criu_set_shell_job, MRB_ARGS_REQ(1)); 326 | mrb_define_method(mrb, criu, "set_tcp_established", mrb_criu_set_tcp_established, MRB_ARGS_REQ(1)); 327 | mrb_define_method(mrb, criu, "set_ext_unix_sk", mrb_criu_set_ext_unix_sk, MRB_ARGS_REQ(1)); 328 | mrb_define_method(mrb, criu, "set_leave_running", mrb_criu_set_leave_running, MRB_ARGS_REQ(1)); 329 | mrb_define_method(mrb, criu, "set_evasive_devices", mrb_criu_set_evasive_devices, MRB_ARGS_REQ(1)); 330 | mrb_define_method(mrb, criu, "set_log_file", mrb_criu_set_log_file, MRB_ARGS_REQ(1)); 331 | mrb_define_method(mrb, criu, "set_log_level", mrb_criu_set_log_level, MRB_ARGS_REQ(1)); 332 | mrb_define_method(mrb, criu, "set_service_binary", mrb_criu_set_service_binary, MRB_ARGS_REQ(1)); 333 | mrb_define_method(mrb, criu, "add_external", mrb_criu_add_external, MRB_ARGS_REQ(1)); 334 | DONE; 335 | } 336 | 337 | void mrb_mruby_criu_gem_final(mrb_state *mrb) 338 | { 339 | } 340 | -------------------------------------------------------------------------------- /src/mrb_criu.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** mrb_criu.h - CRIU class 3 | ** 4 | ** See Copyright Notice in LICENSE 5 | */ 6 | 7 | #ifndef MRB_CRIU_H 8 | #define MRB_CRIU_H 9 | 10 | void mrb_mruby_criu_gem_init(mrb_state *mrb); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /tasks/criu_a.patch: -------------------------------------------------------------------------------- 1 | diff --git a/lib/Makefile b/lib/Makefile 2 | index 9463284..1facc25 100644 3 | --- a/lib/Makefile 4 | +++ b/lib/Makefile 5 | @@ -1,4 +1,5 @@ 6 | CRIU_SO := libcriu.so 7 | +CRIU_A := libcriu.a 8 | UAPI_HEADERS := lib/c/criu.h images/rpc.proto 9 | 10 | # 11 | @@ -19,6 +20,9 @@ ldflags-so += -lprotobuf-c 12 | lib/c/$(CRIU_SO): lib/c/built-in.o 13 | $(call msg-link, $@) 14 | $(Q) $(CC) -shared $(cflags-so) -o $@ $^ $(ldflags-so) $(LDFLAGS) 15 | +lib/c/$(CRIU_A): lib/c/built-in.o 16 | + $(call msg-link, $@) 17 | + ar rcs $@ $^ 18 | lib-c: lib/c/$(CRIU_SO) 19 | .PHONY: lib-c 20 | 21 | -------------------------------------------------------------------------------- /tasks/staticify.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | require 'open3' 3 | 4 | module CRIU::Staticify 5 | PATCH_PATH = File.expand_path(File.dirname(__FILE__) + '/criu_a.patch') 6 | 7 | def run_command env, command 8 | STDOUT.sync = true 9 | puts "EXEC\t[mruby-criu] #{command}" 10 | Open3.popen2e(env, command) do |stdin, stdout, thread| 11 | print stdout.read 12 | fail "#{command} failed" if thread.value != 0 13 | end 14 | end 15 | 16 | def bundle_libcriu 17 | version = CRIU::CRIU_VERSION 18 | tarball_url = "https://github.com/checkpoint-restore/criu/archive/v#{version}.tar.gz" 19 | 20 | def criu_dir(b); (ENV["CRIU_TMP_DIR"] || "#{b.build_dir}/vendor/libcriu"); end 21 | def libcriu_dir(b); "#{criu_dir(b)}/lib/c"; end 22 | def libcriu_header(b); "#{criu_dir(b)}/lib/c/criu.h"; end 23 | def libcriu_a(b); libfile "#{criu_dir(b)}/lib/c/libcriu"; end 24 | 25 | task :clean do 26 | FileUtils.rm_rf [libcriu_dir(build)] 27 | end 28 | 29 | file libcriu_header(build) do 30 | unless File.exist? libcriu_dir(build) 31 | tmpdir = '/tmp' 32 | run_command ENV, "rm -rf #{tmpdir}/libcriu-#{version}" 33 | run_command ENV, "mkdir -p #{File.dirname(criu_dir(build))} #{File.dirname(criu_dir(build))}" 34 | run_command ENV, "curl -sL #{tarball_url} | tar -xz -f - -C #{tmpdir}" 35 | run_command ENV, "mv -f #{tmpdir}/criu-#{version} #{criu_dir(build)}" 36 | if CRIU::CRIU_VERSION != '3.13' 37 | run_command ENV, "cd #{criu_dir(build)} && patch -p1 < #{PATCH_PATH}" 38 | end 39 | run_command ENV, "cd #{File.dirname(libcriu_a(build))} && ln -s . criu" # resolve include 40 | end 41 | end 42 | 43 | file libcriu_a(build) => libcriu_header(build) do 44 | unless File.exist?(libcriu_a(build)) 45 | Dir.chdir criu_dir(build) do 46 | ENV["LD_FLAGS"] = "-lprotobuf-c" 47 | run_command ENV, "make lib/c/libcriu.a" 48 | run_command ENV, "cp criu/include/version.h #{File.dirname(libcriu_a(build))}" 49 | end 50 | end 51 | end 52 | 53 | libmruby_a = libfile("#{build.build_dir}/lib/libmruby") 54 | file libmruby_a => libcriu_a(build) 55 | 56 | self.cc.include_paths << File.dirname(libcriu_header(build)) 57 | self.linker.library_paths << File.dirname(libcriu_a(build)) 58 | # NOTE: order is important!! 59 | self.linker.libraries << 'criu' 60 | self.linker.libraries << 'protobuf-c' 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /test/mrb_criu.rb: -------------------------------------------------------------------------------- 1 | ## 2 | ## CRIU Test 3 | ## 4 | 5 | #assert("CRIU#hello") do 6 | # t = CRIU.new "hello" 7 | # assert_equal("hello", t.hello) 8 | #end 9 | # 10 | #assert("CRIU#bye") do 11 | # t = CRIU.new "hello" 12 | # assert_equal("hello bye", t.bye) 13 | #end 14 | # 15 | #assert("CRIU.hi") do 16 | # assert_equal("hi!!", CRIU.hi) 17 | #end 18 | --------------------------------------------------------------------------------