Пример #1
0
int read_scalar_params(config_item_t block, const char *block_name,
                       const cfg_param_t * params, char *msgout)
{
    int i;
    int rc = 0;

    /* read all expected parameters */
    for (i = 0; params[i].name != NULL; i++)
    {
        switch (params[i].type)
        {
            case PT_STRING:
                rc = GetStringParam(block, block_name, params[i].name,
                                    params[i].flags, (char*)params[i].ptr, params[i].ptrsize,
                                    NULL, NULL, msgout);
                if cfg_is_err(rc, params[i].flags)
                    return rc;
                break;

            case PT_CMD:
                rc = GetCommandParam(block, block_name, params[i].name,
                                     params[i].flags, (char***)params[i].ptr,
                                     NULL, NULL, msgout);
                if cfg_is_err(rc, params[i].flags)
                    return rc;
                break;

            case PT_BOOL:
                rc = GetBoolParam(block, block_name, params[i].name,
                                  params[i].flags, (bool*)params[i].ptr,
                                  NULL, NULL, msgout);
                if cfg_is_err(rc, params[i].flags)
                    return rc;
                break;

            case PT_DURATION:
                rc = GetDurationParam(block, block_name, params[i].name,
                                  params[i].flags, (time_t*)params[i].ptr,
                                  NULL, NULL, msgout);
                if cfg_is_err(rc, params[i].flags)
                    return rc;
                break;

            case PT_SIZE:
                rc = GetSizeParam(block, block_name, params[i].name,
                                  params[i].flags,
                                  (unsigned long long*)params[i].ptr,
                                  NULL, NULL, msgout);
                if cfg_is_err(rc, params[i].flags)
                    return rc;
                break;

            case PT_INT:
                rc = GetIntParam(block, block_name, params[i].name,
                                  params[i].flags, (int*)params[i].ptr,
                                  NULL, NULL, msgout);
                if cfg_is_err(rc, params[i].flags)
                    return rc;
                break;

            case PT_INT64:
                rc = GetInt64Param(block, block_name, params[i].name,
                                  params[i].flags, (uint64_t*)params[i].ptr,
                                  NULL, NULL, msgout);
                if cfg_is_err(rc, params[i].flags)
                    return rc;
                break;

            case PT_FLOAT:
                rc = GetFloatParam(block, block_name, params[i].name,
                                  params[i].flags, (double*)params[i].ptr,
                                  NULL, NULL, msgout);
                if cfg_is_err(rc, params[i].flags)
                    return rc;
                break;

            case PT_TYPE:
                sprintf(msgout, "Unexpected type for %s parameter (type)",
                        params[i].name);
                return EINVAL;
        }
    }
    return 0;
}
Пример #2
0
static int parse_trigger_block( config_item_t config_blk, const char *block_name,
                                trigger_item_t * p_trigger_item, char *msg_out )
{
    int            rc;
    int            rc_hp, rc_lp, rc_hv, rc_lv, rc_hc, rc_lc;
    unsigned int high_count = 0;
    unsigned int low_count = 0;
    double         h_pct, l_pct;
    unsigned long long h_vol, l_vol;
    uint64_t       h_cnt, l_cnt;
    int            tmpval;
    int            i;
    char           tmpstr[1024];
    char         **arg_tab;
    unsigned int   arg_count;

    static const char *trigger_expect[] =
    {
        "trigger_on", "check_interval",
        "high_threshold_pct", "low_threshold_pct",
        "high_threshold_vol", "low_threshold_vol",
        "high_threshold_cnt", "low_threshold_cnt",
        "alert_high", "alert_low",
        /* for backward compatibility */
        "high_watermark_pct", "low_watermark_pct",
        "high_watermark_vol", "low_watermark_vol",
        "high_watermark_cnt", "low_watermark_cnt",
        "notify", "notify_hw", "alert_lw",
        NULL
    };


    /* retrieve parameters */

    rc = GetStringParam( config_blk, block_name, "trigger_on",
                         PARAM_MANDATORY | STR_PARAM_NO_WILDCARDS, tmpstr, 1024, &arg_tab,
                         &arg_count, msg_out );

    if ( rc )                   /* even ENOENT retruns an error because trigger_on is mandatory */
        return rc;

    /* initialize list of optional args */
    p_trigger_item->list = NULL;
    p_trigger_item->list_size = 0;

    /* analyze trigger_on parameter */
    if ( !strcasecmp( tmpstr, "periodic" ) )
    {
        p_trigger_item->type = TRIGGER_ALWAYS;

        /* default: alert enabled if LW cannot be reached */
        p_trigger_item->alert_lw = FALSE;

        /* no arg expected */
        if ( arg_count > 0 )
        {
            sprintf( msg_out,
                     "No extra argument expected for trigger type '%s': %u argument(s) found.",
                     tmpstr, arg_count );
            return EINVAL;
        }
    }
    else if ( !strcasecmp( tmpstr, "global_usage" ) )
    {
        p_trigger_item->type = TRIGGER_GLOBAL_USAGE;

        /* default: alert enabled if LW cannot be reached */
        p_trigger_item->alert_lw = TRUE;

        /* no arg expected */
        if ( arg_count > 0 )
        {
            sprintf( msg_out,
                     "No extra argument expected for trigger type '%s': %u argument(s) found.",
                     tmpstr, arg_count );
            return EINVAL;
        }
    }
    else if ( !strcasecmp( tmpstr, "OST_usage" ) )
    {
        p_trigger_item->type = TRIGGER_OST_USAGE;

        /* default: alert enabled if LW cannot be reached */
        p_trigger_item->alert_lw = TRUE;

        /* no arg expected */
        if ( arg_count > 0 )
        {
            sprintf( msg_out,
                     "No extra argument expected for trigger type '%s': %u argument(s) found.",
                     tmpstr, arg_count );
            return EINVAL;
        }
    }
    else if ( !strcasecmp( tmpstr, "user_usage" ) )
    {
        p_trigger_item->type = TRIGGER_USER_USAGE;

        /* default: alert enabled if LW cannot be reached */
        p_trigger_item->alert_lw = TRUE;

        /* optional arguments: user list */
        if ( arg_count > 0 )
        {
            p_trigger_item->list = ( char ** ) calloc( arg_count, sizeof( char * ) );
            p_trigger_item->list_size = arg_count;
            for ( i = 0; i < arg_count; i++ )
            {
                p_trigger_item->list[i] = ( char * ) malloc( strlen( arg_tab[i] ) + 1 );
                strcpy( p_trigger_item->list[i], arg_tab[i] );
            }
        }
    }
    else if ( !strcasecmp( tmpstr, "group_usage" ) )
    {
        p_trigger_item->type = TRIGGER_GROUP_USAGE;

        /* default: alert enabled if LW cannot be reached */
        p_trigger_item->alert_lw = TRUE;

        /* optional argument: group list */
        if ( arg_count > 0 )
        {
            p_trigger_item->list = ( char ** ) calloc( arg_count, sizeof( char * ) );
            p_trigger_item->list_size = arg_count;
            for ( i = 0; i < arg_count; i++ )
            {
                p_trigger_item->list[i] = ( char * ) malloc( strlen( arg_tab[i] ) + 1 );
                strcpy( p_trigger_item->list[i], arg_tab[i] );
            }
        }
    }
    else if ( !strcasecmp( tmpstr, "pool_usage" ) )
    {
        p_trigger_item->type = TRIGGER_POOL_USAGE;

        /* default: alert enabled if LW cannot be reached */
        p_trigger_item->alert_lw = TRUE;

        /* optional arguments: user list */
        if ( arg_count > 0 )
        {
            p_trigger_item->list = ( char ** ) calloc( arg_count, sizeof( char * ) );
            p_trigger_item->list_size = arg_count;
            for ( i = 0; i < arg_count; i++ )
            {
                p_trigger_item->list[i] = ( char * ) malloc( strlen( arg_tab[i] ) + 1 );
                strcpy( p_trigger_item->list[i], arg_tab[i] );
            }
        }
    }
    else if ( !strcasecmp( tmpstr, "external_command" ) )
    {
        p_trigger_item->type = TRIGGER_CUSTOM_CMD;

        /* default: alert enabled if LW cannot be reached */
        p_trigger_item->alert_lw = TRUE;

        /* single mandatory argument: command */
        if ( arg_count != 1 )
        {
            sprintf( msg_out,
                     "A single mandatory argument is expected for trigger type '%s': %u argument(s) found.",
                     tmpstr, arg_count );
            return EINVAL;
        }

        p_trigger_item->list = ( char ** ) malloc( sizeof( char * ) );
        p_trigger_item->list[0] = ( char * ) malloc( strlen( arg_tab[0] ) + 1 );
        strcpy( p_trigger_item->list[0], arg_tab[0] );
        p_trigger_item->list_size = 1;
    }
    else
    {
        sprintf( msg_out, "Unexpected value for 'trigger_on' parameter: %s.", tmpstr );
        return EINVAL;
    }


    /* retrieve all threshold params and check their compatibility */
    high_count = low_count = 0;

    rc_hp = GetFloatParam( config_blk, block_name, "high_threshold_pct",
                         FLOAT_PARAM_POSITIVE | ALLOW_PCT_SIGN, &h_pct,
                         NULL, NULL, msg_out );
    /* for backward compatibility */
    if ( rc_hp == ENOENT )
        rc_hp = GetFloatParam( config_blk, block_name, "high_watermark_pct",
                             FLOAT_PARAM_POSITIVE | ALLOW_PCT_SIGN, &h_pct,
                             NULL, NULL, msg_out );

    if ( ( rc_hp != 0 ) && ( rc_hp != ENOENT ) )
        return rc_hp;
    else if ( rc_hp != ENOENT )
        high_count++;

    rc_hv = GetSizeParam( config_blk, block_name, "high_threshold_vol",
                        INT_PARAM_POSITIVE, &h_vol, NULL, NULL, msg_out );
    /* for backward compatibility */
    if ( rc_hv == ENOENT )
        rc_hv = GetSizeParam( config_blk, block_name, "high_watermark_vol",
                              INT_PARAM_POSITIVE, &h_vol, NULL, NULL, msg_out );

    if ( ( rc_hv != 0 ) && ( rc_hv != ENOENT ) )
        return rc_hv;
    else if ( rc_hv != ENOENT )
        high_count++;

    rc_hc = GetInt64Param( config_blk, block_name, "high_threshold_cnt",
                           INT_PARAM_POSITIVE, &h_cnt, NULL, NULL, msg_out );
    /* for backward compatibility */
    if ( rc_hc == ENOENT )
            rc_hc = GetInt64Param( config_blk, block_name, "high_watermark_cnt",
                                   INT_PARAM_POSITIVE, &h_cnt, NULL, NULL, msg_out );
    if ( ( rc_hc != 0 ) && ( rc_hc != ENOENT ) )
        return rc_hc;
    else if ( rc_hc != ENOENT )
        high_count++;

    rc_lp = GetFloatParam( config_blk, block_name, "low_threshold_pct",
                         FLOAT_PARAM_POSITIVE | ALLOW_PCT_SIGN, &l_pct,
                         NULL, NULL, msg_out );
    /* for backward compatibility */
    if ( rc_lp == ENOENT )
        rc_lp = GetFloatParam( config_blk, block_name, "low_watermark_pct",
                             FLOAT_PARAM_POSITIVE | ALLOW_PCT_SIGN, &l_pct,
                             NULL, NULL, msg_out );

    if ( ( rc_lp != 0 ) && ( rc_lp != ENOENT ) )
        return rc_lp;
    else if ( rc_lp != ENOENT )
        low_count++;

    rc_lv = GetSizeParam( config_blk, block_name, "low_threshold_vol",
                        INT_PARAM_POSITIVE, &l_vol, NULL, NULL, msg_out );
    /* for backward compatibility */
    if ( rc_lv == ENOENT )
        rc_lv = GetSizeParam( config_blk, block_name, "low_watermark_vol",
                            INT_PARAM_POSITIVE, &l_vol, NULL, NULL, msg_out );
    if ( ( rc_lv != 0 ) && ( rc_lv != ENOENT ) )
        return rc_lv;
    else if ( rc_lv != ENOENT )
        low_count++;

    rc_lc = GetInt64Param( config_blk, block_name, "low_threshold_cnt",
                           INT_PARAM_POSITIVE, &l_cnt, NULL, NULL, msg_out );
    /* for backward compatibility */
    if ( rc_lc == ENOENT )
        rc_lc = GetInt64Param( config_blk, block_name, "low_watermark_cnt",
                               INT_PARAM_POSITIVE, &l_cnt, NULL, NULL, msg_out );
    if ( ( rc_lc != 0 ) && ( rc_lc != ENOENT ) )
        return rc_lc;
    else if ( rc_lc != ENOENT )
        low_count++;

    if ( p_trigger_item->type == TRIGGER_ALWAYS )
    {
        /* in case of 'periodic' trigger, no thresholds are expected */
        if ( (high_count > 0) || (low_count > 0) )
        {
            strcpy( msg_out,
                    "No high/low threshold expected for trigger type 'periodic'" );
            return EINVAL;
        }
    }
    else if ( p_trigger_item->type == TRIGGER_CUSTOM_CMD )
    {
        /* in case of an external command, no thresholds are expected */
        if ( (high_count > 0) || (low_count > 0) )
        {
            strcpy( msg_out,
                    "No high/low thresholds expected for trigger type 'external_command'" );
            return EINVAL;
        }
    }
    else if ( high_count > 1 )
    {
        strcpy( msg_out, "Multiple purge start conditions in trigger." );
        return EINVAL;
    }
    else if ( low_count > 1 )
    {
        strcpy( msg_out, "Multiple purge stop conditions in trigger." );
        return EINVAL;
    }
    else if ( high_count == 0 )
    {
        strcpy( msg_out, "No purge start condition found in trigger "
                         "(mandatory). 'high_threshold_pct', 'high_threshold_vol'"
                         "or 'high_threshold_cnt' expected" );
        return ENOENT;
    }
    else if ( low_count == 0 )
    {
        strcpy( msg_out, "No purge stop condition found in trigger "
                         "(mandatory). 'low_threshold_pct', 'low_threshold_vol'"
                         "or 'low_threshold_cnt' expected" );
        return ENOENT;
    }
    else if ( rc_hc != rc_lc ) /* both 0 or both ENOENT */
    {
        strcpy( msg_out, "Incompatible threshold types: 'high_threshold_cnt' "
                         "must be used with 'low_threshold_cnt'" );
        return ENOENT;
    }

    /* NOTE: count threshold for HSM systems only match online files (not released)*/

    /* count threshold is only on global usage */
    if ( (p_trigger_item->type != TRIGGER_GLOBAL_USAGE)
         && (p_trigger_item->type != TRIGGER_ALWAYS)
         && (p_trigger_item->type != TRIGGER_USER_USAGE)
         && (p_trigger_item->type != TRIGGER_GROUP_USAGE)
         && ( (rc_hc == 0) || (rc_lc == 0) ) )
    {
        strcpy( msg_out, "Threshold on entry count is only supported "
                         "for 'global_usage', 'user_usage', 'group_usage' and 'periodic' triggers" );
        return EINVAL;
    }

    if ( rc_hp == 0 )
    {
        p_trigger_item->hw_type = PCT_THRESHOLD;
        p_trigger_item->hw_percent = h_pct;
    }
    else if ( rc_hv == 0 )
    {
        p_trigger_item->hw_type = VOL_THRESHOLD;
        p_trigger_item->hw_volume = h_vol;
    }
    else if ( rc_hc == 0 )
    {
        p_trigger_item->hw_type = COUNT_THRESHOLD;
        p_trigger_item->hw_count = h_cnt;
    }

    if ( rc_lp == 0 )
    {
        p_trigger_item->lw_type = PCT_THRESHOLD;
        p_trigger_item->lw_percent = l_pct;
    }
    else if ( rc_lv == 0 )
    {
        p_trigger_item->lw_type = VOL_THRESHOLD;
        p_trigger_item->lw_volume = l_vol;
    }
    else if ( rc_lc == 0 )
    {
        p_trigger_item->lw_type = COUNT_THRESHOLD;
        p_trigger_item->lw_count = l_cnt;
    }

    /* retrieve check interval parameter */

    rc = GetDurationParam( config_blk, block_name, "check_interval",
                           INT_PARAM_POSITIVE | INT_PARAM_NOT_NULL
                           | PARAM_MANDATORY, &tmpval, NULL,
                           NULL, msg_out );
    if ( rc )
        return rc;
    p_trigger_item->check_interval = tmpval;

    rc = GetBoolParam( config_blk, block_name, "alert_high", 0,
                       &tmpval, NULL, NULL, msg_out );
    /* for backward compatibility */
    if ( rc == ENOENT )
        rc = GetBoolParam( config_blk, block_name, "notify_hw", 0,
                           &tmpval, NULL, NULL, msg_out );
    if ( rc == ENOENT )
        rc = GetBoolParam( config_blk, block_name, "notify", 0,
                           &tmpval, NULL, NULL, msg_out );

    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;
    else if ( rc == 0 )
        p_trigger_item->alert_hw = tmpval;

    rc = GetBoolParam( config_blk, block_name, "alert_low", 0,
                       &tmpval, NULL, NULL, msg_out );
    /* for backward compatibility */
    if ( rc == ENOENT )
        rc = GetBoolParam( config_blk, block_name, "alert_lw", 0,
                           &tmpval, NULL, NULL, msg_out );

    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;
    else if ( rc == 0 )
        p_trigger_item->alert_lw = tmpval;

    CheckUnknownParameters( config_blk, block_name, trigger_expect );

    return 0;

}
Пример #3
0
/** read thresholds params, check their consistency and fills the trigger item.
 *  @param[in] prefix "high" or "low"
 *  @param[in] p_trigger to check compatibility with trigger type and target.
 */
static int read_threshold_params(config_item_t config_blk,
                                 const char *block_name, const char *prefix,
                                 const trigger_item_t *p_trigger,
                                 trigger_value_type_t *type, threshold_u *val,
                                 char *msg_out)
{
    unsigned int cnt = 0;
    uint64_t tmpval;
    int rc;
    char buff[128]; /* oversized for param name */

    rc = GetFloatParam(config_blk, block_name,
                       mk_threshold_param(prefix, "pct", buff),
                       PFLG_POSITIVE | PFLG_ALLOW_PCT_SIGN, &val->percent,
                       NULL, NULL, msg_out);
    if ((rc != 0) && (rc != ENOENT))    /* real error */
        return rc;
    if (rc == 0) {
        *type = PCT_THRESHOLD;
        cnt++;
    }

    rc = GetSizeParam(config_blk, block_name,
                      mk_threshold_param(prefix, "vol", buff),
                      PFLG_POSITIVE, &val->volume, NULL, NULL, msg_out);
    if ((rc != 0) && (rc != ENOENT))
        return rc;
    if (rc == 0) {
        *type = VOL_THRESHOLD;
        cnt++;
    }

    rc = GetInt64Param(config_blk, block_name,
                       mk_threshold_param(prefix, "cnt", buff),
                       PFLG_POSITIVE, &tmpval, NULL, NULL, msg_out);
    if ((rc != 0) && (rc != ENOENT))
        return rc;
    if (rc == 0) {
        *type = COUNT_THRESHOLD;
        /* unsigned long long to uint64_t */
        val->count = (unsigned long long)tmpval;
        cnt++;
    }

    /* check params consistency */
    if (p_trigger->trigger_type == TRIG_ALWAYS) {
        if (cnt > 0) {
            /* in case of 'periodic' triggers, no thresholds are expected */
            strcpy(msg_out,
                   "No high/low threshold expected for 'periodic' trigger");
            return EINVAL;
        } else  /* no extra check needed */
            return 0;
    }

    if (cnt > 1) {
        sprintf(msg_out, "Multiple %s_threshold parameters in trigger", prefix);
        return EINVAL;
    }

    if (cnt == 0) {
        sprintf(msg_out, "No %s_threshold found in trigger (mandatory): "
                " '%s_threshold_pct', '%s_threshold_vol'"
                "or '%s_threshold_cnt' expected", prefix, prefix,
                prefix, prefix);
        return ENOENT;
    }

    /* count threshold is only support for global FS usage */
    if ((*type == COUNT_THRESHOLD)
            && (p_trigger->target_type != TGT_FS)
            && (p_trigger->target_type != TGT_USER)
            && (p_trigger->target_type != TGT_GROUP)) {
        strcpy(msg_out, "Threshold on entry count is only supported "
               "for 'global_usage', 'user_usage' and 'group_usage' triggers");
        return EINVAL;
    }

    return 0;
}