File indexing completed on 2024-04-28 05:45:53

0001 /*
0002     SPDX-FileCopyrightText: 2008-2010 Volker Lanz <vl@fidra.de>
0003     SPDX-FileCopyrightText: 2013-2020 Andrius Štikonas <andrius@stikonas.eu>
0004     SPDX-FileCopyrightText: 2016 Chantara Tith <tith.chantara@gmail.com>
0005     SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
0006     SPDX-FileCopyrightText: 2019 Yuri Chornoivan <yurchor@ukr.net>
0007     SPDX-FileCopyrightText: 2020 Gaël PORTAY <gael.portay@collabora.com>
0008 
0009     SPDX-License-Identifier: GPL-3.0-or-later
0010 */
0011 
0012 #include "jobs/createpartitionjob.h"
0013 
0014 #include "backend/corebackend.h"
0015 #include "backend/corebackendmanager.h"
0016 #include "backend/corebackenddevice.h"
0017 #include "backend/corebackendpartitiontable.h"
0018 
0019 #include "core/partition.h"
0020 #include "core/device.h"
0021 #include "core/lvmdevice.h"
0022 
0023 #include "util/report.h"
0024 
0025 #include <KLocalizedString>
0026 
0027 /** Creates a new CreatePartitionJob
0028     @param d the Device the Partition to be created will be on
0029     @param p the Partition to create
0030 */
0031 CreatePartitionJob::CreatePartitionJob(Device& d, Partition& p) :
0032     Job(),
0033     m_Device(d),
0034     m_Partition(p)
0035 {
0036 }
0037 
0038 bool CreatePartitionJob::run(Report& parent)
0039 {
0040     Q_ASSERT(partition().devicePath() == device().deviceNode());
0041 
0042     bool rval = false;
0043     Report* report = jobStarted(parent);
0044 
0045     if (device().partitionTable()->type() == PartitionTable::TableType::none) {
0046         partition().setPartitionPath(device().deviceNode());
0047         partition().setState(Partition::State::None);
0048         rval = true;
0049         jobFinished(*report, rval);
0050         return rval;
0051     }
0052 
0053     if (device().type() == Device::Type::Disk_Device || device().type() == Device::Type::SoftwareRAID_Device) {
0054         std::unique_ptr<CoreBackendDevice> backendDevice = CoreBackendManager::self()->backend()->openDevice(device());
0055 
0056         if (backendDevice) {
0057             std::unique_ptr<CoreBackendPartitionTable> backendPartitionTable = backendDevice->openPartitionTable();
0058 
0059             if (backendPartitionTable) {
0060                 QString partitionPath = backendPartitionTable->createPartition(*report, partition());
0061 
0062                 if (!partitionPath.isEmpty()) {
0063                     rval = true;
0064                     partition().setPartitionPath(partitionPath);
0065                     partition().setState(Partition::State::None);
0066                     backendPartitionTable->commit();
0067                     // The UUID is supported by GPT only; it is generated automatically once the creation of a partition.
0068                     // Store the generated UUID to the partition object if no UUID is set.
0069                     if (m_Device.partitionTable()->type() == PartitionTable::gpt && partition().uuid().isEmpty())
0070                         partition().setUUID(backendPartitionTable->getPartitionUUID(*report, partition()));
0071                 } else
0072                     report->line() << xi18nc("@info/plain", "Failed to add partition <filename>%1</filename> to device <filename>%2</filename>.", partition().deviceNode(), device().deviceNode());
0073             } else
0074                 report->line() << xi18nc("@info:progress", "Could not open partition table on device <filename>%1</filename> to create new partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
0075         } else
0076             report->line() << xi18nc("@info:progress", "Could not open device <filename>%1</filename> to create new partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
0077     } else if (device().type() == Device::Type::LVM_Device) {
0078         LvmDevice& dev = dynamic_cast<LvmDevice&>(device());
0079         partition().setState(Partition::State::None);
0080 
0081         QString partPath = partition().partitionPath();
0082         QString lvname   = partPath.right(partPath.length() - partPath.lastIndexOf(QStringLiteral("/")) - 1);
0083         rval = LvmDevice::createLV(*report, dev, partition(), lvname);
0084     }
0085 
0086     jobFinished(*report, rval);
0087 
0088     return rval;
0089 }
0090 
0091 QString CreatePartitionJob::description() const
0092 {
0093     if (partition().number() > 0)
0094         return xi18nc("@info:progress", "Create new partition <filename>%1</filename>", partition().deviceNode());
0095 
0096     return xi18nc("@info:progress", "Create new partition on device <filename>%1</filename>", device().deviceNode());
0097 }