source: src-qt4/pc-installgui/wizardDisk.cpp @ b1a3938

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3releng/10.1
Last change on this file since b1a3938 was b1a3938, checked in by Kris Moore <kris@…>, 15 months ago

Switch default ZFS compression to lz4

  • Property mode set to 100644
File size: 32.6 KB
Line 
1/****************************************************************************
2** ui.h extension file, included from the uic-generated form implementation.
3**
4** If you want to add, delete, or rename functions or slots, use
5** Qt Designer to update this file, preserving your code.
6**
7** You should not define a constructor or destructor in this file.
8** Instead, write your code in functions called init() and destroy().
9** These will automatically be called by the form's constructor and
10** destructor.
11*****************************************************************************/
12#include <QDebug>
13#include <QInputDialog>
14#include <QMessageBox>
15#include "wizardDisk.h"
16#include "ui_wizardDisk.h"
17
18void wizardDisk::programInit()
19{
20  prevID = 0;
21  restoreMode=false;
22
23  populateDiskInfo();
24
25  //connect(pushClose, SIGNAL(clicked()), this, SLOT(slotClose()));
26  connect(checkGPT, SIGNAL(clicked()), this, SLOT(slotGPTClicked()));
27  connect(pushSwapSize, SIGNAL(clicked()), this, SLOT(slotSwapSize()));
28  connect(pushRemoveMount, SIGNAL(clicked()), this, SLOT(slotRemoveFS()));
29  connect(pushAddMount, SIGNAL(clicked()), this, SLOT(slotAddFS()));
30  connect(this,SIGNAL(currentIdChanged(int)),this,SLOT(slotCheckComplete()));
31  connect(lineZpoolName,SIGNAL(textChanged ( const QString & )),this,SLOT(slotCheckComplete()));
32  connect(groupZFSPool,SIGNAL( clicked(bool)),this,SLOT(slotCheckComplete()));
33  connect(comboDisk,SIGNAL(currentIndexChanged(int)),this,SLOT(slotCheckComplete()));
34  connect(comboDisk,SIGNAL(currentIndexChanged(int)),this,SLOT(slotChangedDisk()));
35  connect(comboPartition,SIGNAL(currentIndexChanged(int)),this,SLOT(slotCheckComplete()));
36  connect(treeMounts,SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),this,SLOT(slotTreeDiskChanged()));
37  treeMounts->setContextMenuPolicy(Qt::CustomContextMenu);
38  connect(treeMounts,SIGNAL(customContextMenuRequested(const QPoint &)),this,SLOT(slotTreeMountsRightClick()));
39  connect(pushTerminal, SIGNAL(clicked()), this, SLOT(slotTerminal()));
40
41  // ZFS Mode Page
42  connect(comboZFSMode,SIGNAL(currentIndexChanged(int)),this,SLOT(slotCheckComplete()));
43  connect(groupZFSOpts,SIGNAL(clicked(bool)),this,SLOT(slotCheckComplete()));
44  connect(listZFSDisks,SIGNAL(itemClicked(QListWidgetItem *)),this,SLOT(slotCheckComplete()));
45  connect(listZFSDisks,SIGNAL(itemActivated(QListWidgetItem *)),this,SLOT(slotCheckComplete()));
46  connect(listZFSDisks,SIGNAL(itemChanged(QListWidgetItem *)),this,SLOT(slotCheckComplete()));
47
48}
49
50void wizardDisk::populateDiskInfo()
51{
52  qDebug() << "Loading Disk Info";
53  sysDisks = Scripts::Backend::hardDrives();
54
55  // load drives
56  comboDisk->clear();
57  for (int i=0; i < sysDisks.count(); ++i) {
58    // Make sure to only add the drives to the comboDisk
59    if ( sysDisks.at(i).at(0) == "DRIVE" )
60      comboDisk->addItem(sysDisks.at(i).at(1) + " - " + sysDisks.at(i).at(2) + "MB " + sysDisks.at(i).at(3));
61  }
62
63  // Reload the slice list box
64  slotChangedDisk();
65}
66
67void wizardDisk::slotChangedDisk()
68{
69  QString ptag;
70
71  if ( comboDisk->currentText().isEmpty())
72    return;
73
74  comboPartition->clear();
75  comboPartition->addItem(tr("Use entire disk"));
76       
77  QString disk = comboDisk->currentText();
78  disk.truncate(disk.indexOf(" -"));
79  for (int i=0; i < sysDisks.count(); ++i) {
80    // Make sure to only add the slices to the listDiskSlices
81    if ( sysDisks.at(i).at(0) == "SLICE" && disk == sysDisks.at(i).at(1) && sysDisks.at(i).at(4) != "Unused Space") {
82      ptag = sysDisks.at(i).at(4).section(",", 0, 0);
83      ptag = ptag.section("/", 0, 0);
84      ptag.truncate(15);
85      if ( ptag.indexOf(")") == -1 )
86        ptag += ")";
87      comboPartition->addItem(sysDisks.at(i).at(2) + ": " +  sysDisks.at(i).at(3) + "MB " + ptag );
88    }
89  }
90
91}
92
93void wizardDisk::slotClose()
94{
95  close();
96}
97
98void wizardDisk::accept()
99{
100  bool useGRUB = true;
101  bool useGPT = false;
102  bool force4K = false;
103  QString zpoolName;
104  if (comboPartition->currentIndex() == 0 )
105    useGPT = checkGPT->isChecked();
106
107  // Are we installing GRUB?
108  useGRUB = checkGRUB->isChecked();
109
110  if ( comboPartition->currentIndex() != 0 && ! useGRUB  ) {
111     QMessageBox::warning(this, tr("No boot-loader!"),
112     tr("You have chosen not to install GRUB on your MBR. You will need to manually setup your own MBR loader."),
113     QMessageBox::Ok,
114     QMessageBox::Ok);
115  }
116     
117  // When doing advanced ZFS setups, make sure to use GPT
118  if ( radioAdvanced->isChecked() && groupZFSOpts->isChecked() )
119    useGPT = true;
120
121  // When doing advanced ZFS setups, check if 4K is enabled
122  if ( radioAdvanced->isChecked() && checkForce4K->isChecked() )
123    force4K = true;
124
125  if ( radioAdvanced->isChecked() && groupZFSPool->isChecked() )
126     zpoolName = lineZpoolName->text();
127
128  if ( radioExpert->isChecked() )
129    emit saved(sysFinalDiskLayout, false, false, zpoolName, force4K);
130  else
131    emit saved(sysFinalDiskLayout, useGRUB, useGPT, zpoolName, force4K);
132  close();
133}
134
135int wizardDisk::nextId() const
136{
137  switch (currentId()) {
138     case Page_Intro:
139       if (radioExpert->isChecked())
140         return Page_Expert;
141       if (radioBasic->isChecked()) {
142         checkGPT->setVisible(false);
143         checkGRUB->setVisible(false);
144         checkForce4K->setVisible(false);
145         groupZFSPool->setVisible(false);
146       }
147       if (radioAdvanced->isChecked()) {
148         checkGPT->setVisible(true);
149         checkGRUB->setVisible(true);
150         checkForce4K->setVisible(true);
151         groupZFSPool->setVisible(true);
152       }
153        break;
154     case Page_BasicDisk:
155       if (radioBasic->isChecked())
156         return Page_Confirmation;
157       if (comboPartition->currentIndex() != 0 ) {
158         groupZFSOpts->setEnabled(false);
159         return Page_Mounts;
160       } else {
161         groupZFSOpts->setEnabled(true);
162         return Page_ZFS;
163       }
164       break;
165     case Page_ZFS:
166       return Page_Mounts;
167       break;
168     case Page_Mounts:
169       return Page_Confirmation;
170       break;
171     case Page_Confirmation:
172       return -1;
173       break;
174     default:
175        return currentId() + 1;
176  }
177  return currentId() + 1;
178}
179
180// Logic checks to see if we are ready to move onto next page
181bool wizardDisk::validatePage()
182{
183
184  // Generate suggested disk layout and show disk tree
185  if ( prevID == Page_BasicDisk && currentId() == Page_Mounts) {
186    generateDiskLayout();
187    populateDiskTree();
188  }
189
190  // Generate suggested disk layout and show disk tree
191  if ( prevID == Page_ZFS && currentId() == Page_Mounts) {
192    generateDiskLayout();
193    populateDiskTree();
194  } 
195
196  // Show the other disks available
197  if ( prevID == Page_BasicDisk && currentId() == Page_ZFS)
198     populateZFSDisks();
199
200  // Basic mode, generate a disk layout and show summary
201  if ( prevID == Page_BasicDisk && currentId() == Page_Confirmation) {
202    generateDiskLayout();
203    generateConfirmationText();
204  }
205
206  // Create the final disk layout from user options
207  if ( prevID == Page_Mounts && currentId() == Page_Confirmation) {
208    generateCustomDiskLayout();
209    generateConfirmationText();
210  }
211
212  // Create the final disk layout from user options
213  if ( prevID == Page_Expert && currentId() == Page_Confirmation) {
214    generateConfirmationText();
215  }
216 
217 
218  // Reset the prevID
219  prevID = currentId();
220
221  switch (currentId()) {
222     case Page_Intro:
223         button(QWizard::NextButton)->setEnabled(true);
224         return true;
225     case Page_BasicDisk:
226       
227         if ( ! radioAdvanced->isChecked() ) {
228           checkGPT->setChecked(false);
229           checkGPT->setVisible(false);
230           checkForce4K->setVisible(false);
231           checkForce4K->setChecked(false);
232         } else {
233           checkGPT->setVisible(true);
234           checkForce4K->setVisible(true);
235           if ( comboPartition->currentIndex() == 0)
236             checkGRUB->setText(tr("Install GRUB (Required for Boot-Environment support)"));
237           else
238             checkGRUB->setText(tr("Stamp GRUB on MBR"));
239         } 
240
241         // Doing a Advanced install
242         if ( radioAdvanced->isChecked() && groupZFSPool->isChecked() )
243         {
244            if ( lineZpoolName->text().isEmpty() ) {
245              button(QWizard::NextButton)->setEnabled(false);
246              return false;
247            }
248            if ( lineZpoolName->text() == "root" ) {
249              button(QWizard::NextButton)->setEnabled(false);
250              return false;
251            }
252            if ( lineZpoolName->text().contains(" ") ) {
253              button(QWizard::NextButton)->setEnabled(false);
254              return false;
255            }
256            QRegExp *re = new QRegExp("^[-'a-zA-Z]*$"); 
257            if (! re->exactMatch(lineZpoolName->text()) ) {
258              button(QWizard::NextButton)->setEnabled(false);
259              return false;
260            }
261
262         }
263
264         // If the select partition is just too small, we can stop here
265         if ( ! checkDiskSpace() ) {
266           button(QWizard::NextButton)->setEnabled(false);
267           return false;
268         }
269       
270         // if we get this far, all the fields are filled in
271         button(QWizard::NextButton)->setEnabled(true);
272         return true;
273     case Page_ZFS:
274         // Check if we have valid ZFS disk options specified
275         if ( ! groupZFSOpts->isChecked() ) {
276           button(QWizard::NextButton)->setEnabled(true);
277           return true;
278         }
279         // Need at least one other disk for mirroring
280         if ( comboZFSMode->currentText() == "mirror" ) {
281            labelZFSMsg->setText(tr("Please select at least 1 other drive for mirroring"));
282            for ( int i = 0; i < listZFSDisks->count(); ++i )
283            {
284                if ( listZFSDisks->item(i)->checkState() == Qt::Checked ) {
285                   button(QWizard::NextButton)->setEnabled(true);
286                   return true;
287                }
288            }
289         }
290         if ( comboZFSMode->currentText() == "raidz1" ) {
291            labelZFSMsg->setText(tr("Please select 2 or 4 additional drives for raidz1"));
292            int numChecked = 0;
293            for ( int i = 0; i < listZFSDisks->count(); ++i )
294                if ( listZFSDisks->item(i)->checkState() == Qt::Checked )
295                   numChecked++;
296            if ( numChecked == 2 || numChecked == 4 ) {
297              button(QWizard::NextButton)->setEnabled(true);
298              return true;
299            }
300         }
301         if ( comboZFSMode->currentText() == "raidz2" ) {
302            labelZFSMsg->setText(tr("Please select 3, 5, or 9 additional drives for raidz2"));
303            int numChecked = 0;
304            for ( int i = 0; i < listZFSDisks->count(); ++i )
305                if ( listZFSDisks->item(i)->checkState() == Qt::Checked )
306                   numChecked++;
307            if ( numChecked == 3 || numChecked == 5 || numChecked == 9 ) {
308              button(QWizard::NextButton)->setEnabled(true);
309              return true;
310            }
311         }
312         if ( comboZFSMode->currentText() == "raidz3" ) {
313            labelZFSMsg->setText(tr("Please select 4, 6, or 10 additional drives for raidz3"));
314            int numChecked = 0;
315            for ( int i = 0; i < listZFSDisks->count(); ++i )
316                if ( listZFSDisks->item(i)->checkState() == Qt::Checked )
317                   numChecked++;
318            if ( numChecked == 4 || numChecked == 6 || numChecked == 10 ) {
319              button(QWizard::NextButton)->setEnabled(true);
320              return true;
321            }
322         }
323
324         // Disable the next button until we get a working config
325         button(QWizard::NextButton)->setEnabled(false);
326         return false;
327     case Page_Confirmation:
328         button(QWizard::FinishButton)->setEnabled(true);
329         return true;
330     default:
331         button(QWizard::NextButton)->setEnabled(true);
332         return true;
333  }
334
335  return true;
336}
337
338void wizardDisk::populateZFSDisks()
339{
340   qDebug() << "Adding ZFS disks...";
341   listZFSDisks->clear();
342
343   QString curDisk = comboDisk->currentText();
344   curDisk.truncate(curDisk.indexOf(" -"));
345
346   for (int z=0; z < sysDisks.count(); ++z)
347     if ( sysDisks.at(z).at(0) == "DRIVE" && sysDisks.at(z).at(1) != curDisk  )
348     {
349        QListWidgetItem *dItem = new QListWidgetItem(sysDisks.at(z).at(1) + " - " + sysDisks.at(z).at(2) + "MB " + sysDisks.at(z).at(3));
350        dItem->setCheckState(Qt::Unchecked);
351        listZFSDisks->addItem(dItem);
352     }
353}
354
355bool wizardDisk::checkDiskSpace()
356{
357  if ( getDiskSliceSize() < 4000 )
358    return false;
359
360  return true;
361}
362
363void wizardDisk::slotCheckComplete()
364{
365   // Validate this page
366   validatePage();
367}
368
369
370void wizardDisk::generateDiskLayout()
371{
372  QString targetType, tmp;
373  int targetLoc, totalSize = 0;
374  QString targetDisk, targetSlice, tmpPass, fsType, target;
375
376  // Clear out the original disk layout
377  sysFinalDiskLayout.clear();
378  QStringList fileSystem;
379  qDebug() << "Generating disk layout";
380
381  if ( comboPartition->currentIndex() == 0) {
382    targetType = "DRIVE";
383    targetSlice = "ALL";
384    targetDisk = comboDisk->currentText();
385    targetDisk.truncate(targetDisk.indexOf(" -"));
386    target = targetDisk;
387    targetLoc = 1;
388  } else {
389    targetType = "SLICE";
390    targetDisk = comboDisk->currentText();
391    targetDisk.truncate(targetDisk.indexOf(" -"));
392    targetSlice = comboPartition->currentText();
393    targetSlice.truncate(targetSlice.indexOf(":"));
394    targetSlice = targetSlice.remove(0, targetSlice.size() -2);
395    target = targetDisk + targetSlice;
396    targetLoc = 2;
397  }
398
399  // Get the size of the slice we are working on
400  totalSize = getDiskSliceSize();
401
402  // Setup some swap space
403  if ( totalSize > 30000 ) {
404    // 2GB if over 30GB of disk space, 512MB otherwise
405    swapsize = 2000;
406  } else {
407    swapsize = 512;
408  }
409  totalSize = totalSize - swapsize;
410
411
412  if ( totalSize != -1 )
413  {
414     fsType= "ZFS";
415
416     // This lets the user do nifty stuff like a mirror/raid post-install with a single zpool command
417    fileSystem << targetDisk << targetSlice << "/,/tmp(compress=lz4),/usr(canmount=off),/usr/home,/usr/jails,/usr/obj(compress=lz4),/usr/pbi,/usr/ports(compress=lz4),/usr/ports/distfiles(compress=lz4),/usr/src(compress=lz4),/var(canmount=off),/var/audit(compress=lz4),/var/log(compress=lz4),/var/tmp(compress=lz4)" << fsType << tmp.setNum(totalSize) << "" << tmpPass;
418    sysFinalDiskLayout << fileSystem;
419    fileSystem.clear();
420
421    // Now add swap space
422    fileSystem << targetDisk << targetSlice << "SWAP" << "SWAP" << tmp.setNum(swapsize) << "" << "";
423    sysFinalDiskLayout << fileSystem;
424    fileSystem.clear();
425
426    //qDebug() << "Auto-Gen FS:" <<  fileSystem;
427  }
428 
429  qDebug() << "AutoLayout:" <<  sysFinalDiskLayout;
430}
431
432void wizardDisk::populateDiskTree()
433{
434  QStringList tmpList, zMnts;
435  QString tmp, opts;
436
437  treeMounts->clear();
438  treeMounts->setHeaderLabels(QStringList() << "ID" << tr("ZFS Mounts") << tr("ZFS Options") );
439  treeMounts->setColumnCount(3);
440  labelFreeSpace->setVisible(false);
441  lineFreeMB->setVisible(false);
442
443  treeMounts->header()->setSectionHidden(0, true);
444  treeMounts->header()->setDefaultSectionSize(150);
445
446
447  zMnts = sysFinalDiskLayout.at(0).at(2).split(",");
448
449  // Now loop through ZFS mounts
450  for (int i=0; i < zMnts.count(); ++i) {
451    tmpList.clear();
452    opts = zMnts.at(i).section("(", 1, 1).section(")", 0, 0); 
453    tmpList << tmp.setNum(i+1) << zMnts.at(i).split("(").at(0) << opts ;
454    QTreeWidgetItem *mItem = new QTreeWidgetItem(treeMounts, tmpList);
455    mItem->setToolTip(2, opts);
456  }
457
458  treeMounts->setCurrentItem(treeMounts->findItems("0", Qt::MatchFixedString).at(0));
459  slotTreeDiskChanged(); 
460
461  if ( restoreMode ) {
462     treeMounts->setEnabled(false);
463     pushRemoveMount->setEnabled(false);
464     pushAddMount->setEnabled(false);
465     labelMounts->setText(tr("The original system datasets / mount-points will be automatically restored."));
466  }
467
468}
469
470int wizardDisk::getDiskSliceSize()
471{
472  bool ok;
473  QString disk = comboDisk->currentText();
474  disk.truncate(disk.indexOf(" -"));
475
476  int safeBuf = 10;
477
478  // Check the full disk
479  if ( comboPartition->currentIndex() == 0) {
480    for (int i=0; i < sysDisks.count(); ++i) {
481      // Make sure to only add the drives to the comboDiskList
482      if ( sysDisks.at(i).at(0) == "DRIVE" && sysDisks.at(i).at(1) == disk ) {
483        //qDebug() << "Selected Disk Size: " +  sysDisks.at(i).at(2);
484        sysDisks.at(i).at(2).toInt(&ok);
485        if( ok )
486          return sysDisks.at(i).at(2).toInt(&ok) - safeBuf;
487        else
488          return -1;
489      }
490    }
491  } else {
492    // Check the selected partition
493    QString slice = comboPartition->currentText();
494    slice.truncate(slice.indexOf(":"));
495    for (int i=0; i < sysDisks.count(); ++i) {
496      // Make sure to only add the slices to the listDiskSlices
497      if ( sysDisks.at(i).at(0) == "SLICE" && slice == sysDisks.at(i).at(2)) {
498        //qDebug() << "Selected Slice Size: " +  sysDisks.at(i).at(3);
499        sysDisks.at(i).at(3).toInt(&ok);
500        if( ok )
501          return sysDisks.at(i).at(3).toInt(&ok) - safeBuf;
502        else
503          return -1;
504      }
505    }
506  }
507
508  return -1;
509}
510
511void wizardDisk::slotTreeDiskChanged()
512{
513   if ( ! treeMounts->currentItem() )
514     return;
515
516   pushRemoveMount->setEnabled(true);
517   pushAddMount->setEnabled(true);
518
519   if ( treeMounts->currentItem()->text(1) == "/boot" || treeMounts->currentItem()->text(1) == "/")
520     pushRemoveMount->setEnabled(false);
521
522   if ( lineFreeMB->text() == "0" )
523     pushAddMount->setEnabled(false);
524}
525
526void wizardDisk::slotResizeFS()
527{
528  if ( ! treeMounts->currentItem() )
529  return;
530
531  QString mnt = treeMounts->currentItem()->text(1);
532  bool ok;
533  int curSize, availSize, minSize; 
534  curSize =  treeMounts->currentItem()->text(2).toInt(&ok);
535  availSize = curSize + lineFreeMB->text().toInt(&ok);
536
537  minSize = 100;
538
539  // See if we need some other sanity check on sizes
540  if ( mnt == "SWAP" )
541    minSize = 256;
542  if ( mnt == "/" )
543    minSize = 2000;
544  if ( mnt == "/boot" )
545    minSize = 1000;
546
547  addingMount="";
548  rFS = new dialogFSSize();
549  rFS->programInit(QString(tr("Resizing") + " " + mnt), curSize, availSize, minSize);
550  rFS->setWindowModality(Qt::ApplicationModal);
551  connect(rFS, SIGNAL(saved(int)), this, SLOT(slotSaveFSResize(int)));
552  rFS->show();
553  rFS->raise();
554}
555
556void wizardDisk::slotRemoveFS()
557{
558  if ( ! treeMounts->currentItem() )
559  return;
560
561  int ret = QMessageBox::question(this, tr("Remove mount-point"),
562              tr("Are you sure you want to remove this mount point?"),
563              QMessageBox::Yes | QMessageBox::No,
564              QMessageBox::No);
565
566  if ( ret != QMessageBox::Yes )
567    return;
568 
569  QTreeWidgetItem *rmItem = treeMounts->currentItem();
570  treeMounts->setCurrentItem(treeMounts->findItems("0", Qt::MatchFixedString).at(0));
571
572  delete rmItem;
573}
574
575void wizardDisk::slotAddFS()
576{
577  bool ok;
578  QString tmp;
579  QString nMount = QInputDialog::getText(this, tr("Enter mount-point"),
580                                          tr("Please enter the new mount-point:"), QLineEdit::Normal,
581                                          "/", &ok);
582  if (!ok || nMount.isEmpty())
583    return;
584
585  // Sanity checks
586  ////////////////////////////////////////
587  if ( nMount.indexOf("/") != 0 ) {
588      QMessageBox::critical(this, tr("Invalid Mount"),
589              tr("Mount point should start with '/'"),
590              QMessageBox::Ok,
591              QMessageBox::Ok);
592      return;
593  }
594  // End sanity checks
595  ////////////////////////////////////////
596
597  // Make sure this mount doesn't already exist
598  QList<QTreeWidgetItem *> mItems = treeMounts->findItems("*", Qt::MatchWildcard);
599  for ( int i = 0; i < mItems.size(); ++i) {
600    if ( mItems.at(i)->text(1) == nMount )
601      return;
602  }
603
604  new QTreeWidgetItem(treeMounts, QStringList() << tmp.setNum(mItems.size() + 1) << nMount );
605}
606
607void wizardDisk::slotSaveFSResize(int newSize)
608{
609
610  QString tmp, tmp2;
611  bool ok;
612  int oSize, availSize, tSize, newAvailSize;
613
614  // If adding a new mount point
615  if ( ! addingMount.isEmpty() ) {
616    QList<QTreeWidgetItem *> mItems = treeMounts->findItems("*", Qt::MatchWildcard);
617    new QTreeWidgetItem(treeMounts, QStringList() << tmp.setNum(mItems.size() + 1) << addingMount << tmp2.setNum(newSize) << "UFS+SUJ" );
618    addingMount="";
619    availSize = lineFreeMB->text().toInt(&ok); 
620    newAvailSize = availSize - newSize;
621    lineFreeMB->setText(tmp.setNum(newAvailSize));
622    return;
623  } 
624
625  if ( ! treeMounts->currentItem() )
626    return;
627
628  // Just resizing an existing partition
629  oSize = treeMounts->currentItem()->text(2).toInt(&ok); 
630  treeMounts->currentItem()->setText(2, tmp.setNum(newSize));
631
632  // Set the available size
633  if ( oSize > newSize ) {
634    tSize = oSize - newSize;
635    availSize = lineFreeMB->text().toInt(&ok); 
636    newAvailSize = availSize + tSize;
637  } else {
638    tSize = newSize - oSize;
639    availSize = lineFreeMB->text().toInt(&ok); 
640    newAvailSize = availSize - tSize;
641  }
642  lineFreeMB->setText(tmp.setNum(newAvailSize));
643
644  // Check if we need to enable the add button
645  if ( newAvailSize >= 100 )
646    pushAddMount->setEnabled(true);
647  else
648    pushAddMount->setEnabled(false);
649}
650
651void wizardDisk::slotTreeMountsRightClick()
652{
653  if ( ! treeMounts->currentItem() )
654    return;
655
656  popup = new QMenu();
657  popup->setTitle(tr("Editing:") + " " + treeMounts->currentItem()->text(1));
658  popup->addSeparator();
659
660  // Create atime sub-menu
661  popupAT = popup->addMenu("atime");
662  popupAT->addAction( "on", this, SLOT(slotZATON()));
663  popupAT->addAction( "off", this, SLOT(slotZATOFF()));
664
665  // Create canmount sub-menu
666  popupCM = popup->addMenu("canmount");
667  popupCM->addAction( "on", this, SLOT(slotZCMON()));
668  popupCM->addAction( "off", this, SLOT(slotZCMOFF()));
669  popupCM->addAction( "noauto", this, SLOT(slotZCMNOAUTO()));
670
671  // Create Checksum sub-menu
672  popupCH = popup->addMenu("checksum");
673  popupCH->addAction( "on", this, SLOT(slotZChkON()));
674  popupCH->addAction( "off", this, SLOT(slotZChkOFF()));
675
676  // Create compression sub-menu
677  popupCmp = popup->addMenu("compression");
678  popupCmp->addAction( "off", this, SLOT(slotZCmpOFF()));
679  popupCmp->addAction( "on", this, SLOT(slotZCmpON()));
680  popupCmp->addAction( "lz4", this, SLOT(slotZCmpLZ4()));
681  popupCmp->addAction( "lzjb", this, SLOT(slotZCmpLZJB()));
682  popupCmp->addAction( "gzip", this, SLOT(slotZCmpGZIP()));
683  popupCmp->addAction( "zle", this, SLOT(slotZCmpZLE()));
684
685  // Create dedup sub-menu
686  // dedup is disabled for now, until such time as it is safe in all cases
687  //popupDD = popup->addMenu("dedup");
688  //popupDD->addAction( "off", this, SLOT(slotZDDOFF()));
689  //popupDD->addAction( "on", this, SLOT(slotZDDON()));
690  //popupDD->addAction( "verify", this, SLOT(slotZDDVERIFY()));
691
692  // Create exec sub-menu
693  popupNE = popup->addMenu("exec");
694  popupNE->addAction( "on", this, SLOT(slotZEXON()));
695  popupNE->addAction( "off", this, SLOT(slotZEXOFF()));
696
697  popup->exec( QCursor::pos() );
698
699}
700
701void wizardDisk::slotZCMNOAUTO()
702{
703  toggleZFSOpt(QString("canmount=noauto"));
704}
705
706void wizardDisk::slotZCMOFF()
707{
708  toggleZFSOpt(QString("canmount=off"));
709}
710
711void wizardDisk::slotZCMON()
712{
713  toggleZFSOpt(QString("canmount=on"));
714}
715
716void wizardDisk::slotZDDVERIFY()
717{
718  toggleZFSOpt(QString("dedup=verify"));
719}
720
721void wizardDisk::slotZDDON()
722{
723  toggleZFSOpt(QString("dedup=on"));
724}
725
726void wizardDisk::slotZDDOFF()
727{
728  toggleZFSOpt(QString("dedup=off"));
729}
730
731void wizardDisk::slotZCmpZLE()
732{
733  toggleZFSOpt(QString("compress=zle"));
734}
735
736void wizardDisk::slotZCmpGZIP()
737{
738  toggleZFSOpt(QString("compress=gzip"));
739}
740
741void wizardDisk::slotZCmpLZ4()
742{
743  toggleZFSOpt(QString("compress=lz4"));
744}
745
746void wizardDisk::slotZCmpLZJB()
747{
748  toggleZFSOpt(QString("compress=lzjb"));
749}
750
751void wizardDisk::slotZCmpOFF()
752{
753  toggleZFSOpt(QString("compress=off"));
754}
755
756void wizardDisk::slotZCmpON()
757{
758  toggleZFSOpt(QString("compress=on"));
759}
760
761void wizardDisk::slotZChkOFF()
762{
763  toggleZFSOpt(QString("checksum=off"));
764}
765
766void wizardDisk::slotZChkON()
767{
768  toggleZFSOpt(QString("checksum=on"));
769}
770
771void wizardDisk::slotZATON()
772{
773  toggleZFSOpt(QString("atime=on"));
774}
775
776void wizardDisk::slotSwapSize()
777{
778  bool ok;
779  QString tmp;
780  int size = QInputDialog::getInt(this, tr("Enter SWAP size"),
781                                  tr("Size (MB)"), swapsize, 0, 1000000, 1, &ok);
782  if ( ok )
783    swapsize = size;
784}
785
786void wizardDisk::slotZATOFF()
787{
788  toggleZFSOpt(QString("atime=off"));
789}
790
791void wizardDisk::slotZEXOFF()
792{
793  toggleZFSOpt(QString("exec=off"));
794}
795
796void wizardDisk::slotZEXON()
797{
798  toggleZFSOpt(QString("exec=on"));
799}
800
801// Toggle an option being on / off for ZFS
802void wizardDisk::toggleZFSOpt(QString option)
803{
804  if ( ! treeMounts->currentItem() )
805    return;
806
807  bool found = false;
808  QString optTag = option.section("=", 0, 0);
809  QString tmpTag;
810  QStringList newOpts;
811  QStringList curOpts = treeMounts->currentItem()->text(2).split("|");
812  for (int i=0; i < curOpts.count(); ++i) {
813    tmpTag=curOpts.at(i).section("=", 0, 0);
814    if ( optTag == tmpTag ) {
815      found = true;
816      // Only save option if setting to new value
817      if ( option != curOpts.at(i) )
818        newOpts << option;
819    } else {
820      if ( !curOpts.at(i).isEmpty() )
821        newOpts << curOpts.at(i);
822    }
823  }
824
825  if ( ! found )
826      newOpts << option;
827
828  QString optString;
829  if ( newOpts.count() <= 1)
830    optString = newOpts.join("");
831  else
832    optString = newOpts.join("|");
833
834  treeMounts->currentItem()->setText(2, optString);
835  treeMounts->currentItem()->setToolTip(2, optString);
836}
837
838void wizardDisk::generateCustomDiskLayout()
839{
840  QString targetType, tmp;
841  int targetLoc;
842  QString targetDisk, targetSlice, tmpPass, fsType, target;
843
844  // Clear out the original disk layout
845  sysFinalDiskLayout.clear();
846  QStringList fileSystem;
847  qDebug() << "Generating custom disk layout";
848       
849  if ( comboPartition->currentIndex() == 0) {
850    targetType = "DRIVE";
851    targetSlice = "ALL";
852    targetDisk = comboDisk->currentText();
853    targetDisk.truncate(targetDisk.indexOf(" -"));
854    target = targetDisk;
855    targetLoc = 1;
856  } else {
857    targetType = "SLICE";
858    targetDisk = comboDisk->currentText();
859    targetDisk.truncate(targetDisk.indexOf(" -"));
860    targetSlice = comboPartition->currentText();
861    targetSlice.truncate(targetSlice.indexOf(":"));
862    targetSlice = targetSlice.remove(0, targetSlice.size() -2);
863    target = targetDisk + targetSlice;
864    targetLoc = 2;
865  }
866
867  // Start building the ZFS file-systems
868  QStringList zMnts;
869  fsType = "ZFS";
870  int zpoolSize = getDiskSliceSize();
871
872  // Deduct any swap space
873  zpoolSize = zpoolSize - swapsize;
874
875  // Get the zfs mounts
876  QList<QTreeWidgetItem *> mItems = treeMounts->findItems("*", Qt::MatchWildcard);
877  for ( int i = 0; i < mItems.size(); ++i) {
878    if ( mItems.at(i)->text(2).isEmpty() )
879      zMnts << mItems.at(i)->text(1);
880    else
881      zMnts << mItems.at(i)->text(1) + "(" + mItems.at(i)->text(2) + ")";
882  }
883
884  // If we have any additional ZFS mirror / raidz devices set it up now
885  QString zOpts, zDisk;
886  if ( groupZFSOpts->isChecked() && comboPartition->currentIndex() == 0 ) {
887     zOpts = comboZFSMode->currentText() + ":";
888     for ( int i = 0; i < listZFSDisks->count(); ++i )
889        if ( listZFSDisks->item(i)->checkState() == Qt::Checked ) {
890           zDisk = listZFSDisks->item(i)->text();
891           zDisk.truncate(zDisk.indexOf(" -"));
892           zOpts = zOpts + " " + zDisk;
893        }
894  }
895
896  // Save the final disk layout
897  fileSystem.clear();
898  fileSystem << targetDisk << targetSlice << zMnts.join(",") << fsType << tmp.setNum(zpoolSize) << zOpts << tmpPass;
899  sysFinalDiskLayout << fileSystem;
900
901  fileSystem.clear();
902  fileSystem << targetDisk << targetSlice << "SWAP" << "SWAP" << tmp.setNum(swapsize) << "" << "";
903  sysFinalDiskLayout << fileSystem;
904
905  qDebug() <<"AutoLayout:" << sysFinalDiskLayout;
906}
907
908void wizardDisk::generateConfirmationText()
909{
910  // If running in expert mode, we just create a simple config / confirmation
911  if ( radioExpert->isChecked() ) {
912    QStringList filesystem;
913    filesystem << "MANUAL" << "/mnt" ;
914    sysFinalDiskLayout << filesystem;
915    textConfirmation->setText(tr("Installing to file-system mounted at /mnt"));
916    return;
917  }
918
919  QList<QStringList> copyList;
920  QStringList summaryList;
921  QString tmp, workingDisk, workingSlice, tmpSlice, XtraTmp, startPart, sliceSize;
922  int disk = 0;
923
924  // Copy over the list to a new variable we can mangle without modifying the original
925  copyList = sysFinalDiskLayout;
926
927  // Start our summary
928  summaryList << "";
929  summaryList << "<b>" + tr("The disk will be setup with the following configuration:") + "</b>";
930
931  while ( ! copyList.empty() )
932  {
933    workingDisk = copyList.at(0).at(0);
934    workingSlice = copyList.at(0).at(1);
935    tmpSlice = workingSlice;
936
937    // Check if this is an install to "Unused Space"
938    for (int z=0; z < sysDisks.count(); ++z)
939      if ( sysDisks.at(z).at(0) == "SLICE" \
940        && sysDisks.at(z).at(2) == workingDisk + workingSlice \
941        && sysDisks.at(z).at(4) == "Unused Space" )
942          tmpSlice = "free";
943
944    // Check for any mirror for this device
945    for (int i=0; i < copyList.count(); ++i) {
946       if ( copyList.at(i).at(2).indexOf("MIRROR(" + workingDisk + ")") != -1 )
947       {
948         summaryList << tr("Disk:") + copyList.at(i).at(0) + " " + tr("Mirroring:") + workingDisk;
949         copyList.removeAt(i);
950         break;
951       }
952    }
953
954    // If after doing the mirror, our list is empty, break out
955    if ( copyList.empty() )
956      break;
957   
958    // If there is a dedicated /boot partition, need to list that first, see what is found
959    for (int i=0; i < copyList.count(); ++i) {
960      QStringList mounts = copyList.at(i).at(2).split(",");
961      for (int z = 0; z < mounts.size(); ++z) {
962        if ( copyList.at(i).at(0) == workingDisk \
963          && copyList.at(i).at(1) == workingSlice \
964          && mounts.at(z) == "/boot" )
965                startPart="/boot";
966      }
967    }
968
969    // If no dedicated /boot partition, then lets list "/" first
970    if(startPart.isEmpty())
971        startPart="/";
972
973    // Start by looking for the root partition
974    for (int i=0; i < copyList.count(); ++i) {
975      QStringList mounts = copyList.at(i).at(2).split(",");
976      for (int z = 0; z < mounts.size(); ++z) {
977        if ( copyList.at(i).at(0) == workingDisk \
978          && copyList.at(i).at(1) == workingSlice \
979          && mounts.at(z) == startPart ) {
980
981          // Check if we have any extra arguments to throw on the end
982          XtraTmp="";
983          if ( ! copyList.at(i).at(5).isEmpty() )
984            XtraTmp=" (" + copyList.at(i).at(5) + ")" ;
985
986          // Write the user summary
987          summaryList << "";
988          summaryList << tr("Partition:") + " " + workingDisk + "(" + workingSlice + "):";
989          summaryList << tr("FileSystem:") + " " + copyList.at(i).at(3);
990          summaryList << tr("Size:") + " " + copyList.at(i).at(4) + "MB ";
991
992          if ( copyList.at(i).at(3) == "ZFS" ) {
993            QStringList zDS = copyList.at(i).at(2).split(",/");
994            QString zTMP;
995            for (int ds = 0; ds < zDS.size(); ++ds) {
996              if ( zDS.at(ds) != "/" )
997                zDS.replace(ds, "/" + zDS.at(ds));
998              if ( zDS.at(ds).indexOf("(") != -1 ) {
999                zTMP = zDS.at(ds);
1000                zTMP.replace("(", " (");
1001                zDS.replace(ds, zTMP );
1002              }
1003            }
1004            summaryList << tr("ZFS Datasets:<br>") + " " + zDS.join("<br>");
1005          } else {
1006            summaryList << tr("Mount:") + " " + copyList.at(i).at(2);
1007          }
1008          if ( ! XtraTmp.isEmpty() ) {
1009            summaryList << tr("Options:") + " " + copyList.at(i).at(5);
1010          }
1011
1012          // Done with this item, remove it now
1013          copyList.removeAt(i);
1014          break;
1015        }
1016      }
1017    }
1018
1019
1020    // Now look for SWAP
1021    for (int i=0; i < copyList.count(); ++i) {
1022      if ( copyList.at(i).at(0) == workingDisk \
1023        && copyList.at(i).at(1) == workingSlice \
1024        && copyList.at(i).at(2) == "SWAP" ) {
1025
1026        // Write the user summary
1027        summaryList << "";
1028        summaryList << tr("Partition:") + " " + workingDisk + "(" + workingSlice + "):";
1029        summaryList << tr("FileSystem:") + " " + copyList.at(i).at(3);
1030        summaryList << tr("Size:") + " " + copyList.at(i).at(4) + "MB ";
1031
1032        // Done with this item, remove it now
1033        copyList.removeAt(i);
1034        break;
1035      }
1036    }
1037
1038 
1039    // Now look for any other partitions
1040    int count = copyList.count();
1041    for (int i=0; i < count; ++i) {
1042      if ( copyList.at(i).at(0) == workingDisk \
1043        && copyList.at(i).at(1) == workingSlice ) {
1044
1045        // Check if we have any extra arguments to throw on the end
1046        XtraTmp="";
1047        if ( ! copyList.at(i).at(5).isEmpty() )
1048          XtraTmp=" (" + copyList.at(i).at(5) + ")" ;
1049
1050        // If we are working on the last partition, set the size to 0 to use remaining disk
1051        if ( i == (count - 1) ) 
1052                sliceSize = "0";
1053        else
1054                sliceSize=copyList.at(i).at(4);
1055
1056        // Write the user summary
1057        summaryList << "";
1058        summaryList << tr("Partition:") + " " + workingDisk + "(" + workingSlice + "):";
1059        summaryList << tr("FileSystem:") + " " + copyList.at(i).at(3);
1060        summaryList << tr("Size:") + " " + copyList.at(i).at(4) + "MB ";
1061        summaryList << tr("Mount:") + " " + copyList.at(i).at(2);
1062        if ( ! XtraTmp.isEmpty() ) {
1063          summaryList << tr("Options:") + " " + copyList.at(i).at(5);
1064        }
1065
1066        // Done with this item, remove it now
1067        copyList.removeAt(i);
1068        i--;
1069        count--;
1070      }
1071    }
1072
1073    // Increment our disk counter
1074    disk++;
1075  }
1076
1077  textConfirmation->setText(summaryList.join("<br>"));
1078}
1079
1080void wizardDisk::slotTerminal()
1081{
1082  system("xterm &");
1083}
1084
1085void wizardDisk::setRestoreMode()
1086{
1087  restoreMode=true;
1088}
1089
1090void wizardDisk::slotGPTClicked()
1091{
1092   // Right now we can't do the dirty "gnop" trick on GPT
1093   // Mangles the partitions and fails to boot
1094   if ( checkGPT->isChecked() )
1095   {
1096     checkForce4K->setChecked(false);
1097     checkForce4K->setEnabled(false);
1098   } else {
1099     checkForce4K->setEnabled(true);
1100   }
1101}
Note: See TracBrowser for help on using the repository browser.