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

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

When user is installing to a MBR slice, and declines to install GRUB on MBR, we
will instead stamp it on the particular slice being used. Then the user
can manage their own MBR boot-loader to chain-load GRUB from the slice

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