File indexing completed on 2024-04-28 05:46:31

0001 /*
0002     SPDX-FileCopyrightText: 2016 Chantara Tith <tith.chantara@gmail.com>
0003     SPDX-FileCopyrightText: 2016-2020 Andrius Štikonas <andrius@stikonas.eu>
0004     SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
0005     SPDX-FileCopyrightText: 2019 Yuri Chornoivan <yurchor@ukr.net>
0006 
0007     SPDX-License-Identifier: GPL-3.0-or-later
0008 */
0009 
0010 #include "gui/createvolumegroupdialog.h"
0011 #include "gui/volumegroupwidget.h"
0012 
0013 #include <core/device.h>
0014 #include <core/lvmdevice.h>
0015 #include <core/partitiontable.h>
0016 
0017 #include <fs/lvm2_pv.h>
0018 
0019 #include <ops/deleteoperation.h>
0020 
0021 #include <util/capacity.h>
0022 #include <util/helpers.h>
0023 
0024 #include <utility>
0025 
0026 #include <QtGlobal>
0027 
0028 #include <KConfigGroup>
0029 #include <KLocalizedString>
0030 #include <KSharedConfig>
0031 
0032 CreateVolumeGroupDialog::CreateVolumeGroupDialog(QWidget* parent, QString& vgName, QVector<const Partition*>& partList, qint32& peSize, QList<Device*> devices, QList<Operation*> pendingOps)
0033     : VolumeGroupDialog(parent, vgName, partList)
0034     , m_PESize(peSize)
0035     , m_Devices(devices)
0036     , m_PendingOps(pendingOps)
0037 {
0038     setWindowTitle(xi18nc("@title:window", "Create new Volume Group"));
0039 
0040     setupDialog();
0041     setupConstraints();
0042     setupConnections();
0043 
0044     // disable volume type and PE size for now, until the features are implemented.
0045     dialogWidget().volumeType().setEnabled(false);
0046 
0047     KConfigGroup kcg(KSharedConfig::openConfig(), QStringLiteral("createVolumeDialog"));
0048     restoreGeometry(kcg.readEntry<QByteArray>("Geometry", QByteArray()));
0049 }
0050 
0051 void CreateVolumeGroupDialog::setupDialog()
0052 {
0053     for (const auto &p : std::as_const(LVM::pvList::list())) {
0054         bool toBeDeleted = false;
0055 
0056         // Ignore partitions that are going to be deleted
0057         for (const auto &o : std::as_const(m_PendingOps)) {
0058             if (dynamic_cast<DeleteOperation *>(o) && o->targets(*p.partition())) {
0059                 toBeDeleted = true;
0060                 break;
0061             }
0062         }
0063 
0064         if (toBeDeleted)
0065             continue;
0066 
0067         if (!p.isLuks() && p.vgName().isEmpty() && !LvmDevice::s_DirtyPVs.contains(p.partition()))
0068             dialogWidget().listPV().addPartition(*p.partition(), false);
0069     }
0070 
0071     for (const Device *d : std::as_const(m_Devices)) {
0072         if (d->partitionTable() != nullptr) {
0073             for (const Partition *p : std::as_const(d->partitionTable()->children())) {
0074                 // Looking if there is another VG creation that contains this partition
0075                 if (LvmDevice::s_DirtyPVs.contains(p))
0076                     continue;
0077 
0078                 // Including new LVM PVs (that are currently in OperationStack and that aren't at other VG creation)
0079                 if (p->state() == Partition::State::New) {
0080                     if (p->fileSystem().type() == FileSystem::Type::Lvm2_PV)
0081                         dialogWidget().listPV().addPartition(*p, false);
0082                     else if (p->fileSystem().type() == FileSystem::Type::Luks || p->fileSystem().type() == FileSystem::Type::Luks2) {
0083                         FileSystem *fs = static_cast<const FS::luks *>(&p->fileSystem())->innerFS();
0084 
0085                         if (fs->type() == FileSystem::Type::Lvm2_PV)
0086                             dialogWidget().listPV().addPartition(*p, false);
0087                     }
0088                 }
0089             }
0090         }
0091     }
0092 
0093     for (const Partition *p : std::as_const(LvmDevice::s_OrphanPVs))
0094         if (!LvmDevice::s_DirtyPVs.contains(p))
0095             dialogWidget().listPV().addPartition(*p, false);
0096 }
0097 
0098 void CreateVolumeGroupDialog::setupConnections()
0099 {
0100     connect(&dialogWidget().vgName(), &QLineEdit::textChanged, this, &CreateVolumeGroupDialog::onVGNameChanged);
0101     connect(&dialogWidget().spinPESize(), &QSpinBox::valueChanged, this, &CreateVolumeGroupDialog::onSpinPESizeChanged);
0102 }
0103 
0104 void  CreateVolumeGroupDialog::accept()
0105 {
0106     QString& tname = targetName();
0107     tname = dialogWidget().vgName().text();
0108 
0109     targetPVList().append(dialogWidget().listPV().checkedItems());
0110 
0111     qint32& pesize = peSize();
0112     pesize = dialogWidget().spinPESize().value();
0113 
0114     QDialog::accept();
0115 }
0116 
0117 void CreateVolumeGroupDialog::updateOkButtonStatus()
0118 {
0119     VolumeGroupDialog::updateOkButtonStatus();
0120 
0121     if (okButton->isEnabled())
0122         okButton->setEnabled(!dialogWidget().listPV().checkedItems().empty());
0123 }
0124 
0125 void CreateVolumeGroupDialog::onVGNameChanged(const QString& vgName)
0126 {
0127     for (const auto &d : m_Devices) {
0128         if (dynamic_cast<LvmDevice*>(d)) {
0129             if (d->name() == vgName) {
0130                 m_IsValidName = false;
0131                 break;
0132             }
0133             else
0134                 m_IsValidName = true;
0135         }
0136     }
0137     updateOkButtonStatus();
0138 }
0139 
0140 void CreateVolumeGroupDialog::onSpinPESizeChanged(int newsize)
0141 {
0142     Q_UNUSED(newsize)
0143     updateOkButtonStatus();
0144     updateSectorInfos();
0145 }