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

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

Fix a bug where raidz options are left enabled if user goes back and
picks a slice to install onto

Reported By: Josh Smith

  • Property mode set to 100644
File size: 29.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(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
598  popupCmp = popup->addMenu("compression");
599  popupCmp->addAction( "off", this, SLOT(slotZCmpOFF()));
600  popupCmp->addAction( "lzjb", this, SLOT(slotZCmpLZJB()));
601  popupCmp->addAction( "gzip", this, SLOT(slotZCmpGZIP()));
602  popupCmp->addAction( "zle", this, SLOT(slotZCmpZLE()));
603
604  // Create dedup sub-menu
605  // dedup is disabled for now, until such time as it is safe in all cases
606  //popupDD = popup->addMenu("dedup");
607  //popupDD->addAction( "off", this, SLOT(slotZDDOFF()));
608  //popupDD->addAction( "on", this, SLOT(slotZDDON()));
609  //popupDD->addAction( "verify", this, SLOT(slotZDDVERIFY()));
610
611  // Create exec sub-menu
612  popupNE = popup->addMenu("exec");
613  popupNE->addAction( "on", this, SLOT(slotZEXON()));
614  popupNE->addAction( "off", this, SLOT(slotZEXOFF()));
615
616  popup->exec( QCursor::pos() );
617
618}
619
620void wizardDisk::slotZCMNOAUTO()
621{
622  toggleZFSOpt(QString("canmount=noauto"));
623}
624
625void wizardDisk::slotZCMOFF()
626{
627  toggleZFSOpt(QString("canmount=off"));
628}
629
630void wizardDisk::slotZCMON()
631{
632  toggleZFSOpt(QString("canmount=on"));
633}
634
635void wizardDisk::slotZDDVERIFY()
636{
637  toggleZFSOpt(QString("dedup=verify"));
638}
639
640void wizardDisk::slotZDDON()
641{
642  toggleZFSOpt(QString("dedup=on"));
643}
644
645void wizardDisk::slotZDDOFF()
646{
647  toggleZFSOpt(QString("dedup=off"));
648}
649
650void wizardDisk::slotZCmpZLE()
651{
652  toggleZFSOpt(QString("compress=zle"));
653}
654
655void wizardDisk::slotZCmpGZIP()
656{
657  toggleZFSOpt(QString("compress=gzip"));
658}
659
660void wizardDisk::slotZCmpLZJB()
661{
662  toggleZFSOpt(QString("compress=lzjb"));
663}
664
665void wizardDisk::slotZCmpOFF()
666{
667  toggleZFSOpt(QString("compress=off"));
668}
669
670void wizardDisk::slotZChkOFF()
671{
672  toggleZFSOpt(QString("checksum=off"));
673}
674
675void wizardDisk::slotZChkON()
676{
677  toggleZFSOpt(QString("checksum=on"));
678}
679
680void wizardDisk::slotZATON()
681{
682  toggleZFSOpt(QString("atime=on"));
683}
684
685void wizardDisk::slotZSwapSize()
686{
687  bool ok;
688  QString tmp;
689  int size = QInputDialog::getInt(this, tr("Enter SWAP size"),
690                                  tr("Size (MB)"), 2048, 0, 1000000, 1, &ok);
691  if ( ok )
692  {
693    tmp.setNum(size);
694    QString optString = "volsize=" + tmp + "M|org.freebsd:swap=on|checksum=off";
695    treeMounts->currentItem()->setText(2, optString);
696    treeMounts->currentItem()->setToolTip(2, optString);
697  }
698}
699
700void wizardDisk::slotZATOFF()
701{
702  toggleZFSOpt(QString("atime=off"));
703}
704
705void wizardDisk::slotZEXOFF()
706{
707  toggleZFSOpt(QString("exec=off"));
708}
709
710void wizardDisk::slotZEXON()
711{
712  toggleZFSOpt(QString("exec=on"));
713}
714
715// Toggle an option being on / off for ZFS
716void wizardDisk::toggleZFSOpt(QString option)
717{
718  if ( ! treeMounts->currentItem() )
719    return;
720
721  bool found = false;
722  QString optTag = option.section("=", 0, 0);
723  QString tmpTag;
724  QStringList newOpts;
725  QStringList curOpts = treeMounts->currentItem()->text(2).split("|");
726  for (int i=0; i < curOpts.count(); ++i) {
727    tmpTag=curOpts.at(i).section("=", 0, 0);
728    if ( optTag == tmpTag ) {
729      found = true;
730      // Only save option if setting to new value
731      if ( option != curOpts.at(i) )
732        newOpts << option;
733    } else {
734      if ( !curOpts.at(i).isEmpty() )
735        newOpts << curOpts.at(i);
736    }
737  }
738
739  if ( ! found )
740      newOpts << option;
741
742  QString optString;
743  if ( newOpts.count() <= 1)
744    optString = newOpts.join("");
745  else
746    optString = newOpts.join("|");
747
748  treeMounts->currentItem()->setText(2, optString);
749  treeMounts->currentItem()->setToolTip(2, optString);
750}
751
752void wizardDisk::generateCustomDiskLayout()
753{
754  QString targetType, tmp;
755  int targetLoc;
756  QString targetDisk, targetSlice, tmpPass, fsType, target;
757
758  // Clear out the original disk layout
759  sysFinalDiskLayout.clear();
760  QStringList fileSystem;
761  qDebug() << "Generating custom disk layout";
762       
763  if ( comboPartition->currentIndex() == 0) {
764    targetType = "DRIVE";
765    targetSlice = "ALL";
766    targetDisk = comboDisk->currentText();
767    targetDisk.truncate(targetDisk.indexOf(" -"));
768    target = targetDisk;
769    targetLoc = 1;
770  } else {
771    targetType = "SLICE";
772    targetDisk = comboDisk->currentText();
773    targetDisk.truncate(targetDisk.indexOf(" -"));
774    targetSlice = comboPartition->currentText();
775    targetSlice.truncate(targetSlice.indexOf(":"));
776    targetSlice = targetSlice.remove(0, targetSlice.size() -2);
777    target = targetDisk + targetSlice;
778    targetLoc = 2;
779  }
780
781  // Start building the ZFS file-systems
782  QStringList zMnts;
783  fsType = "ZFS";
784  int zpoolSize = getDiskSliceSize();
785
786  // Get the zfs mounts
787  QList<QTreeWidgetItem *> mItems = treeMounts->findItems("*", Qt::MatchWildcard);
788  for ( int i = 0; i < mItems.size(); ++i) {
789    if ( mItems.at(i)->text(2).isEmpty() )
790      zMnts << mItems.at(i)->text(1);
791    else
792      zMnts << mItems.at(i)->text(1) + "(" + mItems.at(i)->text(2) + ")";
793  }
794
795  // If we have any additional ZFS mirror / raidz devices set it up now
796  QString zOpts, zDisk;
797  if ( groupZFSOpts->isChecked() && comboPartition->currentIndex() == 0 ) {
798     zOpts = comboZFSMode->currentText() + ":";
799     for ( int i = 0; i < listZFSDisks->count(); ++i )
800        if ( listZFSDisks->item(i)->checkState() == Qt::Checked ) {
801           zDisk = listZFSDisks->item(i)->text();
802           zDisk.truncate(zDisk.indexOf(" -"));
803           zOpts = zOpts + " " + zDisk;
804        }
805  }
806
807  // Save the final disk layout
808  fileSystem.clear();
809  fileSystem << targetDisk << targetSlice << zMnts.join(",") << fsType << tmp.setNum(zpoolSize) << zOpts << tmpPass;
810  sysFinalDiskLayout << fileSystem;
811
812  qDebug() <<"AutoLayout:" << sysFinalDiskLayout;
813}
814
815void wizardDisk::generateConfirmationText()
816{
817  // If running in expert mode, we just create a simple config / confirmation
818  if ( radioExpert->isChecked() ) {
819    QStringList filesystem;
820    filesystem << "MANUAL" << "/mnt" ;
821    sysFinalDiskLayout << filesystem;
822    textConfirmation->setText(tr("Installing to file-system mounted at /mnt"));
823    return;
824  }
825
826  QList<QStringList> copyList;
827  QStringList summaryList;
828  QString tmp, workingDisk, workingSlice, tmpSlice, XtraTmp, startPart, sliceSize;
829  int disk = 0;
830
831  // Copy over the list to a new variable we can mangle without modifying the original
832  copyList = sysFinalDiskLayout;
833
834  // Start our summary
835  summaryList << "";
836  summaryList << "<b>" + tr("The disk will be setup with the following configuration:") + "</b>";
837
838  while ( ! copyList.empty() )
839  {
840    workingDisk = copyList.at(0).at(0);
841    workingSlice = copyList.at(0).at(1);
842    tmpSlice = workingSlice;
843
844    // Check if this is an install to "Unused Space"
845    for (int z=0; z < sysDisks.count(); ++z)
846      if ( sysDisks.at(z).at(0) == "SLICE" \
847        && sysDisks.at(z).at(2) == workingDisk + workingSlice \
848        && sysDisks.at(z).at(4) == "Unused Space" )
849          tmpSlice = "free";
850
851    // Check for any mirror for this device
852    for (int i=0; i < copyList.count(); ++i) {
853       if ( copyList.at(i).at(2).indexOf("MIRROR(" + workingDisk + ")") != -1 )
854       {
855         summaryList << tr("Disk:") + copyList.at(i).at(0) + " " + tr("Mirroring:") + workingDisk;
856         copyList.removeAt(i);
857         break;
858       }
859    }
860
861    // If after doing the mirror, our list is empty, break out
862    if ( copyList.empty() )
863      break;
864   
865    // If there is a dedicated /boot partition, need to list that first, see what is found
866    for (int i=0; i < copyList.count(); ++i) {
867      QStringList mounts = copyList.at(i).at(2).split(",");
868      for (int z = 0; z < mounts.size(); ++z) {
869        if ( copyList.at(i).at(0) == workingDisk \
870          && copyList.at(i).at(1) == workingSlice \
871          && mounts.at(z) == "/boot" )
872                startPart="/boot";
873      }
874    }
875
876    // If no dedicated /boot partition, then lets list "/" first
877    if(startPart.isEmpty())
878        startPart="/";
879
880    // Start by looking for the root partition
881    for (int i=0; i < copyList.count(); ++i) {
882      QStringList mounts = copyList.at(i).at(2).split(",");
883      for (int z = 0; z < mounts.size(); ++z) {
884        if ( copyList.at(i).at(0) == workingDisk \
885          && copyList.at(i).at(1) == workingSlice \
886          && mounts.at(z) == startPart ) {
887
888          // Check if we have any extra arguments to throw on the end
889          XtraTmp="";
890          if ( ! copyList.at(i).at(5).isEmpty() )
891            XtraTmp=" (" + copyList.at(i).at(5) + ")" ;
892
893          // Write the user summary
894          summaryList << "";
895          summaryList << tr("Partition:") + " " + workingDisk + "(" + workingSlice + "):";
896          summaryList << tr("FileSystem:") + " " + copyList.at(i).at(3);
897          summaryList << tr("Size:") + " " + copyList.at(i).at(4) + "MB ";
898
899          if ( copyList.at(i).at(3) == "ZFS" ) {
900            QStringList zDS = copyList.at(i).at(2).split(",/");
901            QString zTMP;
902            for (int ds = 0; ds < zDS.size(); ++ds) {
903              if ( zDS.at(ds) != "/" )
904                zDS.replace(ds, "/" + zDS.at(ds));
905              if ( zDS.at(ds).indexOf("(") != -1 ) {
906                zTMP = zDS.at(ds);
907                zTMP.replace("(", " (");
908                zDS.replace(ds, zTMP );
909              }
910            }
911            summaryList << tr("ZFS Datasets:<br>") + " " + zDS.join("<br>");
912          } else {
913            summaryList << tr("Mount:") + " " + copyList.at(i).at(2);
914          }
915          if ( ! XtraTmp.isEmpty() ) {
916            summaryList << tr("Options:") + " " + copyList.at(i).at(5);
917          }
918
919          // Done with this item, remove it now
920          copyList.removeAt(i);
921          break;
922        }
923      }
924    }
925
926
927    // Now look for SWAP
928    for (int i=0; i < copyList.count(); ++i) {
929      if ( copyList.at(i).at(0) == workingDisk \
930        && copyList.at(i).at(1) == workingSlice \
931        && copyList.at(i).at(2) == "SWAP" ) {
932
933        // Write the user summary
934        summaryList << "";
935        summaryList << tr("Partition:") + " " + workingDisk + "(" + workingSlice + "):";
936        summaryList << tr("FileSystem:") + " " + copyList.at(i).at(3);
937        summaryList << tr("Size:") + " " + copyList.at(i).at(4) + "MB ";
938
939        // Done with this item, remove it now
940        copyList.removeAt(i);
941        break;
942      }
943    }
944
945 
946    // Now look for any other partitions
947    int count = copyList.count();
948    for (int i=0; i < count; ++i) {
949      if ( copyList.at(i).at(0) == workingDisk \
950        && copyList.at(i).at(1) == workingSlice ) {
951
952        // Check if we have any extra arguments to throw on the end
953        XtraTmp="";
954        if ( ! copyList.at(i).at(5).isEmpty() )
955          XtraTmp=" (" + copyList.at(i).at(5) + ")" ;
956
957        // If we are working on the last partition, set the size to 0 to use remaining disk
958        if ( i == (count - 1) ) 
959                sliceSize = "0";
960        else
961                sliceSize=copyList.at(i).at(4);
962
963        // Write the user summary
964        summaryList << "";
965        summaryList << tr("Partition:") + " " + workingDisk + "(" + workingSlice + "):";
966        summaryList << tr("FileSystem:") + " " + copyList.at(i).at(3);
967        summaryList << tr("Size:") + " " + copyList.at(i).at(4) + "MB ";
968        summaryList << tr("Mount:") + " " + copyList.at(i).at(2);
969        if ( ! XtraTmp.isEmpty() ) {
970          summaryList << tr("Options:") + " " + copyList.at(i).at(5);
971        }
972
973        // Done with this item, remove it now
974        copyList.removeAt(i);
975        i--;
976        count--;
977      }
978    }
979
980    // Increment our disk counter
981    disk++;
982  }
983
984  textConfirmation->setText(summaryList.join("<br>"));
985}
986
987void wizardDisk::slotTerminal()
988{
989  system("xterm &");
990}
991
Note: See TracBrowser for help on using the repository browser.