diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee75f62b0..471fa8312 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@
- [Notifications] New notification page to provide important information about XOA (PR [#3904](https://github.com/vatesfr/xen-orchestra/pull/3904))
- [VM] Ability to export a VM with zstd compression [#3773](https://github.com/vatesfr/xen-orchestra/issues/3773) (PR [#3891](https://github.com/vatesfr/xen-orchestra/pull/3891))
- [Host/network] Display PIF speed [#3887](https://github.com/vatesfr/xen-orchestra/issues/3887) (PR [#3901](https://github.com/vatesfr/xen-orchestra/pull/3901))
+- [SR] Display iscsi paths and mark the SR with a yellow dot if one path is not available. [#3659](https://github.com/vatesfr/xen-orchestra/issues/3659) (PR [#3829](https://github.com/vatesfr/xen-orchestra/pull/3829))
### Bug fixes
diff --git a/packages/xo-server/src/xapi-object-to-xo.js b/packages/xo-server/src/xapi-object-to-xo.js
index 06593f141..5299668ff 100644
--- a/packages/xo-server/src/xapi-object-to-xo.js
+++ b/packages/xo-server/src/xapi-object-to-xo.js
@@ -477,6 +477,7 @@ const TRANSFORMS = {
host: link(obj, 'host'),
SR: link(obj, 'SR'),
device_config: obj.device_config,
+ otherConfig: obj.other_config,
}
},
diff --git a/packages/xo-web/src/common/intl/messages.js b/packages/xo-web/src/common/intl/messages.js
index abda778f0..30312a622 100644
--- a/packages/xo-web/src/common/intl/messages.js
+++ b/packages/xo-web/src/common/intl/messages.js
@@ -29,10 +29,14 @@ const messages = {
noValue: 'None',
compression: 'Compression',
multipathing: 'Multipathing',
+ multipathingDisabled: 'Multipathing disabled',
enableMultipathing: 'Enable multipathing',
disableMultipathing: 'Disable multipathing',
enableAllHostsMultipathing: 'Enable all hosts multipathing',
disableAllHostsMultipathing: 'Disable all hosts multipathing',
+ paths: 'Paths',
+ pbdDisconnected: 'PBD disconnected',
+ hasInactivePath: 'Has an inactive path',
// ----- Modals -----
alertOk: 'OK',
@@ -770,7 +774,10 @@ const messages = {
hostStatus: 'Status',
hostBuildNumber: 'Build number',
hostIscsiName: 'iSCSI name',
+ hostNoIscsiSr: 'Not connected to an iSCSI SR',
hostMultipathingSrs: 'Click to see concerned SRs',
+ hostMultipathingPaths:
+ '{nActives, number} of {nPaths, number} path{nPaths, plural, one {} other {s}} ({ nSessions, number } iSCSI session{nSessions, plural, one {} other {s}})',
hostMultipathingWarning:
'The host{nHosts, plural, one {} other {s}} will lose the connection to the SRs. Do you want to continue?',
hostXenServerVersion: 'Version',
diff --git a/packages/xo-web/src/common/utils.js b/packages/xo-web/src/common/utils.js
index d5dd50140..2eb5b9196 100644
--- a/packages/xo-web/src/common/utils.js
+++ b/packages/xo-web/src/common/utils.js
@@ -593,3 +593,11 @@ export const generateRandomId = () =>
Math.random()
.toString(36)
.slice(2)
+
+// ===================================================================
+
+// it returns [nActivePaths, nPaths]
+export const getIscsiPaths = pbd => {
+ const pathsInfo = pbd.otherConfig[`mpath-${pbd.device_config.SCSIid}`]
+ return pathsInfo !== undefined ? JSON.parse(pathsInfo) : []
+}
diff --git a/packages/xo-web/src/xo-app/home/sr-item.js b/packages/xo-web/src/xo-app/home/sr-item.js
index 108cae8b7..c0381cc50 100644
--- a/packages/xo-web/src/xo-app/home/sr-item.js
+++ b/packages/xo-web/src/xo-app/home/sr-item.js
@@ -1,16 +1,14 @@
import _ from 'intl'
import Component from 'base-component'
-import sum from 'lodash/sum'
import Ellipsis, { EllipsisContainer } from 'ellipsis'
import Icon from 'icon'
import Link, { BlockLink } from 'link'
-import map from 'lodash/map'
import React from 'react'
import SingleLineRow from 'single-line-row'
-import size from 'lodash/size'
import Tooltip from 'tooltip'
import HomeTags from 'home-tags'
import { Col } from 'grid'
+import { map, size, sum, some } from 'lodash'
import { Text } from 'editable'
import {
createGetObject,
@@ -25,7 +23,7 @@ import {
removeTag,
setDefaultSr,
} from 'xo'
-import { connectStore, formatSizeShort } from 'utils'
+import { connectStore, formatSizeShort, getIscsiPaths } from 'utils'
import styles from './index.css'
@@ -43,10 +41,11 @@ import styles from './index.css'
isSrShared
),
status: createSelector(
+ (_, props) => Boolean(props.item.sm_config.multipathable),
createGetObjectsOfType('PBD').filter((_, props) => pbd =>
pbd.SR === props.item.id
),
- pbds => {
+ (multipathable, pbds) => {
const nbAttached = sum(map(pbds, pbd => (pbd.attached ? 1 : 0)))
const nbPbds = size(pbds)
if (!nbPbds) {
@@ -55,8 +54,18 @@ import styles from './index.css'
if (!nbAttached) {
return 0
}
+ if (nbAttached < nbPbds) {
+ return 1
+ }
- return nbAttached < nbPbds ? 1 : 2
+ const hasInactivePath =
+ multipathable &&
+ some(pbds, pbd => {
+ const [nActives, nPaths] = getIscsiPaths(pbd)
+ return nActives !== nPaths
+ })
+
+ return hasInactivePath ? 3 : 2
}
),
})
@@ -99,6 +108,12 @@ export default class SrItem extends Component {