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 */
예제 #2
0
// 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);
}