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

9.2-releasereleng/10.0releng/10.0.1
Last change on this file since 7431d6d was 7431d6d, checked in by Kris Moore <kris@…>, 9 months ago

Dont show ZFS compression options on the boot device '/'

This causes issues with the boot-loader being unable to read the dev and
then not boot.

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