ruby-lxc 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/lxc/extconf.rb +7 -0
- data/ext/lxc/lxc.c +545 -173
- data/lib/lxc/version.rb +1 -1
- metadata +2 -2
data/ext/lxc/extconf.rb
CHANGED
@@ -3,5 +3,12 @@ require 'mkmf'
|
|
3
3
|
abort 'missing liblxc' unless find_library('lxc', 'lxc_container_new')
|
4
4
|
abort 'missing lxc/lxccontainer.h' unless have_header('lxc/lxccontainer.h')
|
5
5
|
|
6
|
+
def add_define(name)
|
7
|
+
$defs.push("-D#{name}")
|
8
|
+
end
|
9
|
+
|
10
|
+
add_define "HAVE_RB_THREAD_CALL_WITHOUT_GVL" if have_func('rb_thread_call_without_gvl')
|
11
|
+
add_define "HAVE_RB_THREAD_BLOCKING_REGION" if have_func('rb_thread_blocking_region')
|
12
|
+
|
6
13
|
$CFLAGS += " -Wall #{ENV['CFLAGS']}"
|
7
14
|
create_makefile('lxc/lxc')
|
data/ext/lxc/lxc.c
CHANGED
@@ -3,13 +3,46 @@
|
|
3
3
|
#include <linux/sched.h> /* for CLONE_* constants */
|
4
4
|
#include <lxc/lxccontainer.h>
|
5
5
|
#include <lxc/attach_options.h>
|
6
|
+
#include <signal.h>
|
6
7
|
#include <stdint.h>
|
7
8
|
#include <string.h>
|
8
9
|
|
9
10
|
#define SYMBOL(s) ID2SYM(rb_intern(s))
|
10
11
|
|
12
|
+
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
13
|
+
/* Defined in Ruby, but not in all Ruby versions' header files */
|
14
|
+
extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
15
|
+
rb_unblock_function_t *ubf,
|
16
|
+
void *data2);
|
17
|
+
|
18
|
+
#define RETURN_WITHOUT_GVL_TYPE void *
|
19
|
+
#define RETURN_WITHOUT_GVL(x) return (void *)(intptr_t)(x)
|
20
|
+
#define RELEASING_GVL(func, arg) \
|
21
|
+
(int)(intptr_t)rb_thread_call_without_gvl(func, arg, NULL, NULL)
|
22
|
+
#define RELEASING_GVL2(func, arg, killfunc, killarg) \
|
23
|
+
(int)(intptr_t)rb_thread_call_without_gvl(func, arg, killfunc, killarg)
|
24
|
+
#define RELEASING_GVL_VOID(func, arg) \
|
25
|
+
rb_thread_call_without_gvl(func, arg, NULL, NULL)
|
26
|
+
#elif defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
27
|
+
#define RETURN_WITHOUT_GVL_TYPE VALUE
|
28
|
+
#define RETURN_WITHOUT_GVL(x) return INT2NUM(x)
|
29
|
+
#define RELEASING_GVL(func, arg) \
|
30
|
+
NUM2INT(rb_thread_blocking_region(func, arg, NULL, NULL))
|
31
|
+
#define RELEASING_GVL2(func, arg, killfunc, killarg) \
|
32
|
+
NUM2INT(rb_thread_blocking_region(func, arg, killfunc, killarg))
|
33
|
+
#define RELEASING_GVL_VOID(func, arg) \
|
34
|
+
rb_thread_blocking_region(func, arg, NULL, NULL)
|
35
|
+
#else
|
36
|
+
#define RETURN_WITHOUT_GVL_TYPE int
|
37
|
+
#define RETURN_WITHOUT_GVL(x) return x
|
38
|
+
#define RELEASING_GVL(func, arg) func(arg)
|
39
|
+
#define RELEASING_GVL_VOID(func, arg) func(arg)
|
40
|
+
#define RELEASING_GVL2(func, arg, killfunc, killarg) func(arg)
|
41
|
+
#endif
|
42
|
+
|
11
43
|
extern int lxc_wait_for_pid_status(pid_t pid);
|
12
44
|
extern long lxc_config_parse_arch(const char *arch);
|
45
|
+
extern const char *lxc_strerror(int error);
|
13
46
|
|
14
47
|
static VALUE Container;
|
15
48
|
static VALUE Error;
|
@@ -161,6 +194,32 @@ lxc_version(VALUE self)
|
|
161
194
|
return rb_str_new2(lxc_get_version());
|
162
195
|
}
|
163
196
|
|
197
|
+
struct list_containers_without_gvl_args {
|
198
|
+
int active;
|
199
|
+
int defined;
|
200
|
+
char *config;
|
201
|
+
char **names;
|
202
|
+
};
|
203
|
+
|
204
|
+
static RETURN_WITHOUT_GVL_TYPE
|
205
|
+
list_containers_without_gvl(void *args_void)
|
206
|
+
{
|
207
|
+
struct list_containers_without_gvl_args *args =
|
208
|
+
(struct list_containers_without_gvl_args *)args_void;
|
209
|
+
int num_containers = 0;
|
210
|
+
args->names = NULL;
|
211
|
+
if (args->active && args->defined) {
|
212
|
+
num_containers = list_all_containers(args->config, &args->names, NULL);
|
213
|
+
} else if (args->active) {
|
214
|
+
num_containers =
|
215
|
+
list_active_containers(args->config, &args->names, NULL);
|
216
|
+
} else if (args->defined) {
|
217
|
+
num_containers =
|
218
|
+
list_defined_containers(args->config, &args->names, NULL);
|
219
|
+
}
|
220
|
+
RETURN_WITHOUT_GVL(num_containers);
|
221
|
+
}
|
222
|
+
|
164
223
|
/*
|
165
224
|
* call-seq:
|
166
225
|
* LXC.list_containers([opts])
|
@@ -175,36 +234,33 @@ static VALUE
|
|
175
234
|
lxc_list_containers(int argc, VALUE *argv, VALUE self)
|
176
235
|
{
|
177
236
|
int i, num_containers;
|
178
|
-
int active, defined;
|
179
|
-
char *config;
|
180
|
-
char **names;
|
181
237
|
VALUE rb_active, rb_defined, rb_config;
|
182
238
|
VALUE rb_opts;
|
183
239
|
VALUE rb_containers;
|
240
|
+
struct list_containers_without_gvl_args args;
|
184
241
|
|
185
242
|
rb_scan_args(argc, argv, "01", &rb_opts);
|
186
243
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
244
|
+
args.active = 1;
|
245
|
+
args.defined = 1;
|
246
|
+
args.config = NULL;
|
247
|
+
|
248
|
+
if (!NIL_P(rb_opts)) {
|
192
249
|
Check_Type(rb_opts, T_HASH);
|
250
|
+
|
193
251
|
rb_active = rb_hash_aref(rb_opts, SYMBOL("active"));
|
194
|
-
|
252
|
+
if (!NIL_P(rb_active))
|
253
|
+
args.active = rb_active != Qfalse;
|
254
|
+
|
195
255
|
rb_defined = rb_hash_aref(rb_opts, SYMBOL("defined"));
|
196
|
-
|
256
|
+
if (!NIL_P(rb_defined))
|
257
|
+
args.defined = rb_defined != Qfalse;
|
258
|
+
|
197
259
|
rb_config = rb_hash_aref(rb_opts, SYMBOL("config_path"));
|
198
|
-
|
260
|
+
if (!NIL_P(rb_config))
|
261
|
+
args.config = StringValuePtr(rb_config);
|
199
262
|
}
|
200
|
-
|
201
|
-
num_containers = 0;
|
202
|
-
if (active && defined)
|
203
|
-
num_containers = list_all_containers(config, &names, NULL);
|
204
|
-
else if (active)
|
205
|
-
num_containers = list_active_containers(config, &names, NULL);
|
206
|
-
else if (defined)
|
207
|
-
num_containers = list_defined_containers(config, &names, NULL);
|
263
|
+
num_containers = RELEASING_GVL(list_containers_without_gvl, &args);
|
208
264
|
if (num_containers < 0)
|
209
265
|
rb_raise(Error, "failure to list containers");
|
210
266
|
|
@@ -214,10 +270,10 @@ lxc_list_containers(int argc, VALUE *argv, VALUE self)
|
|
214
270
|
* ie, don't use free_c_string_array().
|
215
271
|
*/
|
216
272
|
for (i = 0; i < num_containers; i++) {
|
217
|
-
rb_ary_store(rb_containers, i, rb_str_new2(names[i]));
|
218
|
-
free(names[i]);
|
273
|
+
rb_ary_store(rb_containers, i, rb_str_new2(args.names[i]));
|
274
|
+
free(args.names[i]);
|
219
275
|
}
|
220
|
-
free(names);
|
276
|
+
free(args.names);
|
221
277
|
|
222
278
|
return rb_containers;
|
223
279
|
}
|
@@ -383,9 +439,27 @@ container_state(VALUE self)
|
|
383
439
|
return rb_str_intern(rb_funcall(rb_state, rb_intern("downcase"), 0));
|
384
440
|
}
|
385
441
|
|
442
|
+
struct add_device_node_without_gvl_args {
|
443
|
+
struct container_data *data;
|
444
|
+
char *src_path;
|
445
|
+
char *dest_path;
|
446
|
+
};
|
447
|
+
|
448
|
+
static RETURN_WITHOUT_GVL_TYPE
|
449
|
+
add_device_node_without_gvl(void *args_void)
|
450
|
+
{
|
451
|
+
struct add_device_node_without_gvl_args *args =
|
452
|
+
(struct add_device_node_without_gvl_args *)args_void;
|
453
|
+
RETURN_WITHOUT_GVL(
|
454
|
+
args->data->container->add_device_node(args->data->container,
|
455
|
+
args->src_path,
|
456
|
+
args->dest_path)
|
457
|
+
);
|
458
|
+
}
|
459
|
+
|
386
460
|
/*
|
387
461
|
* call-seq:
|
388
|
-
* container.add_device_node(src_path,
|
462
|
+
* container.add_device_node(src_path, dest_path = src_path)
|
389
463
|
*
|
390
464
|
* Adds a device node to the container.
|
391
465
|
*/
|
@@ -393,17 +467,16 @@ static VALUE
|
|
393
467
|
container_add_device_node(int argc, VALUE *argv, VALUE self)
|
394
468
|
{
|
395
469
|
int ret;
|
396
|
-
|
397
|
-
struct
|
398
|
-
VALUE rb_src_path, rb_dst_path;
|
470
|
+
VALUE rb_src_path, rb_dest_path;
|
471
|
+
struct add_device_node_without_gvl_args args;
|
399
472
|
|
400
|
-
rb_scan_args(argc, argv, "11", &rb_src_path, &
|
401
|
-
src_path =
|
402
|
-
|
473
|
+
rb_scan_args(argc, argv, "11", &rb_src_path, &rb_dest_path);
|
474
|
+
args.src_path = StringValuePtr(rb_src_path);
|
475
|
+
args.dest_path = NIL_P(rb_dest_path) ? NULL : StringValuePtr(rb_dest_path);
|
403
476
|
|
404
|
-
Data_Get_Struct(self, struct container_data, data);
|
477
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
405
478
|
|
406
|
-
ret =
|
479
|
+
ret = RELEASING_GVL(add_device_node_without_gvl, &args);
|
407
480
|
if (!ret)
|
408
481
|
rb_raise(Error, "unable to add device node");
|
409
482
|
|
@@ -593,6 +666,20 @@ err:
|
|
593
666
|
return NULL;
|
594
667
|
}
|
595
668
|
|
669
|
+
static RETURN_WITHOUT_GVL_TYPE
|
670
|
+
lxc_wait_for_pid_status_without_gvl(void *pid)
|
671
|
+
{
|
672
|
+
RETURN_WITHOUT_GVL(lxc_wait_for_pid_status(*(pid_t*)pid));
|
673
|
+
}
|
674
|
+
|
675
|
+
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) || defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
676
|
+
static void
|
677
|
+
kill_pid_without_gvl(void *pid)
|
678
|
+
{
|
679
|
+
kill(*(pid_t *)pid, SIGKILL);
|
680
|
+
}
|
681
|
+
#endif
|
682
|
+
|
596
683
|
/*
|
597
684
|
* call-seq:
|
598
685
|
* container.attach(opts = {}, &block)
|
@@ -650,7 +737,8 @@ container_attach(int argc, VALUE *argv, VALUE self)
|
|
650
737
|
goto out;
|
651
738
|
|
652
739
|
if (wait) {
|
653
|
-
ret =
|
740
|
+
ret = RELEASING_GVL2(lxc_wait_for_pid_status_without_gvl, &pid,
|
741
|
+
kill_pid_without_gvl, &pid);
|
654
742
|
/* handle case where attach fails */
|
655
743
|
if (WIFEXITED(ret) && WEXITSTATUS(ret) == 255)
|
656
744
|
ret = -1;
|
@@ -702,6 +790,31 @@ container_clear_config_item(VALUE self, VALUE rb_key)
|
|
702
790
|
return self;
|
703
791
|
}
|
704
792
|
|
793
|
+
struct clone_without_gvl_args {
|
794
|
+
struct container_data *data;
|
795
|
+
struct lxc_container *new_container;
|
796
|
+
char *name;
|
797
|
+
char *config_path;
|
798
|
+
int flags;
|
799
|
+
char *bdev_type;
|
800
|
+
char *bdev_data;
|
801
|
+
uint64_t new_size;
|
802
|
+
char **hook_args;
|
803
|
+
};
|
804
|
+
|
805
|
+
static RETURN_WITHOUT_GVL_TYPE
|
806
|
+
clone_without_gvl(void *args_void)
|
807
|
+
{
|
808
|
+
struct clone_without_gvl_args *args =
|
809
|
+
(struct clone_without_gvl_args *)args_void;
|
810
|
+
struct lxc_container *container = args->data->container;
|
811
|
+
args->new_container =
|
812
|
+
container->clone(container, args->name,
|
813
|
+
args->config_path, args->flags, args->bdev_type,
|
814
|
+
args->bdev_data, args->new_size, args->hook_args);
|
815
|
+
RETURN_WITHOUT_GVL(0);
|
816
|
+
}
|
817
|
+
|
705
818
|
/*
|
706
819
|
* call-seq:
|
707
820
|
* container.clone(clone_name, opts = {})
|
@@ -719,27 +832,22 @@ container_clear_config_item(VALUE self, VALUE rb_key)
|
|
719
832
|
static VALUE
|
720
833
|
container_clone(int argc, VALUE *argv, VALUE self)
|
721
834
|
{
|
722
|
-
int flags;
|
723
|
-
uint64_t new_size;
|
724
|
-
char *name, *config_path, *bdev_type, *bdev_data;
|
725
|
-
char **hook_args;
|
726
|
-
struct lxc_container *container, *new_container;
|
727
|
-
struct container_data *data;
|
728
835
|
VALUE rb_name, rb_opts;
|
729
836
|
VALUE rb_flags, rb_config_path, rb_bdev_type, rb_bdev_data;
|
730
837
|
VALUE rb_new_size, rb_hook_args;
|
731
838
|
VALUE rb_args[2];
|
839
|
+
struct clone_without_gvl_args args;
|
732
840
|
|
733
841
|
rb_scan_args(argc, argv, "11", &rb_name, &rb_opts);
|
734
842
|
|
735
|
-
name = StringValuePtr(rb_name);
|
843
|
+
args.name = StringValuePtr(rb_name);
|
736
844
|
|
737
|
-
config_path = NULL;
|
738
|
-
flags = 0;
|
739
|
-
bdev_type = NULL;
|
740
|
-
bdev_data = NULL;
|
741
|
-
new_size = 0;
|
742
|
-
hook_args = NULL;
|
845
|
+
args.config_path = NULL;
|
846
|
+
args.flags = 0;
|
847
|
+
args.bdev_type = NULL;
|
848
|
+
args.bdev_data = NULL;
|
849
|
+
args.new_size = 0;
|
850
|
+
args.hook_args = NULL;
|
743
851
|
|
744
852
|
rb_config_path = Qnil;
|
745
853
|
|
@@ -747,49 +855,68 @@ container_clone(int argc, VALUE *argv, VALUE self)
|
|
747
855
|
Check_Type(rb_opts, T_HASH);
|
748
856
|
rb_config_path = rb_hash_aref(rb_opts, SYMBOL("config_path"));
|
749
857
|
if (!NIL_P(rb_config_path))
|
750
|
-
config_path = StringValuePtr(rb_config_path);
|
858
|
+
args.config_path = StringValuePtr(rb_config_path);
|
751
859
|
|
752
860
|
rb_flags = rb_hash_aref(rb_opts, SYMBOL("flags"));
|
753
861
|
if (!NIL_P(rb_flags))
|
754
|
-
flags = NUM2INT(rb_flags);
|
862
|
+
args.flags = NUM2INT(rb_flags);
|
755
863
|
|
756
864
|
rb_bdev_type = rb_hash_aref(rb_opts, SYMBOL("bdev_type"));
|
757
865
|
if (!NIL_P(rb_bdev_type))
|
758
|
-
bdev_type = StringValuePtr(rb_bdev_type);
|
866
|
+
args.bdev_type = StringValuePtr(rb_bdev_type);
|
759
867
|
|
760
868
|
rb_bdev_data = rb_hash_aref(rb_opts, SYMBOL("bdev_data"));
|
761
869
|
if (!NIL_P(rb_bdev_data))
|
762
|
-
bdev_data = StringValuePtr(rb_bdev_data);
|
870
|
+
args.bdev_data = StringValuePtr(rb_bdev_data);
|
763
871
|
|
764
872
|
rb_new_size = rb_hash_aref(rb_opts, SYMBOL("new_size"));
|
765
873
|
if (!NIL_P(rb_bdev_data))
|
766
|
-
new_size = NUM2ULL(rb_new_size);
|
874
|
+
args.new_size = NUM2ULL(rb_new_size);
|
767
875
|
|
768
876
|
rb_hook_args = rb_hash_aref(rb_opts, SYMBOL("hook_args"));
|
769
877
|
if (!NIL_P(rb_hook_args))
|
770
|
-
hook_args = ruby_to_c_string_array(rb_hook_args);
|
878
|
+
args.hook_args = ruby_to_c_string_array(rb_hook_args);
|
771
879
|
}
|
772
880
|
|
773
|
-
Data_Get_Struct(self, struct container_data, data);
|
774
|
-
container = data->container;
|
881
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
775
882
|
|
776
|
-
|
777
|
-
flags, bdev_type, bdev_data, new_size,
|
778
|
-
hook_args);
|
883
|
+
RELEASING_GVL_VOID(clone_without_gvl, &args);
|
779
884
|
|
780
|
-
if (hook_args)
|
781
|
-
free_c_string_array(hook_args);
|
885
|
+
if (args.hook_args)
|
886
|
+
free_c_string_array(args.hook_args);
|
782
887
|
|
783
|
-
if (new_container == NULL)
|
888
|
+
if (args.new_container == NULL)
|
784
889
|
rb_raise(Error, "unable to clone container");
|
785
890
|
|
786
|
-
lxc_container_put(new_container);
|
891
|
+
lxc_container_put(args.new_container);
|
787
892
|
|
788
893
|
rb_args[0] = rb_name;
|
789
894
|
rb_args[1] = rb_config_path;
|
790
895
|
return rb_class_new_instance(2, rb_args, Container);
|
791
896
|
}
|
792
897
|
|
898
|
+
struct console_without_gvl_args {
|
899
|
+
struct container_data *data;
|
900
|
+
int tty_num;
|
901
|
+
int stdin_fd;
|
902
|
+
int stdout_fd;
|
903
|
+
int stderr_fd;
|
904
|
+
int escape;
|
905
|
+
};
|
906
|
+
|
907
|
+
static RETURN_WITHOUT_GVL_TYPE
|
908
|
+
console_without_gvl(void *args_void)
|
909
|
+
{
|
910
|
+
struct console_without_gvl_args *args =
|
911
|
+
(struct console_without_gvl_args *)args_void;
|
912
|
+
struct lxc_container *container = args->data->container;
|
913
|
+
RETURN_WITHOUT_GVL(
|
914
|
+
container->console(container, args->tty_num,
|
915
|
+
args->stdin_fd, args->stdout_fd,
|
916
|
+
args->stderr_fd, args->escape)
|
917
|
+
);
|
918
|
+
}
|
919
|
+
|
793
920
|
/*
|
794
921
|
* call-seq:
|
795
922
|
* container.console(opts = {})
|
@@ -807,29 +934,44 @@ static VALUE
|
|
807
934
|
container_console(int argc, VALUE *argv, VALUE self)
|
808
935
|
{
|
809
936
|
int ret;
|
810
|
-
|
811
|
-
struct container_data *data;
|
812
|
-
struct lxc_container *container;
|
937
|
+
struct console_without_gvl_args args;
|
813
938
|
VALUE rb_opts;
|
939
|
+
VALUE rb_opt;
|
940
|
+
|
941
|
+
args.tty_num = -1;
|
942
|
+
args.stdin_fd = 0;
|
943
|
+
args.stdout_fd = 1;
|
944
|
+
args.stderr_fd = 2;
|
945
|
+
args.escape = 1;
|
814
946
|
|
815
947
|
rb_scan_args(argc, argv, "01", &rb_opts);
|
816
948
|
switch (TYPE(rb_opts)) {
|
817
949
|
case T_HASH:
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
950
|
+
rb_opt = rb_hash_aref(rb_opts, SYMBOL("tty_num"));
|
951
|
+
if (!NIL_P(rb_opt))
|
952
|
+
args.tty_num = NUM2INT(rb_opt);
|
953
|
+
rb_opt = rb_hash_aref(rb_opts, SYMBOL("stdin_fd"));
|
954
|
+
if (!NIL_P(rb_opt))
|
955
|
+
args.stdin_fd = NUM2INT(rb_opt);
|
956
|
+
rb_opt = rb_hash_aref(rb_opts, SYMBOL("stdout_fd"));
|
957
|
+
if (!NIL_P(rb_opt))
|
958
|
+
args.stdout_fd = NUM2INT(rb_opt);
|
959
|
+
rb_opt = rb_hash_aref(rb_opts, SYMBOL("stderr_fd"));
|
960
|
+
if (!NIL_P(rb_opt))
|
961
|
+
args.stderr_fd = NUM2INT(rb_opt);
|
962
|
+
rb_opt = rb_hash_aref(rb_opts, SYMBOL("escape"));
|
963
|
+
if (!NIL_P(rb_opt))
|
964
|
+
args.escape = NUM2INT(rb_opt);
|
965
|
+
break;
|
966
|
+
case T_NIL:
|
823
967
|
break;
|
824
968
|
default:
|
825
969
|
rb_raise(rb_eArgError, "options must be a hash");
|
826
970
|
}
|
827
971
|
|
828
|
-
Data_Get_Struct(self, struct container_data, data);
|
829
|
-
container = data->container;
|
972
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
830
973
|
|
831
|
-
ret =
|
832
|
-
escape);
|
974
|
+
ret = RELEASING_GVL(console_without_gvl, &args);
|
833
975
|
if (ret != 0)
|
834
976
|
rb_raise(Error, "unable to access container console");
|
835
977
|
|
@@ -863,6 +1005,27 @@ container_console_fd(int argc, VALUE *argv, VALUE self)
|
|
863
1005
|
return rb_class_new_instance(1, rb_io_args, rb_cIO);
|
864
1006
|
}
|
865
1007
|
|
1008
|
+
/* Used to run container->create outside of GIL */
|
1009
|
+
struct container_create_without_gvl_args {
|
1010
|
+
struct container_data *data;
|
1011
|
+
char *template;
|
1012
|
+
char *bdevtype;
|
1013
|
+
int flags;
|
1014
|
+
char **args;
|
1015
|
+
};
|
1016
|
+
|
1017
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1018
|
+
container_create_without_gvl(void *args_void)
|
1019
|
+
{
|
1020
|
+
struct container_create_without_gvl_args *args =
|
1021
|
+
(struct container_create_without_gvl_args *)args_void;
|
1022
|
+
RETURN_WITHOUT_GVL(
|
1023
|
+
args->data->container->create(args->data->container, args->template,
|
1024
|
+
args->bdevtype, NULL, args->flags,
|
1025
|
+
args->args)
|
1026
|
+
);
|
1027
|
+
}
|
1028
|
+
|
866
1029
|
/*
|
867
1030
|
* call-seq:
|
868
1031
|
* container.create(template, bdevtype = nil, flags = 0, args = [])
|
@@ -876,28 +1039,27 @@ container_console_fd(int argc, VALUE *argv, VALUE self)
|
|
876
1039
|
static VALUE
|
877
1040
|
container_create(int argc, VALUE *argv, VALUE self)
|
878
1041
|
{
|
879
|
-
int ret
|
880
|
-
char *template;
|
881
|
-
char *bdevtype;
|
882
|
-
char **args = { NULL };
|
883
|
-
struct container_data *data;
|
884
|
-
struct lxc_container *container;
|
1042
|
+
int ret;
|
885
1043
|
VALUE rb_template, rb_bdevtype, rb_flags, rb_args;
|
1044
|
+
struct container_create_without_gvl_args args;
|
1045
|
+
char **default_args = { NULL };
|
886
1046
|
|
887
|
-
|
1047
|
+
args.args = default_args;
|
1048
|
+
rb_scan_args(argc, argv, "13",
|
1049
|
+
&rb_template, &rb_bdevtype, &rb_flags, &rb_args);
|
888
1050
|
|
889
|
-
template = StringValuePtr(rb_template);
|
890
|
-
bdevtype = NIL_P(rb_bdevtype) ? NULL : StringValuePtr(rb_bdevtype);
|
891
|
-
flags = NIL_P(rb_flags) ? 0 : NUM2INT(rb_flags);
|
1051
|
+
args.template = StringValuePtr(rb_template);
|
1052
|
+
args.bdevtype = NIL_P(rb_bdevtype) ? NULL : StringValuePtr(rb_bdevtype);
|
1053
|
+
args.flags = NIL_P(rb_flags) ? 0 : NUM2INT(rb_flags);
|
892
1054
|
if (!NIL_P(rb_args))
|
893
|
-
args = ruby_to_c_string_array(rb_args);
|
1055
|
+
args.args = ruby_to_c_string_array(rb_args);
|
894
1056
|
|
895
|
-
Data_Get_Struct(self, struct container_data, data);
|
896
|
-
|
897
|
-
ret =
|
1057
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
1058
|
+
|
1059
|
+
ret = RELEASING_GVL(container_create_without_gvl, &args);
|
898
1060
|
|
899
1061
|
if (!NIL_P(rb_args))
|
900
|
-
free_c_string_array(args);
|
1062
|
+
free_c_string_array(args.args);
|
901
1063
|
|
902
1064
|
if (!ret)
|
903
1065
|
rb_raise(Error, "unable to create container");
|
@@ -905,6 +1067,14 @@ container_create(int argc, VALUE *argv, VALUE self)
|
|
905
1067
|
return self;
|
906
1068
|
}
|
907
1069
|
|
1070
|
+
|
1071
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1072
|
+
destroy_without_gvl(void *data_void)
|
1073
|
+
{
|
1074
|
+
struct container_data *data = (struct container_data *)data_void;
|
1075
|
+
RETURN_WITHOUT_GVL(data->container->destroy(data->container));
|
1076
|
+
}
|
1077
|
+
|
908
1078
|
/*
|
909
1079
|
* call-seq:
|
910
1080
|
* container.destroy
|
@@ -919,12 +1089,19 @@ container_destroy(VALUE self)
|
|
919
1089
|
|
920
1090
|
Data_Get_Struct(self, struct container_data, data);
|
921
1091
|
|
922
|
-
ret =
|
1092
|
+
ret = RELEASING_GVL(destroy_without_gvl, data);
|
923
1093
|
if (!ret)
|
924
1094
|
rb_raise(Error, "unable to destroy container");
|
925
1095
|
return self;
|
926
1096
|
}
|
927
1097
|
|
1098
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1099
|
+
freeze_without_gvl(void *data_void)
|
1100
|
+
{
|
1101
|
+
struct container_data *data = (struct container_data *)data_void;
|
1102
|
+
RETURN_WITHOUT_GVL(data->container->freeze(data->container));
|
1103
|
+
}
|
1104
|
+
|
928
1105
|
/*
|
929
1106
|
* call-seq:
|
930
1107
|
* container.freeze
|
@@ -939,7 +1116,7 @@ container_freeze(VALUE self)
|
|
939
1116
|
|
940
1117
|
Data_Get_Struct(self, struct container_data, data);
|
941
1118
|
|
942
|
-
ret =
|
1119
|
+
ret = RELEASING_GVL(freeze_without_gvl, data);
|
943
1120
|
if (!ret)
|
944
1121
|
rb_raise(Error, "unable to freeze container");
|
945
1122
|
|
@@ -1146,6 +1323,21 @@ container_ips(int argc, VALUE *argv, VALUE self)
|
|
1146
1323
|
return rb_ips;
|
1147
1324
|
}
|
1148
1325
|
|
1326
|
+
struct load_config_without_gvl_args {
|
1327
|
+
struct container_data *data;
|
1328
|
+
char *path;
|
1329
|
+
};
|
1330
|
+
|
1331
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1332
|
+
load_config_without_gvl(void *args_void)
|
1333
|
+
{
|
1334
|
+
struct load_config_without_gvl_args *args =
|
1335
|
+
(struct load_config_without_gvl_args *)args_void;
|
1336
|
+
RETURN_WITHOUT_GVL(
|
1337
|
+
args->data->container->load_config(args->data->container, args->path)
|
1338
|
+
);
|
1339
|
+
}
|
1340
|
+
|
1149
1341
|
/*
|
1150
1342
|
* call-seq:
|
1151
1343
|
* container.load_config(config_path = nil)
|
@@ -1156,22 +1348,28 @@ static VALUE
|
|
1156
1348
|
container_load_config(int argc, VALUE *argv, VALUE self)
|
1157
1349
|
{
|
1158
1350
|
int ret;
|
1159
|
-
char *path;
|
1160
|
-
struct container_data *data;
|
1161
1351
|
VALUE rb_path;
|
1352
|
+
struct load_config_without_gvl_args args;
|
1162
1353
|
|
1163
1354
|
rb_scan_args(argc, argv, "01", &rb_path);
|
1164
|
-
path = NIL_P(rb_path) ? NULL : StringValuePtr(rb_path);
|
1355
|
+
args.path = NIL_P(rb_path) ? NULL : StringValuePtr(rb_path);
|
1165
1356
|
|
1166
|
-
Data_Get_Struct(self, struct container_data, data);
|
1357
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
1167
1358
|
|
1168
|
-
ret =
|
1359
|
+
ret = RELEASING_GVL(load_config_without_gvl, &args);
|
1169
1360
|
if (!ret)
|
1170
1361
|
rb_raise(Error, "unable to load configuration file");
|
1171
1362
|
|
1172
1363
|
return self;
|
1173
1364
|
}
|
1174
1365
|
|
1366
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1367
|
+
reboot_without_gvl(void* data_void)
|
1368
|
+
{
|
1369
|
+
struct container_data *data = (struct container_data *)data_void;
|
1370
|
+
RETURN_WITHOUT_GVL(data->container->reboot(data->container));
|
1371
|
+
}
|
1372
|
+
|
1175
1373
|
/*
|
1176
1374
|
* call-seq:
|
1177
1375
|
* container.reboot
|
@@ -1186,16 +1384,34 @@ container_reboot(VALUE self)
|
|
1186
1384
|
|
1187
1385
|
Data_Get_Struct(self, struct container_data, data);
|
1188
1386
|
|
1189
|
-
ret =
|
1387
|
+
ret = RELEASING_GVL(reboot_without_gvl, data);
|
1190
1388
|
if (!ret)
|
1191
1389
|
rb_raise(Error, "unable to reboot container");
|
1192
1390
|
|
1193
1391
|
return self;
|
1194
1392
|
}
|
1195
1393
|
|
1394
|
+
struct remove_device_node_without_gvl_args {
|
1395
|
+
struct container_data *data;
|
1396
|
+
char *src_path;
|
1397
|
+
char *dest_path;
|
1398
|
+
};
|
1399
|
+
|
1400
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1401
|
+
remove_device_node_without_gvl(void *args_void)
|
1402
|
+
{
|
1403
|
+
struct remove_device_node_without_gvl_args *args =
|
1404
|
+
(struct remove_device_node_without_gvl_args *)args_void;
|
1405
|
+
RETURN_WITHOUT_GVL(
|
1406
|
+
args->data->container->remove_device_node(args->data->container,
|
1407
|
+
args->src_path,
|
1408
|
+
args->dest_path)
|
1409
|
+
);
|
1410
|
+
}
|
1411
|
+
|
1196
1412
|
/*
|
1197
1413
|
* call-seq:
|
1198
|
-
* container.remove_device_node(src_path,
|
1414
|
+
* container.remove_device_node(src_path, dest_path = src_path)
|
1199
1415
|
*
|
1200
1416
|
* Removes a device node from the container.
|
1201
1417
|
*/
|
@@ -1203,25 +1419,37 @@ static VALUE
|
|
1203
1419
|
container_remove_device_node(int argc, VALUE *argv, VALUE self)
|
1204
1420
|
{
|
1205
1421
|
int ret;
|
1206
|
-
|
1207
|
-
struct
|
1208
|
-
struct container_data *data;
|
1209
|
-
VALUE rb_src_path, rb_dst_path;
|
1422
|
+
VALUE rb_src_path, rb_dest_path;
|
1423
|
+
struct remove_device_node_without_gvl_args args;
|
1210
1424
|
|
1211
|
-
rb_scan_args(argc, argv, "11", &rb_src_path, &
|
1212
|
-
src_path = StringValuePtr(rb_src_path);
|
1213
|
-
|
1425
|
+
rb_scan_args(argc, argv, "11", &rb_src_path, &rb_dest_path);
|
1426
|
+
args.src_path = StringValuePtr(rb_src_path);
|
1427
|
+
args.dest_path = NIL_P(rb_dest_path) ? NULL : StringValuePtr(rb_dest_path);
|
1214
1428
|
|
1215
|
-
Data_Get_Struct(self, struct container_data, data);
|
1216
|
-
container = data->container;
|
1429
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
1217
1430
|
|
1218
|
-
ret =
|
1431
|
+
ret = RELEASING_GVL(remove_device_node_without_gvl, &args);
|
1219
1432
|
if (!ret)
|
1220
1433
|
rb_raise(Error, "unable to remove device node");
|
1221
1434
|
|
1222
1435
|
return self;
|
1223
1436
|
}
|
1224
1437
|
|
1438
|
+
struct rename_without_gvl_args {
|
1439
|
+
struct container_data *data;
|
1440
|
+
char *name;
|
1441
|
+
};
|
1442
|
+
|
1443
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1444
|
+
rename_without_gvl(void *args_void)
|
1445
|
+
{
|
1446
|
+
struct rename_without_gvl_args *args =
|
1447
|
+
(struct rename_without_gvl_args *)args_void;
|
1448
|
+
RETURN_WITHOUT_GVL(
|
1449
|
+
args->data->container->rename(args->data->container, args->name)
|
1450
|
+
);
|
1451
|
+
}
|
1452
|
+
|
1225
1453
|
/*
|
1226
1454
|
* call-seq:
|
1227
1455
|
* container.rename(new_name)
|
@@ -1233,14 +1461,14 @@ static VALUE
|
|
1233
1461
|
container_rename(VALUE self, VALUE rb_name)
|
1234
1462
|
{
|
1235
1463
|
int ret;
|
1236
|
-
char *name;
|
1237
|
-
struct container_data *data;
|
1238
1464
|
VALUE rb_args[2];
|
1465
|
+
struct rename_without_gvl_args args;
|
1239
1466
|
|
1240
|
-
|
1241
|
-
|
1467
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
1468
|
+
|
1469
|
+
args.name = StringValuePtr(rb_name);
|
1242
1470
|
|
1243
|
-
ret =
|
1471
|
+
ret = RELEASING_GVL(rename_without_gvl, &args);
|
1244
1472
|
if (!ret)
|
1245
1473
|
rb_raise(Error, "unable to rename container");
|
1246
1474
|
|
@@ -1278,20 +1506,34 @@ container_running_config_item(VALUE self, VALUE rb_key)
|
|
1278
1506
|
return rb_value;
|
1279
1507
|
}
|
1280
1508
|
|
1509
|
+
struct save_config_without_gvl_args {
|
1510
|
+
struct container_data *data;
|
1511
|
+
char *path;
|
1512
|
+
};
|
1513
|
+
|
1514
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1515
|
+
save_config_without_gvl(void *args_void)
|
1516
|
+
{
|
1517
|
+
struct save_config_without_gvl_args *args =
|
1518
|
+
(struct save_config_without_gvl_args *)args_void;
|
1519
|
+
RETURN_WITHOUT_GVL(
|
1520
|
+
args->data->container->save_config(args->data->container, args->path)
|
1521
|
+
);
|
1522
|
+
}
|
1523
|
+
|
1281
1524
|
static VALUE
|
1282
1525
|
container_save_config(int argc, VALUE *argv, VALUE self)
|
1283
1526
|
{
|
1284
1527
|
int ret;
|
1285
|
-
char *path;
|
1286
|
-
struct container_data *data;
|
1287
1528
|
VALUE rb_path;
|
1529
|
+
struct save_config_without_gvl_args args;
|
1288
1530
|
|
1289
1531
|
rb_scan_args(argc, argv, "01", &rb_path);
|
1290
|
-
path = NIL_P(rb_path) ? NULL : StringValuePtr(rb_path);
|
1532
|
+
args.path = NIL_P(rb_path) ? NULL : StringValuePtr(rb_path);
|
1291
1533
|
|
1292
|
-
Data_Get_Struct(self, struct container_data, data);
|
1534
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
1293
1535
|
|
1294
|
-
ret =
|
1536
|
+
ret = RELEASING_GVL(save_config_without_gvl, &args);
|
1295
1537
|
if (!ret)
|
1296
1538
|
rb_raise(Error, "unable to save configuration file");
|
1297
1539
|
|
@@ -1391,6 +1633,21 @@ container_set_config_path(VALUE self, VALUE rb_path)
|
|
1391
1633
|
return self;
|
1392
1634
|
}
|
1393
1635
|
|
1636
|
+
struct shutdown_without_gvl_args {
|
1637
|
+
struct container_data *data;
|
1638
|
+
int timeout;
|
1639
|
+
};
|
1640
|
+
|
1641
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1642
|
+
shutdown_without_gvl(void* args_void)
|
1643
|
+
{
|
1644
|
+
struct shutdown_without_gvl_args *args =
|
1645
|
+
(struct shutdown_without_gvl_args *)args_void;
|
1646
|
+
RETURN_WITHOUT_GVL(
|
1647
|
+
args->data->container->shutdown(args->data->container, args->timeout)
|
1648
|
+
);
|
1649
|
+
}
|
1650
|
+
|
1394
1651
|
/*
|
1395
1652
|
* call-seq:
|
1396
1653
|
* container.shutdown(timeout = -1)
|
@@ -1402,22 +1659,38 @@ container_set_config_path(VALUE self, VALUE rb_path)
|
|
1402
1659
|
static VALUE
|
1403
1660
|
container_shutdown(int argc, VALUE *argv, VALUE self)
|
1404
1661
|
{
|
1405
|
-
int ret
|
1406
|
-
struct container_data *data;
|
1662
|
+
int ret;
|
1407
1663
|
VALUE rb_timeout;
|
1664
|
+
struct shutdown_without_gvl_args args;
|
1408
1665
|
|
1409
1666
|
rb_scan_args(argc, argv, "01", &rb_timeout);
|
1410
|
-
timeout = NIL_P(rb_timeout) ? -1 : NUM2INT(rb_timeout);
|
1411
1667
|
|
1412
|
-
Data_Get_Struct(self, struct container_data, data);
|
1668
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
1669
|
+
|
1670
|
+
args.timeout = NIL_P(rb_timeout) ? -1 : NUM2INT(rb_timeout);
|
1413
1671
|
|
1414
|
-
ret =
|
1672
|
+
ret = RELEASING_GVL(shutdown_without_gvl, &args);
|
1415
1673
|
if (!ret)
|
1416
1674
|
rb_raise(Error, "unable to shutdown container");
|
1417
1675
|
|
1418
1676
|
return self;
|
1419
1677
|
}
|
1420
1678
|
|
1679
|
+
struct snapshot_without_gvl_args {
|
1680
|
+
struct container_data *data;
|
1681
|
+
char *path;
|
1682
|
+
};
|
1683
|
+
|
1684
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1685
|
+
snapshot_without_gvl(void* args_void)
|
1686
|
+
{
|
1687
|
+
struct snapshot_without_gvl_args *args =
|
1688
|
+
(struct snapshot_without_gvl_args *)args_void;
|
1689
|
+
RETURN_WITHOUT_GVL(
|
1690
|
+
args->data->container->snapshot(args->data->container, args->path)
|
1691
|
+
);
|
1692
|
+
}
|
1693
|
+
|
1421
1694
|
/*
|
1422
1695
|
* call-seq:
|
1423
1696
|
* container.snapshot(path = nil)
|
@@ -1428,17 +1701,16 @@ static VALUE
|
|
1428
1701
|
container_snapshot(int argc, VALUE *argv, VALUE self)
|
1429
1702
|
{
|
1430
1703
|
int ret;
|
1431
|
-
char *path;
|
1432
1704
|
char new_name[20];
|
1433
|
-
struct container_data *data;
|
1434
1705
|
VALUE rb_path;
|
1706
|
+
struct snapshot_without_gvl_args args;
|
1435
1707
|
|
1436
1708
|
rb_scan_args(argc, argv, "01", &rb_path);
|
1437
|
-
path = NIL_P(rb_path) ? NULL : StringValuePtr(rb_path);
|
1709
|
+
args.path = NIL_P(rb_path) ? NULL : StringValuePtr(rb_path);
|
1438
1710
|
|
1439
|
-
Data_Get_Struct(self, struct container_data, data);
|
1711
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
1440
1712
|
|
1441
|
-
ret =
|
1713
|
+
ret = RELEASING_GVL(snapshot_without_gvl, &args);
|
1442
1714
|
if (ret < 0)
|
1443
1715
|
rb_raise(Error, "unable to snapshot container");
|
1444
1716
|
|
@@ -1449,6 +1721,22 @@ container_snapshot(int argc, VALUE *argv, VALUE self)
|
|
1449
1721
|
return rb_str_new2(new_name);
|
1450
1722
|
}
|
1451
1723
|
|
1724
|
+
struct snapshot_destroy_without_gvl_args {
|
1725
|
+
struct container_data *data;
|
1726
|
+
char *name;
|
1727
|
+
};
|
1728
|
+
|
1729
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1730
|
+
snapshot_destroy_without_gvl(void *args_void)
|
1731
|
+
{
|
1732
|
+
struct snapshot_destroy_without_gvl_args *args =
|
1733
|
+
(struct snapshot_destroy_without_gvl_args *)args_void;
|
1734
|
+
RETURN_WITHOUT_GVL(
|
1735
|
+
args->data->container->snapshot_destroy(args->data->container,
|
1736
|
+
args->name)
|
1737
|
+
);
|
1738
|
+
}
|
1739
|
+
|
1452
1740
|
/*
|
1453
1741
|
* call-seq:
|
1454
1742
|
* container.snapshot_destroy(name)
|
@@ -1459,20 +1747,35 @@ static VALUE
|
|
1459
1747
|
container_snapshot_destroy(VALUE self, VALUE rb_name)
|
1460
1748
|
{
|
1461
1749
|
int ret;
|
1462
|
-
|
1463
|
-
struct container_data *data;
|
1750
|
+
struct snapshot_destroy_without_gvl_args args;
|
1464
1751
|
|
1465
|
-
|
1752
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
1466
1753
|
|
1467
|
-
|
1754
|
+
args.name = StringValuePtr(rb_name);
|
1468
1755
|
|
1469
|
-
ret =
|
1756
|
+
ret = RELEASING_GVL(snapshot_destroy_without_gvl, &args);
|
1470
1757
|
if (!ret)
|
1471
1758
|
rb_raise(Error, "unable to destroy snapshot");
|
1472
1759
|
|
1473
1760
|
return self;
|
1474
1761
|
}
|
1475
1762
|
|
1763
|
+
struct snapshot_list_without_gvl_args {
|
1764
|
+
struct container_data *data;
|
1765
|
+
struct lxc_snapshot *snapshots;
|
1766
|
+
};
|
1767
|
+
|
1768
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1769
|
+
snapshot_list_without_gvl(void *args_void)
|
1770
|
+
{
|
1771
|
+
struct snapshot_list_without_gvl_args *args =
|
1772
|
+
(struct snapshot_list_without_gvl_args *)args_void;
|
1773
|
+
RETURN_WITHOUT_GVL(
|
1774
|
+
args->data->container->snapshot_list(args->data->container,
|
1775
|
+
&args->snapshots)
|
1776
|
+
);
|
1777
|
+
}
|
1778
|
+
|
1476
1779
|
/*
|
1477
1780
|
* call-seq:
|
1478
1781
|
* container.snapshot_list
|
@@ -1483,30 +1786,47 @@ static VALUE
|
|
1483
1786
|
container_snapshot_list(VALUE self)
|
1484
1787
|
{
|
1485
1788
|
int i, num_snapshots;
|
1486
|
-
struct lxc_snapshot *snapshots;
|
1487
|
-
struct container_data *data;
|
1488
1789
|
VALUE rb_snapshots;
|
1790
|
+
struct snapshot_list_without_gvl_args args;
|
1489
1791
|
|
1490
|
-
Data_Get_Struct(self, struct container_data, data);
|
1792
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
1491
1793
|
|
1492
|
-
num_snapshots =
|
1794
|
+
num_snapshots = RELEASING_GVL(snapshot_list_without_gvl, &args);
|
1493
1795
|
if (num_snapshots < 0)
|
1494
1796
|
rb_raise(Error, "unable to list snapshots");
|
1495
1797
|
|
1496
1798
|
rb_snapshots = rb_ary_new2(num_snapshots);
|
1497
1799
|
for (i = 0; i < num_snapshots; i++) {
|
1498
1800
|
VALUE attrs = rb_ary_new2(4);
|
1499
|
-
rb_ary_store(attrs, 0, rb_str_new2(snapshots[i].name));
|
1500
|
-
rb_ary_store(attrs, 1, rb_str_new2(snapshots[i].comment_pathname));
|
1501
|
-
rb_ary_store(attrs, 2, rb_str_new2(snapshots[i].timestamp));
|
1502
|
-
rb_ary_store(attrs, 3, rb_str_new2(snapshots[i].lxcpath));
|
1503
|
-
snapshots[i].free(&snapshots[i]);
|
1801
|
+
rb_ary_store(attrs, 0, rb_str_new2(args.snapshots[i].name));
|
1802
|
+
rb_ary_store(attrs, 1, rb_str_new2(args.snapshots[i].comment_pathname));
|
1803
|
+
rb_ary_store(attrs, 2, rb_str_new2(args.snapshots[i].timestamp));
|
1804
|
+
rb_ary_store(attrs, 3, rb_str_new2(args.snapshots[i].lxcpath));
|
1805
|
+
args.snapshots[i].free(&args.snapshots[i]);
|
1504
1806
|
rb_ary_store(rb_snapshots, i, attrs);
|
1505
1807
|
}
|
1506
1808
|
|
1507
1809
|
return rb_snapshots;
|
1508
1810
|
}
|
1509
1811
|
|
1812
|
+
struct snapshot_restore_without_gvl_args {
|
1813
|
+
struct container_data *data;
|
1814
|
+
char *name;
|
1815
|
+
char *new_name;
|
1816
|
+
};
|
1817
|
+
|
1818
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1819
|
+
snapshot_restore_without_gvl(void *args_void)
|
1820
|
+
{
|
1821
|
+
struct snapshot_restore_without_gvl_args *args =
|
1822
|
+
(struct snapshot_restore_without_gvl_args *)args_void;
|
1823
|
+
RETURN_WITHOUT_GVL(
|
1824
|
+
args->data->container->snapshot_restore(args->data->container,
|
1825
|
+
args->name,
|
1826
|
+
args->new_name)
|
1827
|
+
);
|
1828
|
+
}
|
1829
|
+
|
1510
1830
|
/*
|
1511
1831
|
* call-seq:
|
1512
1832
|
* container.snapshot_restore(name, new_name = nil)
|
@@ -1517,23 +1837,44 @@ static VALUE
|
|
1517
1837
|
container_snapshot_restore(int argc, VALUE *argv, VALUE self)
|
1518
1838
|
{
|
1519
1839
|
int ret;
|
1520
|
-
|
1521
|
-
struct container_data *data;
|
1840
|
+
struct snapshot_restore_without_gvl_args args;
|
1522
1841
|
VALUE rb_name, rb_new_name;
|
1523
1842
|
|
1524
1843
|
rb_scan_args(argc, argv, "11", &rb_name, &rb_new_name);
|
1525
|
-
name = StringValuePtr(rb_name);
|
1526
|
-
new_name = NIL_P(rb_new_name) ? NULL : StringValuePtr(rb_new_name);
|
1844
|
+
args.name = StringValuePtr(rb_name);
|
1845
|
+
args.new_name = NIL_P(rb_new_name) ? NULL : StringValuePtr(rb_new_name);
|
1527
1846
|
|
1528
|
-
Data_Get_Struct(self, struct container_data, data);
|
1847
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
1529
1848
|
|
1530
|
-
ret =
|
1849
|
+
ret = RELEASING_GVL(snapshot_restore_without_gvl, &args);
|
1531
1850
|
if (!ret)
|
1532
1851
|
rb_raise(Error, "unable to restore snapshot");
|
1533
1852
|
|
1534
1853
|
return self;
|
1535
1854
|
}
|
1536
1855
|
|
1856
|
+
|
1857
|
+
struct start_without_gvl_args {
|
1858
|
+
struct container_data *data;
|
1859
|
+
int use_init;
|
1860
|
+
int daemonize;
|
1861
|
+
int close_fds;
|
1862
|
+
char **args;
|
1863
|
+
};
|
1864
|
+
|
1865
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1866
|
+
start_without_gvl(void *args_void)
|
1867
|
+
{
|
1868
|
+
struct start_without_gvl_args *args =
|
1869
|
+
(struct start_without_gvl_args *)args_void;
|
1870
|
+
struct lxc_container *container = args->data->container;
|
1871
|
+
container->want_close_all_fds(container, args->close_fds);
|
1872
|
+
container->want_daemonize(container, args->daemonize);
|
1873
|
+
RETURN_WITHOUT_GVL(
|
1874
|
+
container->start(container, args->use_init, args->args)
|
1875
|
+
);
|
1876
|
+
}
|
1877
|
+
|
1537
1878
|
/*
|
1538
1879
|
* call-seq:
|
1539
1880
|
* container.start(opts = {})
|
@@ -1548,41 +1889,42 @@ container_snapshot_restore(int argc, VALUE *argv, VALUE self)
|
|
1548
1889
|
static VALUE
|
1549
1890
|
container_start(int argc, VALUE *argv, VALUE self)
|
1550
1891
|
{
|
1551
|
-
int ret
|
1552
|
-
char **args;
|
1553
|
-
struct container_data *data;
|
1892
|
+
int ret;
|
1554
1893
|
VALUE rb_use_init, rb_daemonize, rb_close_fds, rb_args, rb_opts;
|
1894
|
+
struct start_without_gvl_args args;
|
1555
1895
|
|
1556
|
-
use_init = 0;
|
1557
|
-
daemonize = 1;
|
1558
|
-
close_fds = 0;
|
1559
|
-
args = NULL;
|
1896
|
+
args.use_init = 0;
|
1897
|
+
args.daemonize = 1;
|
1898
|
+
args.close_fds = 0;
|
1899
|
+
args.args = NULL;
|
1560
1900
|
rb_args = Qnil;
|
1561
1901
|
|
1562
1902
|
rb_scan_args(argc, argv, "01", &rb_opts);
|
1563
1903
|
if (!NIL_P(rb_opts)) {
|
1564
1904
|
Check_Type(rb_opts, T_HASH);
|
1565
1905
|
rb_use_init = rb_hash_aref(rb_opts, SYMBOL("use_init"));
|
1566
|
-
|
1906
|
+
if (!NIL_P(rb_use_init))
|
1907
|
+
args.use_init = (rb_use_init != Qfalse);
|
1567
1908
|
|
1568
1909
|
rb_daemonize = rb_hash_aref(rb_opts, SYMBOL("daemonize"));
|
1569
|
-
|
1910
|
+
if (!NIL_P(rb_daemonize))
|
1911
|
+
args.daemonize = (rb_daemonize != Qfalse);
|
1570
1912
|
|
1571
1913
|
rb_close_fds = rb_hash_aref(rb_opts, SYMBOL("close_fds"));
|
1572
|
-
|
1914
|
+
if (!NIL_P(rb_close_fds))
|
1915
|
+
args.close_fds = (rb_close_fds != Qfalse);
|
1573
1916
|
|
1574
1917
|
rb_args = rb_hash_aref(rb_opts, SYMBOL("args"));
|
1575
|
-
|
1918
|
+
if (!NIL_P(rb_args))
|
1919
|
+
args.args = ruby_to_c_string_array(rb_args);
|
1576
1920
|
}
|
1577
1921
|
|
1578
|
-
Data_Get_Struct(self, struct container_data, data);
|
1922
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
1579
1923
|
|
1580
|
-
|
1581
|
-
data->container->want_daemonize(data->container, daemonize);
|
1582
|
-
ret = data->container->start(data->container, use_init, args);
|
1924
|
+
ret = RELEASING_GVL(start_without_gvl, &args);
|
1583
1925
|
|
1584
1926
|
if (!NIL_P(rb_args))
|
1585
|
-
free_c_string_array(args);
|
1927
|
+
free_c_string_array(args.args);
|
1586
1928
|
|
1587
1929
|
if (!ret)
|
1588
1930
|
rb_raise(Error, "unable to start container");
|
@@ -1590,6 +1932,13 @@ container_start(int argc, VALUE *argv, VALUE self)
|
|
1590
1932
|
return self;
|
1591
1933
|
}
|
1592
1934
|
|
1935
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1936
|
+
stop_without_gvl(void *data_void)
|
1937
|
+
{
|
1938
|
+
struct container_data *data = (struct container_data *)data_void;
|
1939
|
+
RETURN_WITHOUT_GVL(data->container->stop(data->container));
|
1940
|
+
}
|
1941
|
+
|
1593
1942
|
/*
|
1594
1943
|
* call-seq:
|
1595
1944
|
* container.stop
|
@@ -1604,13 +1953,20 @@ container_stop(VALUE self)
|
|
1604
1953
|
|
1605
1954
|
Data_Get_Struct(self, struct container_data, data);
|
1606
1955
|
|
1607
|
-
ret =
|
1956
|
+
ret = RELEASING_GVL(stop_without_gvl, data);
|
1608
1957
|
if (!ret)
|
1609
1958
|
rb_raise(Error, "unable to stop container");
|
1610
1959
|
|
1611
1960
|
return self;
|
1612
1961
|
}
|
1613
1962
|
|
1963
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1964
|
+
unfreeze_without_gvl(void *data_void)
|
1965
|
+
{
|
1966
|
+
struct container_data *data = (struct container_data *)data_void;
|
1967
|
+
RETURN_WITHOUT_GVL(data->container->unfreeze(data->container));
|
1968
|
+
}
|
1969
|
+
|
1614
1970
|
/*
|
1615
1971
|
* call-seq:
|
1616
1972
|
* container.unfreeze
|
@@ -1625,13 +1981,30 @@ container_unfreeze(VALUE self)
|
|
1625
1981
|
|
1626
1982
|
Data_Get_Struct(self, struct container_data, data);
|
1627
1983
|
|
1628
|
-
ret =
|
1984
|
+
ret = RELEASING_GVL(unfreeze_without_gvl, data);
|
1629
1985
|
if (!ret)
|
1630
|
-
rb_raise(Error, "unable to unfreeze container");
|
1986
|
+
rb_raise(Error, "unable to unfreeze container: %s", lxc_strerror(ret));
|
1631
1987
|
|
1632
1988
|
return self;
|
1633
1989
|
}
|
1634
1990
|
|
1991
|
+
struct wait_without_gvl_args {
|
1992
|
+
struct container_data *data;
|
1993
|
+
int timeout;
|
1994
|
+
char *state;
|
1995
|
+
};
|
1996
|
+
|
1997
|
+
static RETURN_WITHOUT_GVL_TYPE
|
1998
|
+
wait_without_gvl(void *args_void)
|
1999
|
+
{
|
2000
|
+
struct wait_without_gvl_args *args =
|
2001
|
+
(struct wait_without_gvl_args *)args_void;
|
2002
|
+
RETURN_WITHOUT_GVL(
|
2003
|
+
args->data->container->wait(args->data->container, args->state,
|
2004
|
+
args->timeout)
|
2005
|
+
);
|
2006
|
+
}
|
2007
|
+
|
1635
2008
|
/*
|
1636
2009
|
* call-seq:
|
1637
2010
|
* container.wait(state, timeout = -1)
|
@@ -1642,22 +2015,21 @@ container_unfreeze(VALUE self)
|
|
1642
2015
|
static VALUE
|
1643
2016
|
container_wait(int argc, VALUE *argv, VALUE self)
|
1644
2017
|
{
|
1645
|
-
int ret
|
1646
|
-
char *state;
|
1647
|
-
struct container_data *data;
|
2018
|
+
int ret;
|
1648
2019
|
VALUE rb_state_str, rb_state, rb_timeout;
|
2020
|
+
struct wait_without_gvl_args args;
|
1649
2021
|
|
1650
2022
|
rb_scan_args(argc, argv, "11", &rb_state, &rb_timeout);
|
1651
2023
|
|
1652
2024
|
rb_state_str = rb_funcall(rb_state, rb_intern("to_s"), 0);
|
1653
2025
|
rb_state_str = rb_funcall(rb_state_str, rb_intern("upcase"), 0);
|
1654
|
-
state = StringValuePtr(rb_state_str);
|
2026
|
+
args.state = StringValuePtr(rb_state_str);
|
1655
2027
|
|
1656
|
-
timeout = NIL_P(rb_timeout) ? -1 : NUM2INT(rb_timeout);
|
2028
|
+
args.timeout = NIL_P(rb_timeout) ? -1 : NUM2INT(rb_timeout);
|
1657
2029
|
|
1658
|
-
Data_Get_Struct(self, struct container_data, data);
|
2030
|
+
Data_Get_Struct(self, struct container_data, args.data);
|
1659
2031
|
|
1660
|
-
ret =
|
2032
|
+
ret = RELEASING_GVL(wait_without_gvl, &args);
|
1661
2033
|
if (!ret)
|
1662
2034
|
rb_raise(Error, "error waiting for container");
|
1663
2035
|
|
@@ -1713,7 +2085,7 @@ Init_lxc(void)
|
|
1713
2085
|
rb_define_method(Container, "load_config", container_load_config, -1);
|
1714
2086
|
rb_define_method(Container, "reboot", container_reboot, 0);
|
1715
2087
|
rb_define_method(Container, "remove_device_node",
|
1716
|
-
container_remove_device_node,
|
2088
|
+
container_remove_device_node, -1);
|
1717
2089
|
rb_define_method(Container, "rename", container_rename, 1);
|
1718
2090
|
rb_define_method(Container, "running_config_item",
|
1719
2091
|
container_running_config_item, 1);
|
data/lib/lxc/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lxc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-03-
|
12
|
+
date: 2014-03-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake-compiler
|