Example #1
0
int rodsMonPerfLog( char *serverName, char *resc, char *output, ruleExecInfo_t *rei ) {

    char condstr[MAX_NAME_LEN], fname[MAX_NAME_LEN], msg[MAX_MESSAGE_SIZE],
         monStatus[MAX_NAME_LEN], suffix[MAX_VALUE], *result;
    const char *delim1 = "#";
    const char *delim2 = ",";
    int index, timestamp, rc1 = 0, rc2 = 0, rc3 = 0, rc4 = 0;
    FILE *foutput;
    time_t tps;
    generalRowInsertInp_t generalRowInsertInp;
    generalAdminInp_t generalAdminInp1, generalAdminInp2;
    genQueryInp_t genQueryInp;
    struct tm *now;

    genQueryOut_t *genQueryOut = NULL;
    tps = time( NULL );
    now = localtime( &tps );

    /* a quick test in order to see if the resource is up or down (needed to update the "status" metadata) */
    if ( strcmp( output, MON_OUTPUT_NO_ANSWER ) == 0 ) {
        strncpy( monStatus, RESC_AUTO_DOWN, MAX_NAME_LEN );
    }
    else {
        strncpy( monStatus, RESC_AUTO_UP, MAX_NAME_LEN );
    }

    std::vector<std::string> output_tokens;
    boost::algorithm::split( output_tokens, output, boost::is_any_of( delim1 ) );
    std::vector<std::string> resc_tokens;
    boost::algorithm::split( resc_tokens, resc, boost::is_any_of( delim2 ) );
    std::vector<std::string> disk_tokens;
    boost::algorithm::split( disk_tokens, output_tokens[4], boost::is_any_of( delim2 ) );
    std::vector<std::string> value_tokens;
    boost::algorithm::split( value_tokens, output_tokens[7], boost::is_any_of( delim2 ) );
    index = 0;
    while ( !resc_tokens[index].empty() ) {
        if ( strcmp( monStatus, RESC_AUTO_DOWN ) == 0 ) {
            disk_tokens[index] = "-1";
            value_tokens[index] = "-1";
        }
        sprintf( msg, "server=%s resource=%s cpu=%s, mem=%s, swp=%s, rql=%s, dsk=%s, nin=%s, nout=%s, dskAv(MB)=%s\n",
                 serverName, resc_tokens[index].c_str(), output_tokens[0].c_str(), output_tokens[1].c_str(), output_tokens[2].c_str(),
                 output_tokens[3].c_str(), disk_tokens[index].c_str(), output_tokens[5].c_str(), output_tokens[6].c_str(), value_tokens[index].c_str() );
        sprintf( suffix, "%d.%d.%d", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday );
        sprintf( fname, "%s.%s", OUTPUT_MON_PERF, suffix );
        /* retrieve the system time */
        timestamp = time( &tps );

        /* log the result into the database as well */
        generalRowInsertInp.tableName = "serverload";
        generalRowInsertInp.arg1 = serverName;
        generalRowInsertInp.arg2 = resc_tokens[index].c_str();
        generalRowInsertInp.arg3 = output_tokens[0].c_str();
        generalRowInsertInp.arg4 = output_tokens[1].c_str();
        generalRowInsertInp.arg5 = output_tokens[2].c_str();
        generalRowInsertInp.arg6 = output_tokens[3].c_str();
        generalRowInsertInp.arg7 = disk_tokens[index].c_str();
        generalRowInsertInp.arg8 = output_tokens[5].c_str();
        generalRowInsertInp.arg9 = output_tokens[6].c_str();
        /* prepare DB request to modify resource metadata: freespace and status */
        generalAdminInp1.arg0 = "modify";
        generalAdminInp1.arg1 = "resource";
        generalAdminInp1.arg2 = resc_tokens[index].c_str();
        generalAdminInp1.arg3 = "freespace";
        generalAdminInp1.arg4 = value_tokens[index].c_str();
        generalAdminInp2.arg0 = "modify";
        generalAdminInp2.arg1 = "resource";
        generalAdminInp2.arg2 = resc_tokens[index].c_str();
        generalAdminInp2.arg3 = "status";
        generalAdminInp2.arg4 = monStatus;
        memset( &genQueryInp, 0, sizeof( genQueryInp ) );
        addInxIval( &genQueryInp.selectInp, COL_R_RESC_STATUS, 1 );
        snprintf( condstr, MAX_NAME_LEN, "= '%s'", resc_tokens[index].c_str() );
        addInxVal( &genQueryInp.sqlCondInp, COL_R_RESC_NAME, condstr );
        genQueryInp.maxRows = MAX_SQL_ROWS;
#ifndef windows_platform
        pthread_mutex_lock( &my_mutex );
#endif
        /* append to the output log file */
        foutput = fopen( fname, "a" );
        if ( foutput != NULL ) {
            fprintf( foutput, "time=%i %s", timestamp, msg );
            // fclose(foutput); // JMC cppcheck - nullptr // cannot close it here. it is used later - hcj
        }

        rc1 = rsGeneralRowInsert( rei->rsComm, &generalRowInsertInp );
        rc2 = rsGeneralAdmin( rei->rsComm, &generalAdminInp1 );
        rc3 = rsGenQuery( rei->rsComm, &genQueryInp, &genQueryOut );
        if ( rc3 >= 0 ) {
            result = genQueryOut->sqlResult[0].value;
            if ( strcmp( result, "\0" ) == 0 || ( strncmp( result, "auto-", 5 ) == 0 && strcmp( result, monStatus ) != 0 ) ) {
                rc4 = rsGeneralAdmin( rei->rsComm, &generalAdminInp2 );
            }
        }
        else {
            rodsLog( LOG_ERROR, "msiServerMonPerf: unable to retrieve the status metadata for the resource %s", resc_tokens[index].c_str() );
        }
#ifndef windows_platform
        pthread_mutex_unlock( &my_mutex );
#endif
        if ( foutput != NULL && rc1 != 0 ) {
            fprintf( foutput, "time=%i : unable to insert the entries for server %s into the iCAT\n",
                     timestamp, serverName );
            fclose( foutput );
        }
        if ( rc2 != 0 ) {
            rodsLog( LOG_ERROR, "msiServerMonPerf: unable to register the free space metadata for the resource %s", resc_tokens[index].c_str() );
        }
        if ( rc4 != 0 ) {
            rodsLog( LOG_ERROR, "msiServerMonPerf: unable to register the status metadata for the resource %s", resc_tokens[index].c_str() );
        }
        index += 1;
    }

    clearGenQueryInp( &genQueryInp );
    freeGenQueryOut( &genQueryOut );

    return 0;
}
/**
 * \fn msiSetQuota(msParam_t *type, msParam_t *name, msParam_t *resource, msParam_t *value, ruleExecInfo_t *rei)
 *
 * \brief Sets disk usage quota for a user or group
 *
 * \module core
 *
 * \since 3.0.x
 *
 * \author  Antoine de Torcy
 * \date    2011-07-07
 *
 *
 * \note  This microservice sets a disk usage quota for a given user or group.
 *          If no resource name is provided the quota will apply across all resources.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] type - a STR_MS_T - Can be either "user" or "group"
 * \param[in] name - a STR_MS_T with the name of the user or group
 * \param[in] resource - Optional - a STR_MS_T with the name of the resource where
 *      the quota will apply, or "total" for the quota to be system-wide.
 * \param[in] value - an INT_MST_T or DOUBLE_MS_T or STR_MS_T with the quota (in bytes)
 * \param[in,out] rei - The RuleExecInfo structure that is automatically
 *    handled by the rule engine. The user does not include rei as a
 *    parameter in the rule invocation.
 *
 * \DolVarDependence rei->uoic->authInfo.authFlag must be >= 5 (local admin)
 * \DolVarModified None
 * \iCatAttrDependence None
 * \iCatAttrModified Updates r_quota_main
 * \sideeffect None
 *
 * \return integer
 * \retval 0 on success
 * \pre None
 * \post None
 * \sa None
 **/
int
msiSetQuota( msParam_t *type, msParam_t *name, msParam_t *resource, msParam_t *value, ruleExecInfo_t *rei ) {
    generalAdminInp_t generalAdminInp;              /* Input for rsGeneralAdmin */
    char quota[21];
    int status;


    /* For testing mode when used with irule --test */
    RE_TEST_MACRO( "    Calling msiSetQuota" )

    /* Sanity checks */
    if ( rei == NULL || rei->rsComm == NULL ) {
        rodsLog( LOG_ERROR, "msiSetQuota: input rei or rsComm is NULL." );
        return ( SYS_INTERNAL_NULL_INPUT_ERR );
    }


    /* Must be called from an admin account */
    if ( rei->uoic->authInfo.authFlag < LOCAL_PRIV_USER_AUTH ) {
        status = CAT_INSUFFICIENT_PRIVILEGE_LEVEL;
        rodsLog( LOG_ERROR, "msiSetQuota: User %s is not local admin. Status = %d",
                 rei->uoic->userName, status );
        return ( status );
    }


    /* Prepare generalAdminInp. It needs to be set up as follows:
     *    generalAdminInp.arg0: "set-quota"
     *    generalAdminInp.arg1: type ("user" or "group")
     *    generalAdminInp.arg2: name of user/group
     *    generalAdminInp.arg3: resource name or "total"
     *    generalAdminInp.arg4: quota value
     *    generalAdminInp.arg5: ""
     *    generalAdminInp.arg6: ""
     *    generalAdminInp.arg7: ""
     *    generalAdminInp.arg8: ""
     *    generalAdminInp.arg9: ""
     */
    memset( &generalAdminInp, 0, sizeof( generalAdminInp_t ) );
    generalAdminInp.arg0 = "set-quota";

    /* Parse type */
    generalAdminInp.arg1 = parseMspForStr( type );
    if ( strcmp( generalAdminInp.arg1, "user" ) && strcmp( generalAdminInp.arg1, "group" ) ) {
        status = USER_BAD_KEYWORD_ERR;
        rodsLog( LOG_ERROR, "msiSetQuota: Invalid user type: %s. Valid types are \"user\" and \"group\"",
                 generalAdminInp.arg1 );
        return ( status );
    }

    /* Parse user/group name */
    generalAdminInp.arg2 = parseMspForStr( name );

    /* parse resource name */
    if ( ( generalAdminInp.arg3 = parseMspForStr( resource ) ) == NULL ) {
        generalAdminInp.arg3 = "total";
    }

    /* Parse value */
    if ( value->type && !strcmp( value->type, STR_MS_T ) ) {
        generalAdminInp.arg4 = ( char * )value->inOutStruct;
    }
    else if ( value->type && !strcmp( value->type, INT_MS_T ) ) {
        snprintf( quota, 11, "%d", *( int * )value->inOutStruct );
        generalAdminInp.arg4 = quota;
    }
    else if ( value->type && !strcmp( value->type, DOUBLE_MS_T ) ) {
        snprintf( quota, 21, "%lld", *( rodsLong_t * )value->inOutStruct );
        generalAdminInp.arg4 = quota;
    }
    else {
        status = USER_PARAM_TYPE_ERR;
        rodsLog( LOG_ERROR, "msiSetQuota: Invalid type for param value. Status = %d", status );
        return ( status );
    }

    /* Fill up the rest of generalAdminInp */
    generalAdminInp.arg5 = "";
    generalAdminInp.arg6 = "";
    generalAdminInp.arg7 = "";
    generalAdminInp.arg8 = "";
    generalAdminInp.arg9 = "";


    /* Call rsGeneralAdmin */
    status = rsGeneralAdmin( rei->rsComm, &generalAdminInp );


    /* Done */
    return status;
}