"dun1vio" function vio_couple_key($vio) { return preg_replace('/\d+$/', '', strtolower(trim($vio))); } // Parity of a physical fc port (fcname): "fcs0" -> even, "fcs1" -> odd, ... function fcs_parity($fcs) { if (preg_match('/(\d+)\s*$/', $fcs, $m)) { return (intval($m[1]) % 2 === 0) ? 'even' : 'odd'; } return 'unknown'; } // Balancing rule for one client on a given couple. // Returns null when balanced, otherwise a short problem label (FR). // Expected: exactly 2 paths, on the 2 different VIOs, one even fcs + one odd fcs. function evaluate_client_balance($paths) { $nRows = count($paths); $vios = array_unique(array_map(fn($p) => $p['vio'], $paths)); $evens = array_filter($paths, fn($p) => $p['parity'] === 'even'); $odds = array_filter($paths, fn($p) => $p['parity'] === 'odd'); $unknown = array_filter($paths, fn($p) => $p['parity'] === 'unknown'); if (count($unknown) > 0) { return 'fcs illisible'; } if ($nRows > 2) { return $nRows . ' chemins (plus de 2)'; } if (count($vios) < 2) { return $nRows === 1 ? 'présent sur un seul VIO (chemin manquant)' : 'les 2 chemins sur le même VIO'; } if (count($evens) !== 1 || count($odds) !== 1) { return 'même parité sur les 2 VIO'; } return null; } // Human-readable current distribution of a client's paths. function format_client_paths($paths) { $parts = []; foreach ($paths as $p) { $lbl = $p['parity'] === 'even' ? 'pair' : ($p['parity'] === 'odd' ? 'impair' : '?'); $parts[] = strtoupper($p['vio']) . ':' . $p['fcname'] . ' (' . $lbl . ')'; } return implode(' | ', $parts); } // --------------------------------------------------------------------------- // Data: FC status per VIO // --------------------------------------------------------------------------- $vioRows = Invoke_Infra("select * from X_fcstat_vio"); $groupedVios = []; if (!empty($vioRows)) { foreach ($vioRows as $row) { $vioName = trim($row['vio'] ?? 'UNKNOWN'); $groupedVios[$vioName][] = $row; } } // Group the VIOs into couples, and keep couples + members naturally sorted. $couples = []; foreach ($groupedVios as $vioName => $rows) { $couples[vio_couple_key($vioName)][$vioName] = $rows; } ksort($couples, SORT_NATURAL | SORT_FLAG_CASE); foreach ($couples as $ck => &$members) { ksort($members, SORT_NATURAL | SORT_FLAG_CASE); } unset($members); // --------------------------------------------------------------------------- // Data: client mapping for the balancing check // Error lines (inerr <> 0 or VIOErr <> 0) are excluded (shown on a dedicated page). // --------------------------------------------------------------------------- $cmdbRows = Invoke_Infra("select vio, clintname, fcname, vfcclientname, inerr, VIOErr from X_cmdb_VIO"); $clientPaths = []; // [coupleKey][clintname][] = ['vio','vfc','parity'] if (!empty($cmdbRows)) { foreach ($cmdbRows as $r) { if (intval($r['inerr'] ?? 0) !== 0 || intval($r['VIOErr'] ?? 0) !== 0) { continue; } $vio = strtolower(trim($r['vio'] ?? '')); $client = trim($r['clintname'] ?? ''); if ($vio === '' || $client === '') { continue; } // Redundancy is driven by the PHYSICAL fc port on the VIO (fcname), // not by vfcclientname (client-side virtual adapter, almost always fcs0/fcs1). $fcname = strtolower(trim($r['fcname'] ?? '')); $vfc = strtolower(trim($r['vfcclientname'] ?? '')); $clientPaths[vio_couple_key($vio)][$client][] = [ 'vio' => $vio, 'fcname' => $fcname, 'vfc' => $vfc, 'parity' => fcs_parity($fcname), ]; } } ?>

VIO FC Status

$coupleVios): ?> $rows): ?> getTimestamp() - $tsDate->getTimestamp(); $tsIsOld = $diffSeconds > 86400; } catch (Exception $e) { $tsIsOld = false; } } if ($typeIsDown || $tsIsOld) { $vioHasAlert = true; break; } } $cardColor = $vioHasAlert ? 'red' : 'green'; ?>
getTimestamp() - $tsDate->getTimestamp(); $tsIsOld = $diffSeconds > 86400; } catch (Exception $e) { $tsIsOld = false; } } $rowClass = ($typeIsDown || $tsIsOld) ? 'table-danger fw-bold' : ''; $typeClass = $typeIsDown ? 'bg-danger text-white fw-bold' : ''; $tsClass = $tsIsOld ? 'bg-danger text-white fw-bold' : ''; ?>
FCS FW Speed Type Uports Last TFrames RFrames Fail LossC LossS InvWord InvCRC TS
$paths) { $problem = evaluate_client_balance($paths); if ($problem === null) { $okCount++; } else { $flagged[$clientName] = ['problem' => $problem, 'paths' => $paths]; } } ksort($flagged, SORT_NATURAL | SORT_FLAG_CASE); $hasData = !empty($coupleClients); $balOk = $hasData && empty($flagged); $balColor = !$hasData ? '#6c757d' : ($balOk ? 'green' : 'red'); ?>
Équilibrage — aucune donnée client — OK ( clients vérifiés) — client(s) à corriger ( OK)
$info): ?>
Client Répartition actuelle Problème

No VIO FC data available.