void classifierd_run(void) { struct ovsdb_idl_txn *txn; /* Process a batch of messages from OVSDB. */ ovsdb_idl_run(idl); if (ovsdb_idl_is_lock_contended(idl)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); VLOG_ERR_RL(&rl, "Another classifierd process is running, " "disabling this process until it goes away"); return; } else if (!ovsdb_idl_has_lock(idl)) { return; } /* Nothing to do until system has been configured, i.e. cur_cfg > 0. */ if (!classifierd_system_is_configured()) { return; } /* Update the local configuration and push any changes to the dB. */ txn = ovsdb_idl_txn_create(idl); if (classifierd_reconfigure()) { VLOG_DBG("%s: Committing changes\n",__FUNCTION__); /* Some OVSDB write needs to happen. */ ovsdb_idl_txn_commit_block(txn); } ovsdb_idl_txn_destroy(txn); return; } /* classifierd_run */
// create a new locl_subsystem object static struct locl_subsystem * add_subsystem(const struct ovsrec_subsystem *ovsrec_subsys) { struct locl_subsystem *result; int rc; int idx; struct ovsdb_idl_txn *txn; struct ovsrec_temp_sensor **sensor_array; int sensor_idx; int sensor_count; const char *dir; const YamlThermalInfo *info; // create and initialize basic subsystem information VLOG_DBG("Adding new subsystem %s", ovsrec_subsys->name); result = (struct locl_subsystem *)malloc(sizeof(struct locl_subsystem)); memset(result, 0, sizeof(struct locl_subsystem)); (void)shash_add(&subsystem_data, ovsrec_subsys->name, (void *)result); result->name = strdup(ovsrec_subsys->name); result->marked = false; result->marked = true; result->parent_subsystem = NULL; // OPS_TODO: find parent subsystem shash_init(&result->subsystem_sensors); // use a default if the hw_desc_dir has not been populated dir = ovsrec_subsys->hw_desc_dir; if (dir == NULL || strlen(dir) == 0) { VLOG_ERR("No h/w description directory for subsystem %s", ovsrec_subsys->name); return(NULL); } // since this is a new subsystem, load all of the hardware description // information about devices and sensors (just for this subsystem). // parse sensors and device data for subsystem rc = yaml_add_subsystem(yaml_handle, ovsrec_subsys->name, dir); if (rc != 0) { VLOG_ERR("Error reading h/w description files for subsystem %s", ovsrec_subsys->name); return(NULL); } // need devices data rc = yaml_parse_devices(yaml_handle, ovsrec_subsys->name); if (rc != 0) { VLOG_ERR("Unable to parse subsystem %s devices file (in %s)", ovsrec_subsys->name, dir); return(NULL); } // need thermal (sensor) data rc = yaml_parse_thermal(yaml_handle, ovsrec_subsys->name); if (rc != 0) { VLOG_ERR("Unable to parse subsystem %s thermal file (in %s)", ovsrec_subsys->name, dir); return(NULL); } // get the thermal info, need it for shutdown flag info = yaml_get_thermal_info(yaml_handle, ovsrec_subsys->name); result->emergency_shutdown = info->auto_shutdown; // OPS_TODO: the thermal info has a polling period, but when we // OPS_TODO: have multiple subsystems, that could be tricky to // OPS_TODO: implement if there are different polling periods. // OPS_TODO: For now, hardware the polling period to 5 seconds. // prepare to add sensors to db sensor_idx = 0; sensor_count = yaml_get_sensor_count(yaml_handle, ovsrec_subsys->name); if (sensor_count <= 0) { return(NULL); } result->valid = true; // subsystem db object has reference array for sensors sensor_array = (struct ovsrec_temp_sensor **)malloc(sensor_count * sizeof(struct ovsrec_temp_sensor *)); memset(sensor_array, 0, sensor_count * sizeof(struct ovsrec_temp_sensor *)); txn = ovsdb_idl_txn_create(idl); VLOG_DBG("There are %d sensors in subsystem %s", sensor_count, ovsrec_subsys->name); for (idx = 0; idx < sensor_count; idx++) { const YamlSensor *sensor = yaml_get_sensor(yaml_handle, ovsrec_subsys->name, idx); struct ovsrec_temp_sensor *ovs_sensor; char *sensor_name = NULL; struct locl_sensor *new_sensor; VLOG_DBG("Adding sensor %d (%s) in subsystem %s", sensor->number, sensor->location, ovsrec_subsys->name); // create a name for the sensor from the subsystem name and the // sensor number asprintf(&sensor_name, "%s-%d", ovsrec_subsys->name, sensor->number); // allocate and initialize basic sensor information new_sensor = (struct locl_sensor *)malloc(sizeof(struct locl_sensor)); new_sensor->name = sensor_name; new_sensor->subsystem = result; new_sensor->yaml_sensor = sensor; new_sensor->min = 1000000; new_sensor->max = -1000000; new_sensor->temp = 0; new_sensor->status = SENSOR_STATUS_NORMAL; new_sensor->fan_speed = SENSOR_FAN_NORMAL; new_sensor->test_temp = -1; // no test temperature override set // try to populate sensor information with real data tempd_read_sensor(new_sensor); // add sensor to subsystem sensor dictionary shash_add(&result->subsystem_sensors, sensor_name, (void *)new_sensor); // add sensor to global sensor dictionary shash_add(&sensor_data, sensor_name, (void *)new_sensor); // look for existing Temp_sensor rows ovs_sensor = lookup_sensor(sensor_name); if (ovs_sensor == NULL) { // existing sensor doesn't exist in db, create it ovs_sensor = ovsrec_temp_sensor_insert(txn); } // set initial data ovsrec_temp_sensor_set_name(ovs_sensor, sensor_name); ovsrec_temp_sensor_set_status(ovs_sensor, sensor_status_to_string(new_sensor->status)); ovsrec_temp_sensor_set_temperature(ovs_sensor, new_sensor->temp); ovsrec_temp_sensor_set_min(ovs_sensor, new_sensor->min); ovsrec_temp_sensor_set_max(ovs_sensor, new_sensor->max); ovsrec_temp_sensor_set_fan_state(ovs_sensor, sensor_speed_to_string(new_sensor->fan_speed)); ovsrec_temp_sensor_set_location(ovs_sensor, sensor->location); // add sensor to subsystem reference list sensor_array[sensor_idx++] = ovs_sensor; } ovsrec_subsystem_set_temp_sensors(ovsrec_subsys, sensor_array, sensor_count); // execute transaction ovsdb_idl_txn_commit_block(txn); ovsdb_idl_txn_destroy(txn); free(sensor_array); return(result); }