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; }