diff --git a/pkg/harvester/config/doc-links.js b/pkg/harvester/config/doc-links.js
index 1542d906..a76df6fb 100644
--- a/pkg/harvester/config/doc-links.js
+++ b/pkg/harvester/config/doc-links.js
@@ -9,4 +9,5 @@ export const DOC = {
SUPPORT_BUNDLE_NAMESPACES: `/advanced/index/#support-bundle-namespaces`,
VPC_CONFIGURATION_EXAMPLES: `/networking/kubeovn-vpc#vpc-peering-configuration-examples`,
NETWORK_POLICY: `/networking/kubeovn-vm-isolation/#network-policies`,
+ TRANSPARENT_HUGEPAGES: `https://docs.kernel.org/admin-guide/mm/transhuge.html`,
};
diff --git a/pkg/harvester/detail/harvesterhci.io.host/HarvesterHugepages.vue b/pkg/harvester/detail/harvesterhci.io.host/HarvesterHugepages.vue
new file mode 100644
index 00000000..b4f60394
--- /dev/null
+++ b/pkg/harvester/detail/harvesterhci.io.host/HarvesterHugepages.vue
@@ -0,0 +1,119 @@
+
+
+
+
+
+ {{ t('harvester.host.hugepages.meminfo') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pkg/harvester/detail/harvesterhci.io.host/index.vue b/pkg/harvester/detail/harvesterhci.io.host/index.vue
index a2734e15..4a8a9c45 100644
--- a/pkg/harvester/detail/harvesterhci.io.host/index.vue
+++ b/pkg/harvester/detail/harvesterhci.io.host/index.vue
@@ -27,6 +27,7 @@ import Instance from './VirtualMachineInstance';
import Disk from './HarvesterHostDisk';
import VlanStatus from './VlanStatus';
import HarvesterKsmtuned from './HarvesterKsmtuned.vue';
+import HarvesterHugepages from './HarvesterHugepages.vue';
import HarvesterSeeder from './HarvesterSeeder';
const LONGHORN_SYSTEM = 'longhorn-system';
@@ -46,6 +47,7 @@ export default {
VlanStatus,
LabelValue,
HarvesterKsmtuned,
+ HarvesterHugepages,
Loading,
SortableTable,
HarvesterSeeder,
@@ -209,6 +211,12 @@ export default {
return !!this.$store.getters[`${ inStore }/schemaFor`](HCI.KSTUNED);
},
+ hasHugepagesSchema() {
+ const inStore = this.$store.getters['currentProduct'].inStore;
+
+ return !!this.$store.getters[`${ inStore }/schemaFor`](HCI.HUGEPAGES);
+ },
+
hasBlockDevicesSchema() {
return !!this.$store.getters['harvester/schemaFor'](HCI.BLOCK_DEVICE);
},
@@ -468,6 +476,16 @@ export default {
/>
+
+
+
+
+import LabeledSelect from '@shell/components/form/LabeledSelect.vue';
+import { HCI } from '../../types';
+import { DOC } from '../../config/doc-links';
+
+export const hugepagesTHPEnabledMode = [{
+ label: 'Always',
+ value: 'always',
+}, {
+ label: 'Madvise',
+ value: 'madvise',
+}, {
+ label: 'Never',
+ value: 'never',
+}];
+
+export const hugepagesTHPShmemEnabledMode = [{
+ label: 'Always',
+ value: 'always',
+}, {
+ label: 'Within Size',
+ value: 'within_size',
+}, {
+ label: 'Advise',
+ value: 'advise',
+}, {
+ label: 'Never',
+ value: 'never',
+}, {
+ label: 'Deny',
+ value: 'deny',
+}, {
+ label: 'Force',
+ value: 'force',
+}];
+
+export const hugepagesTHPDefragMode = [{
+ label: 'Always',
+ value: 'always',
+}, {
+ label: 'Defer',
+ value: 'defer',
+}, {
+ label: 'Defer+Madvise',
+ value: 'defer+madvise',
+}, {
+ label: 'Madvise',
+ value: 'madvise',
+}, {
+ label: 'Never',
+ value: 'never'
+}];
+
+export default {
+ name: 'HarvesterHugepages',
+ components: { LabeledSelect },
+
+ props: {
+ node: {
+ type: Object,
+ required: true,
+ },
+
+ registerBeforeHook: {
+ type: Function,
+ required: true,
+ },
+ },
+
+ computed: {
+ docsTransparentHugepagesLink() {
+ return DOC.TRANSPARENT_HUGEPAGES;
+ },
+ },
+
+ methods: {
+ async saveHugepages() {
+ this.hugepages['spec'] = this.spec;
+
+ await this.hugepages.save().catch((reason) => {
+ if (reason?.type === 'error') {
+ this.$store.dispatch('growl/error', {
+ title: this.t('harvester.notification.title.error'),
+ message: reason?.message,
+ }, { root: true });
+
+ return Promise.reject(new Error('saveHugepages error'));
+ }
+ });
+ },
+ },
+
+ async fetch() {
+ const inStore = this.$store.getters['currentProduct'].inStore;
+
+ const hash = await this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.HUGEPAGES });
+
+ this.hugepages = hash.find((node) => {
+ return node.id === this.node.id;
+ });
+ this.spec = this.hugepages.spec;
+ },
+
+ data() {
+ return {
+ hugepages: {},
+ spec: { transparent: {} },
+ hugepagesTHPEnabledMode,
+ hugepagesTHPShmemEnabledMode,
+ hugepagesTHPDefragMode,
+ };
+ },
+
+ created() {
+ this.registerBeforeHook(this.saveHugepages, 'saveHugepages');
+ },
+};
+
+
+
+
+
diff --git a/pkg/harvester/edit/harvesterhci.io.host/index.vue b/pkg/harvester/edit/harvesterhci.io.host/index.vue
index 3f042bb1..4fd44bec 100644
--- a/pkg/harvester/edit/harvesterhci.io.host/index.vue
+++ b/pkg/harvester/edit/harvesterhci.io.host/index.vue
@@ -28,6 +28,7 @@ import { HCI } from '../../types';
import HarvesterDisk from './HarvesterDisk';
import HarvesterSeeder from './HarvesterSeeder';
import HarvesterKsmtuned from './HarvesterKsmtuned';
+import HarvesterHugepages from './HarvesterHugepages';
import Tags from '../../components/DiskTags';
import { LVM_DRIVER } from '../../models/harvester/storage.k8s.io.storageclass';
import isEqual from 'lodash/isEqual';
@@ -50,6 +51,7 @@ export default {
ArrayListGrouped,
HarvesterDisk,
HarvesterKsmtuned,
+ HarvesterHugepages,
ButtonDropdown,
KeyValue,
Banner,
@@ -225,6 +227,12 @@ export default {
return !!this.$store.getters[`${ inStore }/schemaFor`](HCI.KSTUNED);
},
+ hasHugepagesSchema() {
+ const inStore = this.$store.getters['currentProduct'].inStore;
+
+ return !!this.$store.getters[`${ inStore }/schemaFor`](HCI.HUGEPAGES);
+ },
+
hasBlockDevicesSchema() {
const inStore = this.$store.getters['currentProduct'].inStore;
@@ -647,6 +655,17 @@ export default {
+
+
+
+ enabled: Enabled
+ shmemEnabled: Shared Memory Enabled
+ defrag: Defragmentation
+ status:
+ anon: Anonymous Hugepages (bytes)
+ size: Default Hugepage Size (bytes)
+ total: Total Hugepages
+ free: Free Hugepages
+ rsvd: Reserved Hugepages
+ surp: Surplus Hugepages
disk:
add: Add Disk
path:
diff --git a/pkg/harvester/types.ts b/pkg/harvester/types.ts
index b4f7c6ea..6f7bd64b 100644
--- a/pkg/harvester/types.ts
+++ b/pkg/harvester/types.ts
@@ -37,6 +37,7 @@ export const HCI = {
STORAGE: 'harvesterhci.io.storage',
RESOURCE_QUOTA: 'harvesterhci.io.resourcequota',
KSTUNED: 'node.harvesterhci.io.ksmtuned',
+ HUGEPAGES: 'node.harvesterhci.io.hugepage',
PCI_DEVICE: 'devices.harvesterhci.io.pcidevice',
PCI_CLAIM: 'devices.harvesterhci.io.pcideviceclaim',
SR_IOV: 'devices.harvesterhci.io.sriovnetworkdevice',