static ClassHandler::ClassData null_cls_data;
-void ClassHandler::_load_class(ClassData &cls)
+int ClassHandler::_load_class(ClassData &cls)
{
+ int ret;
dout(10) << "load_class " << cls.name << dendl;
cls_deps_t *(*cls_deps)();
snprintf(fname, sizeof(fname), "%s/class-XXXXXX", g_conf.osd_class_tmp);
int fd = mkstemp(fname);
+ if (fd < 0) {
+ dout(0) << "could not create temp file " << fname << dendl;
+ return -errno;
+ }
cls.impl.binary.write_fd(fd);
close(fd);
if (!cls.handle) {
dout(0) << "could not open class (dlopen failed): " << dlerror() << dendl;
+ ret = -EIO;
goto done;
}
cls_deps = (cls_deps_t *(*)())dlsym(cls.handle, "class_deps");
deps++;
}
}
- cls.load();
+ ret = cls.load();
done:
unlink(fname);
- return;
+ return ret;
}
-void ClassHandler::load_class(const string& cname)
+int ClassHandler::load_class(const string& cname)
{
+ int ret;
+
ClassData& cls = get_obj(cname);
if (&cls == &null_cls_data) {
dout(0) << "ERROR: can't load null class data" << dendl;
- return;
+ return -EINVAL;
}
cls.mutex->Lock();
- _load_class(cls);
+ ret = _load_class(cls);
cls.mutex->Unlock();
+
+ return ret;
}
ClassHandler::ClassData& ClassHandler::get_obj(const string& cname)
Mutex::Locker lock(*class_data->mutex);
switch (class_data->status) {
+ case ClassData::CLASS_ERROR:
case ClassData::CLASS_INVALID:
case ClassData::CLASS_LOADED:
if (class_data->cache_timed_out()) {
dout(10) << "added class '" << info_iter->name << "'" << dendl;
data.impl = *impl_iter;
++impl_iter;
- _load_class(data);
+ int ret = _load_class(data);
+ if (ret < 0) {
+ data.set_status(ClassData::CLASS_ERROR);
+ osd->got_class(info_iter->name);
+ }
} else {
dout(10) << "response of an invalid class '" << info_iter->name << "'" << dendl;
data.set_status(ClassData::CLASS_INVALID);
}
-void ClassHandler::ClassData::load()
+int ClassHandler::ClassData::load()
{
- if (status == CLASS_INVALID) {
+ int ret;
+ switch (status) {
+ case CLASS_INVALID:
+ ret = -EINVAL;
+ break;
+ case CLASS_ERROR:
+ ret = -EIO;
+ break;
+ default:
+ ret = 0;
+ }
+ if (ret) {
/* if we're invalid, we should just notify osd */
osd->got_class(name);
- return;
+ return ret;
}
if (!has_missing_deps()) {
ClassData *cls = *iter;
cls->satisfy_dependency(this);
}
+
+ return 0;
}
void ClassHandler::ClassData::init()
}
cls_dep._add_dependent(*this);
- if (cls_dep.status == CLASS_INVALID) {
- dout(0) << "ouch! depending on invalid class" << dendl;
- set_status(CLASS_INVALID); /* we have an invalid dependency, we're invalid */
+ if ((cls_dep.status == CLASS_INVALID) ||
+ (cls_dep.status == CLASS_ERROR)) {
+ dout(0) << "ouch! depending on bad class" << dendl;
+ set_status(cls_dep.status); /* we have an invalid dependency, we're invalid */
}
return true;
status = _status;
switch (status) {
+ case CLASS_ERROR:
case CLASS_INVALID:
case CLASS_LOADED:
set_timeout();
void satisfy_dependency(ClassData *cls);
enum Status {
- CLASS_UNKNOWN,
- CLASS_INVALID,
- CLASS_LOADED,
- CLASS_REQUESTED,
+ CLASS_UNKNOWN,
+ CLASS_INVALID,
+ CLASS_ERROR,
+ CLASS_LOADED,
+ CLASS_REQUESTED,
} status;
ClassVersion version;
time_t timeout;
ClassMethod *get_method(const char *mname);
void unregister_method(ClassMethod *method);
- void load();
+ int load();
void init();
void set_status(Status _status);
ClassData& get_obj(const string& cname);
- void load_class(const string& cname);
- void _load_class(ClassData &data);
+ int load_class(const string& cname);
+ int _load_class(ClassData &data);
ClassHandler(OSD *_osd) : osd(_osd), mutex("ClassHandler") {}