Hallo,
Ik heb bezig om een PHP extensie te (her)schrijven voor RADOS, een onderdeel van Ceph.
Ik zal gelijk maar aangeven, heel erg bedreven ben ik nog niet met C++, maar ik vind een extensie schrijven wel een uitdaging.
Het probleem zit hem in het volgende stukje, laat ik eerst uitschrijven hoe dat in C++ gaat:
Hiermee open ik de pool "data" om daar vervolgens dmv van de IoCTX mee aan de slag te gaan.
Nu ben ik echter bezig met een PHP extensie en kan ik dus niet zo maar een object retourneren, deze moet je registreren waarna het PHP script een resource terug krijgt.
Daar heb ik nu het volgende voor gemaakt, echter gaat dit onderuit met een segfault.
Ik post niet mijn gehele extensie, maar de delen die volgens mij relevant zijn:
Ik test vervolgens met het volgende PHP script:
Dit levert me een segfault op, GDB vertelt me:
Ik word daar persoonlijk niet veel wijzer van. Mijn gevoel zegt dat de IoCTX klasse niet volledig alle informatie heeft om met het RADOS cluster te verbinden, maar dat zou moeten komen doordat de PHP extensie hier iets niet goed doet.
Het zelfde stukje code werkt in C++ prima, dat is het probleem niet.
Heeft iemand enig idee wat hier aan kan schorten?
Ik heb bezig om een PHP extensie te (her)schrijven voor RADOS, een onderdeel van Ceph.
Ik zal gelijk maar aangeven, heel erg bedreven ben ik nog niet met C++, maar ik vind een extensie schrijven wel een uitdaging.
Het probleem zit hem in het volgende stukje, laat ik eerst uitschrijven hoe dat in C++ gaat:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| #include "rados/librados.hpp" using namespace librados; int main(int argc, const char **argv) { Rados rados; IoCtx io_ctx; rados.init(NULL); rados.conf_read_file("/etc/ceph/ceph.conf"); rados.connect(); rados.ioctx_create("data", io_ctx); io_ctx.set_auid(0); } |
Hiermee open ik de pool "data" om daar vervolgens dmv van de IoCTX mee aan de slag te gaan.
Nu ben ik echter bezig met een PHP extensie en kan ik dus niet zo maar een object retourneren, deze moet je registreren waarna het PHP script een resource terug krijgt.
Daar heb ik nu het volgende voor gemaakt, echter gaat dit onderuit met een segfault.
Ik post niet mijn gehele extensie, maar de delen die volgens mij relevant zijn:
C: php_rados.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| #ifndef PHP_RADOS_H #define PHP_RADOS_H #define PHP_RADOS_EXTNAME "rados" #define PHP_RADOS_EXTVER "0.9.1" extern "C" { #include "php.h" #include "php_ini.h" #include "zend_exceptions.h" #include "ext/standard/info.h" #ifdef ZTS #include "TSRM.h" #endif } #include <rados/librados.hpp> using namespace librados; #define PHP_RADOS_POOL_RES_NAME "RADOS Pool" #define PHP_RADOS_LISTCTX_RES_NAME "RADOS List CTX" /** FIXME Should correspond with librados! */ #define PHP_RADOS_POOL_MAX_LENGTH 128 #define PHP_RADOS_MAX_OBJECTS 1024 struct rados_object { zend_object std; Rados *rados; bool initialized; std::vector<const char*> argv; rados_object() : initialized(false), argv(NULL) {} }; PHP_MINIT_FUNCTION(rados); PHP_MSHUTDOWN_FUNCTION(rados); PHP_MINFO_FUNCTION(rados); PHP_METHOD(Rados, __construct); PHP_METHOD(Rados, init); .. .. PHP_METHOD(Rados, ioctx_create); extern zend_module_entry rados_module_entry; #define phpext_rados_ptr &rados_module_entry; extern const zend_function_entry php_rados_ioctx_methods[]; #endif |
C++: rados.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
| #include <sstream> #include <vector> #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php_rados.h" #include "ioctx.h" zend_object_handlers rados_object_handlers; zend_object_handlers rados_ioctx_object_handlers; zend_class_entry *rados_rados_ce; zend_class_entry *rados_radosexception_ce; zend_class_entry *rados_radosioctx_ce; ... ... ... const zend_function_entry rados_rados_methods[] = { PHP_ME(Rados, __construct, arginfo_rados___construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) ... ... PHP_ME(Rados, ioctx_create, arginfo_rados_ioctx_create, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; ... ... ... PHP_METHOD(Rados, ioctx_create) { char *name = NULL; int name_len = 0; IoCtx pioctx; struct radosioctx_object *riob; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { RETURN_NULL(); } rados_object *obj = (rados_object *)zend_object_store_get_object(getThis() TSRMLS_CC); if (obj->rados->ioctx_create(name, pioctx) < 0) { RETURN_FALSE; } if (object_init_ex(return_value, rados_radosioctx_ce) != SUCCESS) { RETURN_FALSE; } riob = (struct radosioctx_object *) zend_object_store_get_object(return_value TSRMLS_CC); riob->ioctx = &pioctx; } PHP_MINIT_FUNCTION(rados) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Rados", rados_rados_methods); rados_rados_ce = zend_register_internal_class(&ce TSRMLS_CC); rados_rados_ce->create_object = rados_create_handler; memcpy(&rados_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); rados_object_handlers.clone_obj = NULL; INIT_CLASS_ENTRY(ce, "RadosException", php_rados_radosexception_methods); rados_radosexception_ce = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC); rados_radosexception_ce->ce_flags |= ZEND_ACC_FINAL; zend_declare_property_long(rados_radosexception_ce, "code", sizeof("code")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); INIT_CLASS_ENTRY(ce, "RadosIoCtx", php_rados_ioctx_methods); rados_radosioctx_ce = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); rados_radosioctx_ce->ce_flags |= ZEND_ACC_FINAL; memcpy(&rados_ioctx_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); rados_ioctx_object_handlers.clone_obj = NULL; return SUCCESS; } ... ... #ifdef COMPILE_DL_RADOS extern "C" { ZEND_GET_MODULE(rados) } #endif |
Ik test vervolgens met het volgende PHP script:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
| <?php $r = new Rados(); $r->init(); $r->conf_read_file('ceph.conf'); $r->connect(); $io = $r->ioctx_create("data"); $io->set_auid(0); $r->shutdown(); ?> |
Dit levert me een segfault op, GDB vertelt me:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| (gdb) run testrados.php Starting program: /usr/bin/php testrados.php [Thread debugging using libthread_db enabled] [New Thread 0x7fffed04e700 (LWP 14354)] [Thread 0x7fffed04e700 (LWP 14354) exited] [New Thread 0x7fffed04e700 (LWP 14355)] [New Thread 0x7fffec84d700 (LWP 14356)] [New Thread 0x7fffec04c700 (LWP 14357)] [New Thread 0x7fffeb84b700 (LWP 14358)] [New Thread 0x7fffeb04a700 (LWP 14359)] [New Thread 0x7fffeaf49700 (LWP 14360)] [New Thread 0x7fffeae48700 (LWP 14361)] Program received signal SIGSEGV, Segmentation fault. Objecter::change_pool_auid (this=0x0, pool=-136073112, onfinish=0x1047800, auid=0) at osdc/Objecter.cc:1063 warning: Source file is more recent than executable. 1063 op->tid = ++last_tid; (gdb) bt #0 Objecter::change_pool_auid (this=0x0, pool=-136073112, onfinish=0x1047800, auid=0) at osdc/Objecter.cc:1063 #1 0x00007fffee9469d9 in librados::RadosClient::pool_change_auid (this=0x7ffff7e3b390, io=<value optimized out>, auid=0) at librados.cc:1116 #2 0x00007fffeeca44fa in zim_RadosIoCtx_set_auid (ht=<value optimized out>, return_value=0x1019fd8, return_value_ptr=<value optimized out>, this_ptr=0x1018118, return_value_used=<value optimized out>) at /home/employee/wido/repos/phprados/ioctx.cc:45 #3 0x00000000006e876a in zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7e3b068) at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:313 #4 0x00000000006bf870 in execute (op_array=0x1018ba0) at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:104 #5 0x00000000006972bd in zend_execute_scripts (type=0, retval=0x7fffffffbfd0, file_count=3) at /build/buildd/php5-5.3.2/Zend/zend.c:1266 #6 0x0000000000642e88 in php_execute_script (primary_file=0x7ffff5605e40) at /build/buildd/php5-5.3.2/main/main.c:2288 #7 0x0000000000728886 in main (argc=0, argv=0x1) at /build/buildd/php5-5.3.2/sapi/cli/php_cli.c:1196 (gdb) |
Ik word daar persoonlijk niet veel wijzer van. Mijn gevoel zegt dat de IoCTX klasse niet volledig alle informatie heeft om met het RADOS cluster te verbinden, maar dat zou moeten komen doordat de PHP extensie hier iets niet goed doet.
Het zelfde stukje code werkt in C++ prima, dat is het probleem niet.
Heeft iemand enig idee wat hier aan kan schorten?