Compare commits

...

33 Commits

Author SHA1 Message Date
Andrius Štikonas 8d2ebfeaed Merge branch 'master' into raid-support 2020-11-14 01:32:31 +00:00
Andrius Štikonas b5e6e1e544 Merge branch 'master' into raid-support 2020-10-04 01:08:46 +01:00
Caio Carvalho 0dcf87d1c4 Merge branch 'master' into raid-support 2019-04-03 15:46:40 -06:00
Andrius Štikonas 6b9dfa2d1e Merge branch 'master' into raid-support 2019-01-06 17:20:23 +00:00
Caio Carvalho c8da38aef5 RAID devices should show its partition table type 2018-10-13 10:33:23 -03:00
Caio Carvalho bbe392b5d2 Support RAID resize 2018-10-12 17:01:38 -03:00
Caio Carvalho e8cb85a15f Changing onRemoveVolumeGroup to accept RAID 2018-10-11 17:43:53 -03:00
Caio Carvalho 5727717776 Activating RAID through GUI 2018-10-11 15:01:46 -03:00
Caio Carvalho 495b2d5b42 Improving volumegroupwidgetbase layout 2018-09-14 18:38:01 -03:00
Caio Carvalho a680ad0be2 Changing RAID name validation. 2018-09-14 09:23:10 -03:00
Caio Carvalho 14b286ede7 Initial implementation of RAID activation. 2018-08-28 15:06:01 -03:00
Caio Carvalho bdc0a24508 Don't resize RAID if it is not active. 2018-08-24 12:23:17 -03:00
Caio Carvalho 702a34d6a4 DeactivateVolumeGroup cast to VolumeManagerDevice instead of LvmDevice 2018-08-19 16:59:48 +02:00
Caio Carvalho 45217f4b7e Allowing reset RAID config file path to default. 2018-08-18 22:52:45 +02:00
Caio Carvalho 170a0fadde Rescanning after RAID config file change 2018-08-16 23:56:01 +02:00
Caio Carvalho 3c79839152 Fix in raid configuration 2018-08-16 14:59:49 +02:00
Caio Carvalho 8eb4393ded Updating RAID configuration to use partitionmanager.kcfg 2018-08-16 14:17:36 +02:00
Caio Carvalho 7b1ca5fe72 Setting RAID configuration file path through GUI. 2018-08-16 01:20:07 +02:00
Andrius Štikonas 863e7cafaa Merge branch 'master' into raid-support 2018-08-15 10:48:29 +00:00
Caio Carvalho 94d1c1d9c6 Only load partitions without active raid while creating. 2018-08-14 15:18:33 +02:00
Caio Carvalho 57a2072686 Updating ok button validation 2018-08-14 12:17:10 +02:00
Caio Carvalho c8cdebf5fb Merge branch 'raid-support' of git://anongit.kde.org/partitionmanager into raid-support 2018-08-14 02:14:42 +02:00
Caio Carvalho fa0b7b838c Check for VolumeManagerDevice instead of LVM. 2018-08-14 02:13:46 +02:00
Caio Carvalho 4312ce3e7f Check for VolumeManagerDevice inside of LVM. 2018-08-14 02:03:49 +02:00
Caio Carvalho 04db81aaba Cast to VolumeManagerDevice instead of LvmDevice. 2018-08-14 01:52:03 +02:00
Caio Carvalho 39d0477ca0 Fixing RAID information on CreateVolumeGroupDialog. 2018-08-14 01:22:50 +02:00
Caio Carvalho a8ae8d5419 Fixing RAID creation GUI. 2018-08-13 20:09:52 -03:00
Caio Carvalho eec9801582 Updating VolumeGroupDialog constraints. 2018-08-13 17:59:42 -03:00
Caio Carvalho f81f6fbff2 Including RAID components in VolumeGroupWidget 2018-08-13 16:42:18 -03:00
Caio Carvalho 4365a0e9d2 Ignore unallocated partitions in RAID creation 2018-08-09 12:16:34 -03:00
Caio Carvalho a7680ae169 Create RAID with LinuxRaidMember, Unformatted or Unknown partitions 2018-08-08 17:24:27 -03:00
Caio Carvalho 50af43636d Allowing only LinuxRaidMember partitions for RAID creation. 2018-08-08 16:39:25 -03:00
Caio Carvalho a87f042468 Load partitions for RAID in CreateVolumeGroupDialog. 2018-07-31 16:34:32 -03:00
23 changed files with 657 additions and 243 deletions

View File

@ -1,6 +1,7 @@
/*
SPDX-FileCopyrightText: 2010 Volker Lanz <vl@fidra.de>
SPDX-FileCopyrightText: 2014-2017 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
SPDX-License-Identifier: GPL-3.0-or-later
*/
@ -11,16 +12,20 @@
#include <util/helpers.h>
#include <QComboBox>
#include <QFileDialog>
#include <KPluginMetaData>
#include <config.h>
#include <kpmcore/core/softwareraid.h>
AdvancedPageWidget::AdvancedPageWidget(QWidget* parent) :
QWidget(parent)
{
setupUi(this);
setupDialog();
connect(selectRaidFileButton, &QPushButton::clicked, this, &AdvancedPageWidget::searchForRaidConfigFile);
}
QString AdvancedPageWidget::backend() const
@ -48,4 +53,36 @@ void AdvancedPageWidget::setupDialog()
comboBackend().addItem(backend.name());
setBackend(Config::backend());
setRaidConfigurationFile(Config::raidConfigurationFilePath());
}
QString AdvancedPageWidget::raidConfigurationFile() const
{
return raidConfigFilePath->text().trimmed();
}
void AdvancedPageWidget::setRaidConfigurationFile(const QString &file)
{
raidConfigFilePath->clear();
raidConfigFilePath->insert(file);
}
void AdvancedPageWidget::searchForRaidConfigFile()
{
QPointer<QFileDialog> dialog = new QFileDialog(this, QStringLiteral("Select Software RAID configuration file"),
QStringLiteral("/"));
dialog->setFileMode(QFileDialog::FileMode::ExistingFile);
dialog->setNameFilter(QStringLiteral("Configuration files (*.conf)"));
auto updateConfig = [this](const QString& file){
if (!file.isEmpty()) {
raidConfigFilePath->clear();
raidConfigFilePath->insert(file);
}
};
connect(dialog, &QFileDialog::fileSelected, updateConfig);
dialog->exec();
}

View File

@ -1,12 +1,12 @@
/*
SPDX-FileCopyrightText: 2010 Volker Lanz <vl@fidra.de>
SPDX-FileCopyrightText: 2014-2017 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
SPDX-License-Identifier: GPL-3.0-or-later
*/
#if !defined(ADVANCEDPAGEWIDGET_H)
#ifndef ADVANCEDPAGEWIDGET_H
#define ADVANCEDPAGEWIDGET_H
#include "ui_configurepageadvanced.h"
@ -30,10 +30,19 @@ public:
const QComboBox& comboBackend() const {
return *m_ComboBackend;
}
const QLineEdit& raidConfigurationLine() const {
return *raidConfigFilePath;
}
QString backend() const;
void setBackend(const QString& name);
QString raidConfigurationFile() const;
void setRaidConfigurationFile(const QString& file);
protected Q_SLOTS:
void searchForRaidConfigFile();
private:
void setupDialog();
};

View File

@ -29,6 +29,7 @@
#include <QIcon>
#include <config.h>
#include <kpmcore/core/softwareraid.h>
ConfigureOptionsDialog::ConfigureOptionsDialog(QWidget* parent, const OperationStack& ostack, const QString& name) :
KConfigDialog(parent, name, Config::self()),
@ -49,6 +50,7 @@ ConfigureOptionsDialog::ConfigureOptionsDialog(QWidget* parent, const OperationS
addPage(&advancedPageWidget(), xi18nc("@title:tab advanced application settings", "Advanced"), QStringLiteral("preferences-other"), i18n("Advanced Settings"));
connect(&advancedPageWidget().comboBackend(), qOverload<int>(&QComboBox::activated), this, &ConfigureOptionsDialog::onComboDefaultFileSystemActivated);
connect(&advancedPageWidget().raidConfigurationLine(), &QLineEdit::textChanged, this, &ConfigureOptionsDialog::onRaidConfigFilePathActivated);
KConfigGroup kcg(KSharedConfig::openConfig(), "configureOptionsDialogs");
restoreGeometry(kcg.readEntry<QByteArray>("Geometry", QByteArray()));
@ -83,6 +85,11 @@ void ConfigureOptionsDialog::updateSettings()
changed = true;
}
if (advancedPageWidget().raidConfigurationFile() != Config::raidConfigurationFilePath()) {
Config::setRaidConfigurationFilePath(advancedPageWidget().raidConfigurationFile());
changed = true;
}
if (changed)
Q_EMIT KConfigDialog::settingsChanged(i18n("General Settings"));
}
@ -98,6 +105,9 @@ bool ConfigureOptionsDialog::hasChanged()
if (advancedPageWidget().isVisible()) {
kcItem = Config::self()->findItem(QStringLiteral("backend"));
result = result || !kcItem->isEqual(advancedPageWidget().backend());
kcItem = Config::self()->findItem(QStringLiteral("raidConfigurationFilePath"));
result = result || !kcItem->isEqual(advancedPageWidget().raidConfigurationFile());
}
return result;
@ -122,8 +132,10 @@ void ConfigureOptionsDialog::updateWidgetsDefault()
generalPageWidget().setDefaultFileSystem(GuiHelpers::defaultFileSystem());
generalPageWidget().radioButton->setChecked(true);
if (advancedPageWidget().isVisible())
if (advancedPageWidget().isVisible()) {
advancedPageWidget().setBackend(CoreBackendManager::defaultBackendName());
advancedPageWidget().setRaidConfigurationFile(SoftwareRAID::getDefaultRaidConfigFile());
}
Config::self()->useDefaults(useDefaults);
}

View File

@ -33,6 +33,9 @@ protected:
void onShredSourceActivated() {
settingsChangedSlot();
}
void onRaidConfigFilePathActivated() {
settingsChangedSlot();
}
void onComboBackendActivated(int);
GeneralPageWidget& generalPageWidget() {

View File

@ -12,12 +12,18 @@ SPDX-License-Identifier: GPL-3.0-or-later
<rect>
<x>0</x>
<y>0</y>
<width>449</width>
<width>511</width>
<height>420</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>420</height>
</size>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -32,7 +38,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Active backend:</string>
<string>Acti&amp;ve backend:</string>
</property>
<property name="buddy">
<cstring>m_ComboBackend</cstring>
@ -45,7 +51,47 @@ SPDX-License-Identifier: GPL-3.0-or-later
</layout>
</widget>
</item>
<item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Software RAID configuration</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Configuration file:</string>
</property>
<property name="buddy">
<cstring>raidConfigFilePath</cstring>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLineEdit" name="raidConfigFilePath">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="selectRaidFileButton">
<property name="text">
<string>Select File</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -56,11 +102,11 @@ SPDX-License-Identifier: GPL-3.0-or-later
<property name="title">
<string>Units</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Preferred unit:</string>
<string>Preferred &amp;unit:</string>
</property>
<property name="buddy">
<cstring>m_ComboBackend</cstring>

View File

@ -13,6 +13,7 @@
#include <core/device.h>
#include <core/lvmdevice.h>
#include <core/partitiontable.h>
#include <core/softwareraid.h>
#include <fs/lvm2_pv.h>
@ -29,9 +30,14 @@
#include <KLocalizedString>
#include <KSharedConfig>
CreateVolumeGroupDialog::CreateVolumeGroupDialog(QWidget* parent, QString& vgName, QVector<const Partition*>& partList, qint32& peSize, QList<Device*> devices, QList<Operation*> pendingOps)
CreateVolumeGroupDialog::CreateVolumeGroupDialog(QWidget* parent, QString& vgName, QVector<const Partition*>& partList,
QString& type, qint32& raidLevel, qint32& chunkSize, qint32& peSize,
QList<Device*> devices, QList<Operation*> pendingOps)
: VolumeGroupDialog(parent, vgName, partList)
, m_type(type)
, m_PESize(peSize)
, m_raidLevel(raidLevel)
, m_chunkSize(chunkSize)
, m_Devices(devices)
, m_PendingOps(pendingOps)
{
@ -41,58 +47,13 @@ CreateVolumeGroupDialog::CreateVolumeGroupDialog(QWidget* parent, QString& vgNam
setupConstraints();
setupConnections();
// disable volume type and PE size for now, until the features are implemented.
dialogWidget().volumeType().setEnabled(false);
KConfigGroup kcg(KSharedConfig::openConfig(), "createVolumeDialog");
restoreGeometry(kcg.readEntry<QByteArray>("Geometry", QByteArray()));
}
void CreateVolumeGroupDialog::setupDialog()
{
for (const auto &p : std::as_const(LVM::pvList::list())) {
bool toBeDeleted = false;
// Ignore partitions that are going to be deleted
for (const auto &o : std::as_const(m_PendingOps)) {
if (dynamic_cast<DeleteOperation *>(o) && o->targets(*p.partition())) {
toBeDeleted = true;
break;
}
}
if (toBeDeleted)
continue;
if (!p.isLuks() && p.vgName().isEmpty() && !LvmDevice::s_DirtyPVs.contains(p.partition()))
dialogWidget().listPV().addPartition(*p.partition(), false);
}
for (const Device *d : std::as_const(m_Devices)) {
if (d->partitionTable() != nullptr) {
for (const Partition *p : std::as_const(d->partitionTable()->children())) {
// Looking if there is another VG creation that contains this partition
if (LvmDevice::s_DirtyPVs.contains(p))
continue;
// Including new LVM PVs (that are currently in OperationStack and that aren't at other VG creation)
if (p->state() == Partition::State::New) {
if (p->fileSystem().type() == FileSystem::Type::Lvm2_PV)
dialogWidget().listPV().addPartition(*p, false);
else if (p->fileSystem().type() == FileSystem::Type::Luks || p->fileSystem().type() == FileSystem::Type::Luks2) {
FileSystem *fs = static_cast<const FS::luks *>(&p->fileSystem())->innerFS();
if (fs->type() == FileSystem::Type::Lvm2_PV)
dialogWidget().listPV().addPartition(*p, false);
}
}
}
}
}
for (const Partition *p : std::as_const(LvmDevice::s_OrphanPVs))
if (!LvmDevice::s_DirtyPVs.contains(p))
dialogWidget().listPV().addPartition(*p, false);
updatePartitionList();
}
void CreateVolumeGroupDialog::setupConnections()
@ -101,16 +62,90 @@ void CreateVolumeGroupDialog::setupConnections()
connect(&dialogWidget().spinPESize(), qOverload<int>(&QSpinBox::valueChanged), this, &CreateVolumeGroupDialog::onSpinPESizeChanged);
}
void CreateVolumeGroupDialog::accept()
void CreateVolumeGroupDialog::updatePartitionList()
{
if (dialogWidget().volumeType().currentText() == QStringLiteral("LVM")) {
dialogWidget().listPV().clear();
for (const auto &p : std::as_const(LVM::pvList::list())) {
bool toBeDeleted = false;
// Ignore partitions that are going to be deleted
for (const auto &o : std::as_const(m_PendingOps)) {
if (dynamic_cast<DeleteOperation *>(o) && o->targets(*p.partition())) {
toBeDeleted = true;
break;
}
}
if (toBeDeleted)
continue;
if (!p.isLuks() && p.vgName() == QString() && !LvmDevice::s_DirtyPVs.contains(p.partition()))
dialogWidget().listPV().addPartition(*p.partition(), false);
}
for (const Device *d : qAsConst(m_Devices)) {
if (d->partitionTable() != nullptr) {
for (const Partition *p : qAsConst(d->partitionTable()->children())) {
// Looking if there is another VG creation that contains this partition
if (LvmDevice::s_DirtyPVs.contains(p))
continue;
// Including new LVM PVs (that are currently in OperationStack and that aren't at other VG creation)
if (p->state() == Partition::State::New) {
if (p->fileSystem().type() == FileSystem::Type::Lvm2_PV)
dialogWidget().listPV().addPartition(*p, false);
else if (p->fileSystem().type() == FileSystem::Type::Luks || p->fileSystem().type() == FileSystem::Type::Luks2) {
FileSystem *fs = static_cast<const FS::luks *>(&p->fileSystem())->innerFS();
if (fs->type() == FileSystem::Type::Lvm2_PV)
dialogWidget().listPV().addPartition(*p, false);
}
}
}
}
}
for (const Partition *p : std::as_const(LvmDevice::s_OrphanPVs))
if (!LvmDevice::s_DirtyPVs.contains(p))
dialogWidget().listPV().addPartition(*p, false);
}
else if (dialogWidget().volumeType().currentText() == QStringLiteral("RAID")) {
for (const Device *d : std::as_const(m_Devices)) {
if (d->type() != Device::Type::SoftwareRAID_Device && d->partitionTable() != nullptr) {
for (const Partition *p : std::as_const(d->partitionTable()->children())) {
if (((p->fileSystem().type() == FileSystem::Type::LinuxRaidMember &&
SoftwareRAID::getRaidArrayName(p->partitionPath()).isEmpty()) ||
p->fileSystem().type() == FileSystem::Type::Unformatted ||
p->fileSystem().type() == FileSystem::Type::Unknown) &&
!p->roles().has(PartitionRole::Role::Unallocated))
dialogWidget().listPV().addPartition(*p, false);
}
}
}
}
}
void CreateVolumeGroupDialog::accept()
{
QString& tname = targetName();
tname = dialogWidget().vgName().text();
targetPVList().append(dialogWidget().listPV().checkedItems());
QString& vgType = type();
vgType = dialogWidget().volumeType().currentText();
qint32& pesize = peSize();
pesize = dialogWidget().spinPESize().value();
qint32& raidlvl = raidLevel();
raidlvl = dialogWidget().raidLevel().currentText().toInt();
qint32& chunk = chunkSize();
chunk = dialogWidget().chunkSize().value();
QDialog::accept();
}
@ -118,21 +153,33 @@ void CreateVolumeGroupDialog::updateOkButtonStatus()
{
VolumeGroupDialog::updateOkButtonStatus();
if (okButton->isEnabled())
if (okButton->isEnabled()) {
okButton->setEnabled(!dialogWidget().listPV().checkedItems().empty());
if (dialogWidget().volumeType().currentText() == QStringLiteral("RAID")) {
bool ok = dialogWidget().listPV().checkedItems().count() >= 2 &&
dialogWidget().vgName().text().length() > 2;
QString name = dialogWidget().vgName().text();
if (ok)
ok = dialogWidget().vgName().text().startsWith(
name.back().isDigit() ? QStringLiteral("md") : QStringLiteral("md/"));
okButton->setEnabled(ok);
}
}
}
void CreateVolumeGroupDialog::onVGNameChanged(const QString& vgName)
{
for (const auto &d : m_Devices) {
if (dynamic_cast<LvmDevice*>(d)) {
if (d->name() == vgName) {
m_IsValidName = false;
break;
}
else
m_IsValidName = true;
if (d->name() == vgName) {
m_IsValidName = false;
break;
}
else
m_IsValidName = true;
}
updateOkButtonStatus();
}

View File

@ -6,7 +6,6 @@
SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef CREATEVOLUMEGROUPDIALOG_H
#define CREATEVOLUMEGROUPDIALOG_H
@ -23,23 +22,42 @@ class CreateVolumeGroupDialog : public VolumeGroupDialog
Q_DISABLE_COPY(CreateVolumeGroupDialog)
public:
CreateVolumeGroupDialog(QWidget* parent, QString& vgName, QVector<const Partition*>& pvList, qint32& peSize, QList<Device*> devices, QList<Operation*> pendingOps = QList<Operation *>());
CreateVolumeGroupDialog(QWidget* parent, QString& vgName, QVector<const Partition*>& pvList, QString& type,
qint32& raidLevel, qint32& chunkSize, qint32& peSize, QList<Device*> devices,
QList<Operation*> pendingOps = QList<Operation *>());
protected:
void accept() override;
void setupDialog() override;
void setupConnections() override;
void updatePartitionList() override;
protected:
virtual void updateOkButtonStatus() override;
void onVGNameChanged(const QString& vgname);
void onSpinPESizeChanged(int newsize);
qint32& peSize() {
QString& type() const {
return m_type;
}
qint32& peSize() const {
return m_PESize;
}
qint32& raidLevel() const {
return m_raidLevel;
}
qint32& chunkSize() const {
return m_chunkSize;
}
QString& m_type;
qint32& m_PESize;
qint32& m_raidLevel;
qint32& m_chunkSize;
private:
const QList<Device*> m_Devices; // List of all devices found on the system

View File

@ -75,6 +75,10 @@ void DevicePropsDialog::setupDialog()
type = (device().partitionTable()->isReadOnly())
? xi18nc("@label device", "%1 (read only)", device().partitionTable()->typeName())
: device().partitionTable()->typeName();
if (device().type() == Device::Type::SoftwareRAID_Device)
type += QStringLiteral(" [Software RAID Device]");
maxPrimaries = QStringLiteral("%1/%2").arg(device().partitionTable()->numPrimaries()).arg(device().partitionTable()->maxPrimaries());
dialogWidget().partTableWidget().setReadOnly(true);
@ -121,9 +125,7 @@ void DevicePropsDialog::setupDialog()
} else {
if (device().type() == Device::Type::LVM_Device)
dialogWidget().type().setText(xi18nc("@label device", "LVM Volume Group"));
else if (device().type() == Device::Type::SoftwareRAID_Device)
dialogWidget().type().setText(xi18nc("@label device", "Software RAID Device"));
else
else if (device().type() != Device::Type::SoftwareRAID_Device)
dialogWidget().type().setText(xi18nc("@label device", "Volume Manager Device"));
//TODO: add Volume Manger Device info
dialogWidget().smartStatusText().setVisible(false);

View File

@ -24,6 +24,11 @@ void ListPhysicalVolumes::addPartition(const Partition& p, bool checked)
listPhysicalVolumes().addItem(item);
}
void ListPhysicalVolumes::clear()
{
listPhysicalVolumes().clear();
}
QVector<const Partition *> ListPhysicalVolumes::checkedItems()
{
QVector<const Partition *> partitionList;

View File

@ -41,6 +41,8 @@ public:
void addPartition(const Partition& p, bool checked);
void clear();
QVector<const Partition *> checkedItems();
QListWidget& listPhysicalVolumes() {

View File

@ -11,7 +11,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<x>0</x>
<y>0</y>
<width>249</width>
<height>300</height>
<height>410</height>
</rect>
</property>
<widget class="QListWidget" name="m_ListPhysicalVolumes">
@ -20,7 +20,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<x>0</x>
<y>0</y>
<width>251</width>
<height>301</height>
<height>410</height>
</rect>
</property>
</widget>

View File

@ -31,6 +31,7 @@
#include <core/smartstatus.h>
#include <ops/operation.h>
#include <ops/activateraidoperation.h>
#include <ops/createpartitiontableoperation.h>
#include <ops/createvolumegroupoperation.h>
#include <ops/resizevolumegroupoperation.h>
@ -82,6 +83,8 @@
#include <KJobWidgets>
#include "config.h"
#include <kpmcore/core/softwareraid.h>
/** Creates a new MainWindow instance.
@param parent the parent widget
*/
@ -257,6 +260,15 @@ void MainWindow::setupActions()
//actionCollection()->setDefaultShortcut(resizeVolumeGroup, QKeySequence(/*SHORTCUT KEY HERE*/));
resizeVolumeGroup->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right-double")));
QAction* activateRAID = actionCollection()->addAction(QStringLiteral("activateRAID"));
connect(activateRAID, &QAction::triggered, this, &MainWindow::onActivateRAID);
activateRAID->setEnabled(false);
activateRAID->setVisible(false);
activateRAID->setText(i18nc("@action:inmenu", "Activate RAID"));
activateRAID->setToolTip(i18nc("@info:tooltip", "Activate selected RAID device"));
activateRAID->setStatusTip(i18nc("@info:status", "Activate selected RAID device"));
activateRAID->setIcon(QIcon::fromTheme(QStringLiteral("answer")).pixmap(IconSize(KIconLoader::Toolbar)));
QAction* deactivateVolumeGroup = actionCollection()->addAction(QStringLiteral("deactivateVolumeGroup"));
connect(deactivateVolumeGroup, &QAction::triggered, this, &MainWindow::onDeactivateVolumeGroup);
deactivateVolumeGroup->setEnabled(false);
@ -506,22 +518,38 @@ void MainWindow::enableActions()
actionCollection()->action(QStringLiteral("createVolumeGroup"))
->setEnabled(CreateVolumeGroupOperation::canCreate());
bool lvmDevice = pmWidget().selectedDevice() && pmWidget().selectedDevice()->type() == Device::Type::LVM_Device;
bool vgDevice = pmWidget().selectedDevice() &&
(pmWidget().selectedDevice()->type() == Device::Type::LVM_Device ||
pmWidget().selectedDevice()->type() == Device::Type::SoftwareRAID_Device);
bool removable = false;
if (lvmDevice)
removable = RemoveVolumeGroupOperation::isRemovable(dynamic_cast<LvmDevice*>(pmWidget().selectedDevice()));
if (vgDevice)
removable = RemoveVolumeGroupOperation::isRemovable(dynamic_cast<VolumeManagerDevice*>(pmWidget().selectedDevice()));
actionCollection()->action(QStringLiteral("removeVolumeGroup"))->setEnabled(removable);
actionCollection()->action(QStringLiteral("removeVolumeGroup"))->setVisible(lvmDevice);
actionCollection()->action(QStringLiteral("removeVolumeGroup"))->setVisible(vgDevice);
bool deactivatable = lvmDevice ?
DeactivateVolumeGroupOperation::isDeactivatable(dynamic_cast<LvmDevice*>(pmWidget().selectedDevice())) : false;
bool isRaid = vgDevice &&
pmWidget().selectedDevice()->type() == Device::Type::SoftwareRAID_Device;
bool canActivateRAID = isRaid &&
static_cast< SoftwareRAID* >(pmWidget().selectedDevice())->status() == SoftwareRAID::Status::Inactive;
actionCollection()->action(QStringLiteral("activateRAID"))->setEnabled(canActivateRAID);
actionCollection()->action(QStringLiteral("activateRAID"))->setVisible(isRaid);
bool deactivatable = vgDevice ?
DeactivateVolumeGroupOperation::isDeactivatable(dynamic_cast<VolumeManagerDevice*>(pmWidget().selectedDevice())) : false;
actionCollection()->action(QStringLiteral("deactivateVolumeGroup"))->setEnabled(deactivatable);
actionCollection()->action(QStringLiteral("deactivateVolumeGroup"))->setVisible(lvmDevice);
actionCollection()->action(QStringLiteral("deactivateVolumeGroup"))->setVisible(vgDevice);
actionCollection()->action(QStringLiteral("resizeVolumeGroup"))->setEnabled(lvmDevice);
actionCollection()->action(QStringLiteral("resizeVolumeGroup"))->setVisible(lvmDevice);
bool canResizeVG = vgDevice;
if (isRaid)
canResizeVG = static_cast<SoftwareRAID*>(pmWidget().selectedDevice())->status() == SoftwareRAID::Status::Active;
actionCollection()->action(QStringLiteral("resizeVolumeGroup"))->setEnabled(canResizeVG);
actionCollection()->action(QStringLiteral("resizeVolumeGroup"))->setVisible(canResizeVG);
const Partition* part = pmWidget().selectedPartition();
@ -1105,19 +1133,30 @@ void MainWindow::onCreateNewVolumeGroup()
{
QString vgName;
QVector<const Partition*> pvList;
QString type;
qint32 raidLevel = 0;
qint32 peSize = 4;
qint32 chunkSize = 512;
// *NOTE*: vgName & pvList will be modified and validated by the dialog
QPointer<CreateVolumeGroupDialog> dlg = new CreateVolumeGroupDialog(this, vgName, pvList, peSize, operationStack().previewDevices(), operationStack().operations());
QPointer<CreateVolumeGroupDialog> dlg = new CreateVolumeGroupDialog(this, vgName, pvList, type, raidLevel, chunkSize,
peSize, operationStack().previewDevices(),
operationStack().operations());
if (dlg->exec() == QDialog::Accepted)
operationStack().push(new CreateVolumeGroupOperation(vgName, pvList, peSize));
{
if (type == QStringLiteral("LVM"))
operationStack().push(new CreateVolumeGroupOperation(vgName, pvList, Device::Type::LVM_Device, peSize));
else if (type == QStringLiteral("RAID"))
operationStack().push(new CreateVolumeGroupOperation(vgName, pvList, Device::Type::SoftwareRAID_Device, raidLevel, chunkSize));
}
delete dlg;
}
void MainWindow::onResizeVolumeGroup()
{
if (pmWidget().selectedDevice()->type() == Device::Type::LVM_Device) {
LvmDevice* d = dynamic_cast<LvmDevice*>(pmWidget().selectedDevice());
if (pmWidget().selectedDevice()->type() == Device::Type::LVM_Device ||
pmWidget().selectedDevice()->type() == Device::Type::SoftwareRAID_Device) {
VolumeManagerDevice* d = dynamic_cast<VolumeManagerDevice*>(pmWidget().selectedDevice());
QVector<const Partition*> pvList;
// *NOTE*: pvList will be modified and validated by the dialog
@ -1133,23 +1172,50 @@ void MainWindow::onResizeVolumeGroup()
void MainWindow::onRemoveVolumeGroup()
{
Device* tmpDev = pmWidget().selectedDevice();
if (tmpDev->type() == Device::Type::LVM_Device) {
operationStack().push(new RemoveVolumeGroupOperation(*(dynamic_cast<LvmDevice*>(tmpDev))));
if (tmpDev->type() == Device::Type::LVM_Device ||
tmpDev->type() == Device::Type::SoftwareRAID_Device) {
operationStack().push(new RemoveVolumeGroupOperation(*(dynamic_cast<VolumeManagerDevice*>(tmpDev))));
}
}
void MainWindow::onDeactivateVolumeGroup()
{
Device* tmpDev = pmWidget().selectedDevice();
if (tmpDev->type() == Device::Type::LVM_Device) {
DeactivateVolumeGroupOperation* deactivate = new DeactivateVolumeGroupOperation( *(dynamic_cast<LvmDevice*>(tmpDev)) );
Report* tmpReport = new Report(nullptr);
if (deactivate->execute(*tmpReport)) {
if (tmpDev->type() == Device::Type::LVM_Device || tmpDev->type() == Device::Type::SoftwareRAID_Device) {
DeactivateVolumeGroupOperation* deactivate = new DeactivateVolumeGroupOperation( *(dynamic_cast<VolumeManagerDevice*>(tmpDev)) );
Report tmpReport(nullptr);
if (deactivate->execute(tmpReport)) {
deactivate->preview();
actionCollection()->action(QStringLiteral("resizeVolumeGroup"))->setEnabled(false);
actionCollection()->action(QStringLiteral("deactivateVolumeGroup"))->setEnabled(false);
}
delete tmpReport;
pmWidget().updatePartitions();
enableActions();
}
}
void MainWindow::onActivateRAID()
{
Device* dev = pmWidget().selectedDevice();
if (dev->type() == Device::Type::SoftwareRAID_Device) {
ActivateRaidOperation activate(static_cast<SoftwareRAID*>(dev));
Report report(nullptr);
if (activate.execute(report))
activate.preview();
Device *tmp = CoreBackendManager::self()->backend()->scanDevice(dev->deviceNode());
if (tmp) {
PartitionTable* ptable = new PartitionTable(*tmp->partitionTable());
dev->setPartitionTable(ptable);
}
delete tmp;
pmWidget().updatePartitions();
enableActions();
}
@ -1169,7 +1235,15 @@ void MainWindow::onShowAboutKPMcore()
void MainWindow::onSettingsChanged()
{
bool raidChanged = false, backendChanged = false;
if (SoftwareRAID::raidConfigurationFilePath() != Config::raidConfigurationFilePath()) {
raidChanged = true;
loadRaidConfiguration();
}
if (CoreBackendManager::self()->backend()->id() != Config::backend()) {
backendChanged = true;
CoreBackendManager::self()->unload();
// FIXME: if loadBackend() fails to load the configured backend and loads the default
// one instead it also sets the default backend in the config; the config dialog will
@ -1182,6 +1256,9 @@ void MainWindow::onSettingsChanged()
close();
}
if (raidChanged && !backendChanged)
scanDevices();
enableActions();
pmWidget().updatePartitions();

View File

@ -235,6 +235,7 @@ protected:
void onRemoveVolumeGroup();
void onResizeVolumeGroup();
void onDeactivateVolumeGroup();
void onActivateRAID();
void onExportPartitionTable();
void onImportPartitionTable();

View File

@ -37,6 +37,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<Action name="importPartitionTable"/>
<separator/>
<Action name="resizeVolumeGroup"/>
<Action name="activateRAID"/>
<Action name="deactivateVolumeGroup"/>
<Action name="removeVolumeGroup"/>
<separator/>

View File

@ -13,6 +13,8 @@
#include <core/lvmdevice.h>
#include <core/volumemanagerdevice.h>
#include <core/partitiontable.h>
#include <core/softwareraid.h>
#include <fs/lvm2_pv.h>
#include <ops/deleteoperation.h>
@ -26,6 +28,8 @@
#include <KLocalizedString>
#include <KSharedConfig>
#include <QDebug>
/** Creates a new ResizeVolumeGroupDialog
@param parent pointer to the parent widget
@param d the Device to show properties for
@ -47,8 +51,15 @@ ResizeVolumeGroupDialog::ResizeVolumeGroupDialog(QWidget* parent, VolumeManagerD
void ResizeVolumeGroupDialog::setupDialog()
{
<<<<<<< HEAD
if (device()->type() == Device::Type::LVM_Device) {
dialogWidget().volumeType().setCurrentIndex(0);
for (const auto &p : qAsConst(LVM::pvList::list())) {
=======
if (dialogWidget().volumeType().currentText() == QStringLiteral("LVM")) {
for (const auto &p : std::as_const(LVM::pvList::list())) {
>>>>>>> master
bool toBeDeleted = false;
// Ignore partitions that are going to be deleted
@ -59,11 +70,9 @@ void ResizeVolumeGroupDialog::setupDialog()
}
}
if (toBeDeleted)
if (toBeDeleted || p.isLuks())
continue;
if (p.isLuks())
continue;
if (p.vgName() == device()->name())
dialogWidget().listPV().addPartition(*p.partition(), true);
else if (p.vgName().isEmpty() && !LvmDevice::s_DirtyPVs.contains(p.partition())) // TODO: Remove LVM PVs in current VG
@ -95,17 +104,56 @@ void ResizeVolumeGroupDialog::setupDialog()
for (const Partition *p : std::as_const(LvmDevice::s_OrphanPVs))
if (!LvmDevice::s_DirtyPVs.contains(p))
dialogWidget().listPV().addPartition(*p, false);
}
//update used size and LV infos
qint32 totalLV = 0;
LvmDevice *lvmDevice = dynamic_cast<LvmDevice *>(device());
if (lvmDevice != nullptr) {
LvmDevice *lvmDevice = static_cast<LvmDevice*>(device());
m_TotalUsedSize = lvmDevice->allocatedPE() * lvmDevice->peSize();
totalLV = lvmDevice->partitionTable()->children().count();
dialogWidget().totalUsedSize().setText(Capacity::formatByteSize(m_TotalUsedSize));
}
else if (device()->type() == Device::Type::SoftwareRAID_Device) {
dialogWidget().volumeType().setCurrentIndex(1);
for (const Device *d : qAsConst(m_Devices)) {
if (d != device() && d->partitionTable() != nullptr) {
for (const Partition *p : qAsConst(d->partitionTable()->children())) {
QString arrayName = SoftwareRAID::getRaidArrayName(p->partitionPath());
if (arrayName == device()->deviceNode())
dialogWidget().listPV().addPartition(*p, true);
else if (((p->fileSystem().type() == FileSystem::Type::LinuxRaidMember &&
arrayName.isEmpty()) || p->fileSystem().type() == FileSystem::Type::Unformatted ||
p->fileSystem().type() == FileSystem::Type::Unknown) && !p->roles().has(PartitionRole::Role::Unallocated))
dialogWidget().listPV().addPartition(*p, false);
}
}
}
SoftwareRAID* raid = static_cast<SoftwareRAID*>(device());
m_TotalUsedSize = 0;
for (const Partition* p : device()->partitionTable()->children())
if (!p->roles().has(PartitionRole::Unallocated))
m_TotalUsedSize += p->used();
dialogWidget().totalUsedSize().setText(Capacity::formatByteSize(m_TotalUsedSize));
int index = dialogWidget().raidLevel().findText(QString::number(raid->raidLevel()));
if (index != -1)
dialogWidget().raidLevel().setCurrentIndex(index);
dialogWidget().chunkSize().setValue(raid->chunkSize());
}
int totalLV = 0;
if (device()->partitionTable()) {
for (const Partition* p : device()->partitionTable()->children())
if (!p->roles().has(PartitionRole::Role::Unallocated))
totalLV++;
}
dialogWidget().totalUsedSize().setText(Capacity::formatByteSize(m_TotalUsedSize));
dialogWidget().totalLV().setText(QString::number(totalLV));
}
@ -114,6 +162,11 @@ void ResizeVolumeGroupDialog::setupConstraints()
dialogWidget().vgName().setEnabled(false);
dialogWidget().spinPESize().setEnabled(false);
dialogWidget().volumeType().setEnabled(false);
// set constraints for raid
dialogWidget().raidLevel().setEnabled(false);
dialogWidget().chunkSize().setEnabled(false);
VolumeGroupDialog::setupConstraints();
}

View File

@ -66,18 +66,16 @@ VolumeGroupDialog::~VolumeGroupDialog()
void VolumeGroupDialog::setupDialog()
{
/* LVM Volume group name can consist of: letters numbers _ . - +
* It cannot start with underscore _ and must not be equal to . or .. or any entry in /dev/
* QLineEdit accepts QValidator::Intermediate, so we just disable . at the beginning */
QRegularExpression re(QStringLiteral(R"(^(?!_|\.)[\w\-.+]+)"));
QRegularExpressionValidator *validator = new QRegularExpressionValidator(re, this);
dialogWidget().vgName().setValidator(validator);
dialogWidget().vgName().setText(targetName());
dialogWidget().volumeType().addItem(QStringLiteral("LVM"));
dialogWidget().volumeType().addItem(QStringLiteral("RAID"));
dialogWidget().volumeType().addItems({ QStringLiteral("LVM"), QStringLiteral("RAID") });
dialogWidget().volumeType().setCurrentIndex(0);
dialogWidget().raidLevel().addItems({ QStringLiteral("0"), QStringLiteral("1"),
QStringLiteral("4"), QStringLiteral("5"),
QStringLiteral("6"), QStringLiteral("10") });
updateNameValidator();
updateComponents();
setMinimumSize(dialogWidget().size());
resize(dialogWidget().size());
}
@ -116,20 +114,35 @@ void VolumeGroupDialog::updateOkButtonStatus()
void VolumeGroupDialog::updateSectorInfos()
{
qint32 totalSectors = 0;
// we can't use LvmDevice method here because pv that is not in any VG will return 0
m_ExtentSize = dialogWidget().spinPESize().value() * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
if (m_ExtentSize > 0) {
totalSectors = m_TotalSize / m_ExtentSize;
if (dialogWidget().volumeType().currentText() == QStringLiteral("LVM")) {
// we can't use LvmDevice method here because pv that is not in any VG will return 0
m_ExtentSize = dialogWidget().spinPESize().value() * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
if (m_ExtentSize > 0)
totalSectors = m_TotalSize / m_ExtentSize;
}
else if (dialogWidget().volumeType().currentText() == QStringLiteral("RAID")) {
m_ExtentSize = dialogWidget().chunkSize().value() * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::KiB);
if (m_ExtentSize > 0)
totalSectors = m_TotalSize / m_ExtentSize;
}
dialogWidget().totalSectors().setText(QString::number(totalSectors));
}
void VolumeGroupDialog::updateSizeInfos()
{
QString type = dialogWidget().volumeType().currentText();
const QVector<const Partition *> checkedPartitions = dialogWidget().listPV().checkedItems();
m_TotalSize = 0;
for (const auto &p : checkedPartitions)
m_TotalSize += p->capacity() - p->capacity() % (dialogWidget().spinPESize().value() * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB)); // subtract space which is too small to hold PE
m_TotalSize += p->capacity() - p->capacity() %
(type == QStringLiteral("LVM") ?
(dialogWidget().spinPESize().value() * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB)) :
(dialogWidget().chunkSize().value() * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::KiB)));
// subtract space which is too small to hold PE
dialogWidget().totalSize().setText(Capacity::formatByteSize(m_TotalSize));
@ -143,6 +156,23 @@ void VolumeGroupDialog::updatePartitionList()
{
}
void VolumeGroupDialog::updateNameValidator()
{
if (dialogWidget().volumeType().currentText() == QStringLiteral("LVM")) {
/* LVM Volume group name can consist of: letters numbers _ . - +
* It cannot start with underscore _ and must not be equal to . or .. or any entry in /dev/
* QLineEdit accepts QValidator::Intermediate, so we just disable . at the beginning */
QRegularExpression re(QStringLiteral(R"(^(?!_|\.)[\w\-.+]+)"));
QRegularExpressionValidator *validator = new QRegularExpressionValidator(re, this);
dialogWidget().vgName().setValidator(validator);
dialogWidget().vgName().setText(targetName());
}
else if (dialogWidget().volumeType().currentText() == QStringLiteral("RAID")) {
// TODO: See how Software RAID names should be validated.
}
}
void VolumeGroupDialog::onPartitionListChanged()
{
}
@ -150,5 +180,17 @@ void VolumeGroupDialog::onPartitionListChanged()
void VolumeGroupDialog::onVolumeTypeChanged(int index)
{
Q_UNUSED(index)
updateNameValidator();
updatePartitionList();
updateComponents();
}
void VolumeGroupDialog::updateComponents()
{
dialogWidget().spinPESize().setVisible(dialogWidget().volumeType().currentText() == QStringLiteral("LVM"));
dialogWidget().textTotalPESize().setVisible(dialogWidget().volumeType().currentText() == QStringLiteral("LVM"));
dialogWidget().raidLevel().setVisible(dialogWidget().volumeType().currentText() == QStringLiteral("RAID"));
dialogWidget().textRaidLevel().setVisible(dialogWidget().volumeType().currentText() == QStringLiteral("RAID"));
dialogWidget().chunkSize().setVisible(dialogWidget().volumeType().currentText() == QStringLiteral("RAID"));
dialogWidget().textChunkSize().setVisible(dialogWidget().volumeType().currentText() == QStringLiteral("RAID"));
}

View File

@ -36,7 +36,9 @@ protected:
virtual void updateSizeInfos();
virtual void updateSectorInfos();
virtual void updatePartitionList();
virtual void updateNameValidator();
virtual void onPartitionListChanged();
virtual void onVolumeTypeChanged(int index);
VolumeGroupWidget& dialogWidget() {
@ -72,8 +74,8 @@ protected:
return m_IsValidName;
}
protected:
virtual void onPartitionListChanged();
private:
void updateComponents();
protected:
VolumeGroupWidget* m_DialogWidget;

View File

@ -25,82 +25,101 @@ public:
public:
QLineEdit& vgName() {
QLineEdit& vgName() const {
Q_ASSERT(m_EditVGName);
return *m_EditVGName;
}
QComboBox& volumeType() {
QComboBox& volumeType() const {
Q_ASSERT(m_ComboVolumeType);
return *m_ComboVolumeType;
}
QSpinBox& spinPESize() {
QSpinBox& spinPESize() const {
Q_ASSERT(m_SpinPESize);
return *m_SpinPESize;
}
ListPhysicalVolumes& listPV() {
ListPhysicalVolumes& listPV() const {
Q_ASSERT(m_ListPV);
return *m_ListPV;
}
QLabel& totalSize() {
QLabel& totalSize() const {
Q_ASSERT(m_LabelTotalSize);
return *m_LabelTotalSize;
}
QLabel& totalSectors() {
QLabel& totalSectors() const {
Q_ASSERT(m_LabelTotalSectors);
return *m_LabelTotalSectors;
}
QLabel& totalUsedSize() {
QLabel& totalUsedSize() const {
Q_ASSERT(m_LabelTotalUsedSize);
return *m_LabelTotalUsedSize;
}
QLabel& totalLV() {
QLabel& totalLV() const {
Q_ASSERT(m_LabelTotalLV);
return *m_LabelTotalLV;
}
QLabel& textVGName() {
QLabel& textVGName() const {
Q_ASSERT(m_LabelTextVGName);
return *m_LabelTextVGName;
}
QLabel& textVolumeType() {
QLabel& textVolumeType() const {
Q_ASSERT(m_LabelTextVolumeType);
return *m_LabelTextVolumeType;
}
QLabel& textTotalSize() {
QLabel& textTotalSize() const {
Q_ASSERT(m_LabelTextTotalSize);
return *m_LabelTextTotalSize;
}
QLabel& textTotalSectors() {
QLabel& textTotalSectors() const {
Q_ASSERT(m_LabelTextTotalSectors);
return *m_LabelTextTotalSectors;
}
QLabel& textTotalUsedSize() {
QLabel& textTotalUsedSize() const {
Q_ASSERT(m_LabelTextTotalUsedSize);
return *m_LabelTextTotalUsedSize;
}
QLabel& textTotalLV() {
QLabel& textTotalLV() const {
Q_ASSERT(m_LabelTextTotalLV);
return *m_LabelTextTotalLV;
}
QLabel& textTotalPESize() {
QLabel& textTotalPESize() const {
Q_ASSERT(m_LabelTextPESize);
return *m_LabelTextPESize;
}
QSpinBox& chunkSize() const {
Q_ASSERT(m_ChunkSize);
return *m_ChunkSize;
}
QComboBox& raidLevel() const {
Q_ASSERT(m_RaidLevel);
return *m_RaidLevel;
}
QLabel& textChunkSize() const {
Q_ASSERT(m_LabelChunkSize);
return *m_LabelChunkSize;
}
QLabel& textRaidLevel() const {
Q_ASSERT(m_LabelRaidLevel);
return *m_LabelRaidLevel;
}
};
#endif

View File

@ -11,7 +11,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<x>0</x>
<y>0</y>
<width>831</width>
<height>512</height>
<height>480</height>
</rect>
</property>
<property name="minimumSize">
@ -21,14 +21,17 @@ SPDX-License-Identifier: GPL-3.0-or-later
</size>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLineEdit" name="m_EditVGName"/>
</item>
</layout>
<item row="0" column="0" rowspan="7">
<widget class="ListPhysicalVolumes" name="m_ListPV" native="true">
<property name="minimumSize">
<size>
<width>250</width>
<height>410</height>
</size>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="0" column="1">
<widget class="QLabel" name="m_LabelTextVGName">
<property name="text">
<string>Volume Group Name: </string>
@ -36,43 +39,68 @@ SPDX-License-Identifier: GPL-3.0-or-later
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="m_LabelTextPESize">
<item row="0" column="2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLineEdit" name="m_EditVGName"/>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QLabel" name="m_LabelTextVolumeType">
<property name="text">
<string>Physical Extent Size: </string>
<string>Volume Group Type: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="m_LabelTotalSectors">
<property name="text">
<string>---</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="2" column="2">
<item row="1" column="2">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QComboBox" name="m_ComboVolumeType"/>
</item>
</layout>
</item>
<item row="3" column="2">
<item row="2" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="m_LabelTextPESize">
<property name="text">
<string>Physical Extent Size: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_LabelRaidLevel">
<property name="text">
<string>RAID level:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_LabelChunkSize">
<property name="text">
<string>Chunk Size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="2">
<layout class="QVBoxLayout" name="verticalLayout_1">
<item>
<widget class="QSpinBox" name="m_SpinPESize">
<property name="suffix">
@ -89,52 +117,28 @@ SPDX-License-Identifier: GPL-3.0-or-later
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="m_RaidLevel"/>
</item>
<item>
<widget class="QSpinBox" name="m_ChunkSize">
<property name="suffix">
<string> KiB</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>2048</number>
</property>
<property name="value">
<number>512</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" rowspan="7">
<widget class="ListPhysicalVolumes" name="m_ListPV" native="true">
<property name="minimumSize">
<size>
<width>250</width>
<height>400</height>
</size>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="m_LabelTextTotalLV">
<property name="text">
<string>Total LV: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QLabel" name="m_LabelTotalLV">
<property name="text">
<string>---</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="m_LabelTextVolumeType">
<property name="text">
<string>Volume Group Type: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="3" column="1">
<widget class="QLabel" name="m_LabelTextTotalSize">
<property name="text">
<string>Total Size: </string>
@ -142,45 +146,19 @@ SPDX-License-Identifier: GPL-3.0-or-later
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="m_LabelTextTotalSectors">
<property name="text">
<string>Total Sectors: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="4" column="2">
<item row="3" column="2">
<widget class="QLabel" name="m_LabelTotalSize">
<property name="text">
<string>---</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="m_LabelTotalUsedSize">
<property name="text">
<string>---</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="4" column="1">
<widget class="QLabel" name="m_LabelTextTotalUsedSize">
<property name="text">
<string>Used Size: </string>
@ -188,8 +166,55 @@ SPDX-License-Identifier: GPL-3.0-or-later
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="m_LabelTotalUsedSize">
<property name="text">
<string>---</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="m_LabelTextTotalSectors">
<property name="text">
<string>Total Sectors: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="m_LabelTotalSectors">
<property name="text">
<string>---</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="m_LabelTextTotalLV">
<property name="text">
<string>Total LV: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="m_LabelTotalLV">
<property name="text">
<string>---</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>

View File

@ -71,6 +71,8 @@ int Q_DECL_IMPORT main(int argc, char* argv[])
if (!loadBackend())
return 0;
loadRaidConfiguration();
MainWindow* mainWindow = new MainWindow();
Q_UNUSED(mainWindow)

View File

@ -167,5 +167,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
</choices>
<default>random</default>
</entry>
<entry key="raidConfigurationFilePath" type="String">
<default>/etc/mdadm.conf</default>
</entry>
</group>
</kcfg>

View File

@ -29,6 +29,8 @@
#include <unistd.h>
#include <kpmcore/core/softwareraid.h>
QIcon createFileSystemColor(FileSystem::Type type, quint32 size)
{
QPixmap pixmap(size, size);
@ -65,6 +67,11 @@ bool loadBackend()
return true;
}
void loadRaidConfiguration()
{
SoftwareRAID::setRaidConfigurationFilePath(Config::raidConfigurationFilePath());
}
Capacity::Unit preferredUnit()
{
return static_cast<Capacity::Unit>(Config::preferredUnit());

View File

@ -19,6 +19,7 @@ class QString;
class QTreeWidget;
bool loadBackend();
void loadRaidConfiguration();
QIcon createFileSystemColor(FileSystem::Type type, quint32 size);
Capacity::Unit preferredUnit();
void showColumnsContextMenu(const QPoint& p, QTreeWidget& tree);