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

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

For sanity sake, don't try to do installs to disks < 4GB

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