| 119 | } |
| 120 | |
| 121 | int ErasureCodePluginRegistry::load(const std::string &plugin_name, |
| 122 | const std::string &directory, |
| 123 | ErasureCodePlugin **plugin, |
| 124 | ostream *ss) |
| 125 | { |
| 126 | ceph_assert(ceph_mutex_is_locked(lock)); |
| 127 | std::string fname = directory + "/" PLUGIN_PREFIX |
| 128 | + plugin_name + PLUGIN_SUFFIX; |
| 129 | void *library = dlopen(fname.c_str(), RTLD_NOW); |
| 130 | if (!library) { |
| 131 | *ss << "load dlopen(" << fname << "): " << dlerror(); |
| 132 | return -EIO; |
| 133 | } |
| 134 | |
| 135 | const char * (*erasure_code_version)() = |
| 136 | (const char *(*)())dlsym(library, PLUGIN_VERSION_FUNCTION); |
| 137 | if (erasure_code_version == NULL) |
| 138 | erasure_code_version = an_older_version; |
| 139 | if (erasure_code_version() != string(CEPH_GIT_NICE_VER)) { |
| 140 | *ss << "expected plugin " << fname << " version " << CEPH_GIT_NICE_VER |
| 141 | << " but it claims to be " << erasure_code_version() << " instead"; |
| 142 | dlclose(library); |
| 143 | return -EXDEV; |
| 144 | } |
| 145 | |
| 146 | int (*erasure_code_init)(const char *, const char *) = |
| 147 | (int (*)(const char *, const char *))dlsym(library, PLUGIN_INIT_FUNCTION); |
| 148 | if (erasure_code_init) { |
| 149 | std::string name = plugin_name; |
| 150 | int r = erasure_code_init(name.c_str(), directory.c_str()); |
| 151 | if (r != 0) { |
| 152 | *ss << "erasure_code_init(" << plugin_name |
| 153 | << "," << directory |
| 154 | << "): " << cpp_strerror(r); |
| 155 | dlclose(library); |
| 156 | return r; |
| 157 | } |
| 158 | } else { |
| 159 | *ss << "load dlsym(" << fname |
| 160 | << ", " << PLUGIN_INIT_FUNCTION |
| 161 | << "): " << dlerror(); |
| 162 | dlclose(library); |
| 163 | return -ENOENT; |
| 164 | } |
| 165 | |
| 166 | *plugin = get(plugin_name); |
| 167 | if (*plugin == 0) { |
| 168 | *ss << "load " << PLUGIN_INIT_FUNCTION << "()" |
| 169 | << "did not register " << plugin_name; |
| 170 | dlclose(library); |
| 171 | return -EBADF; |
| 172 | } |
| 173 | |
| 174 | (*plugin)->library = library; |
| 175 | |
| 176 | *ss << __func__ << ": " << plugin_name << " "; |
| 177 | |
| 178 | return 0; |