Author: fehr
Date: Thu Mar 24 17:28:28 2011
New Revision: 63670
URL: http://svn.opensuse.org/viewcvs/yast?rev=63670&view=rev
Log:
add code to add/remove volumes to/from BTRFS volume
Modified:
trunk/storage/package/yast2-storage.changes
trunk/storage/storage/src/include/ep-btrfs-dialogs.ycp
trunk/storage/storage/src/include/ep-btrfs-lib.ycp
trunk/storage/storage/src/include/ep-btrfs.ycp
trunk/storage/storage/src/modules/Storage.ycp
Modified: trunk/storage/package/yast2-storage.changes
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/package/yast2-storage.changes?rev=63670&r1=63669&r2=63670&view=diff
==============================================================================
--- trunk/storage/package/yast2-storage.changes (original)
+++ trunk/storage/package/yast2-storage.changes Thu Mar 24 17:28:28 2011
@@ -1,4 +1,9 @@
-------------------------------------------------------------------
+Thu Mar 24 17:27:26 CET 2011 - fehr@suse.de
+
+- add code to add/remove volumes to/from BTRFS volume
+
+-------------------------------------------------------------------
Thu Mar 3 18:05:04 CET 2011 - fehr@suse.de
- integrate handling of BTRFS volumes
Modified: trunk/storage/storage/src/include/ep-btrfs-dialogs.ycp
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/storage/src/include/ep-btrfs-dialogs.ycp?rev=63670&r1=63669&r2=63670&view=diff
==============================================================================
--- trunk/storage/storage/src/include/ep-btrfs-dialogs.ycp (original)
+++ trunk/storage/storage/src/include/ep-btrfs-dialogs.ycp Thu Mar 24 17:28:28 2011
@@ -11,20 +11,20 @@
boolean DlgEditBtrfsVolume(map &data)
- {
+ {
y2milestone( "DlgEditBtrfsVolume %1", data );
string device = data["device"]:"error";
map aliases = $[
"FormatMount" : ``(MiniWorkflowStepFormatMount(data)),
"Password" : ``(MiniWorkflowStepPassword(data))
- ];
+ ];
map sequence = $[
"FormatMount" : $[ `next : "Password",
`finish : `finish ],
"Password" : $[ `finish : `finish ]
- ];
+ ];
// dialog title
string title = sformat(_("Edit Btrfs %1"), data["uuid"]:"");
@@ -32,5 +32,181 @@
symbol widget = MiniWorkflow::Run(title, StorageIcons::lvm_lv_icon, aliases, sequence, "FormatMount");
return widget == `finish;
- }
+ }
+
+ /////////////////////////////////////////////////////////////////
+ // Get all volumes, we can probably use as volumes in an BTRFS
+ // Add needed information: disksize
+ define list<map> GetPossibleVols( map targetMap )
+ {
+ list<map> ret = [];
+
+ //////////////////////////////////////////////////////////////////////
+ // add the devicename i.e /dev/hda1 or /dev/system/usr to partition list
+
+ targetMap = mapmap( string dev, map devmap, targetMap,
+ {
+ list partitions = maplist( map part, devmap["partitions"]:[],
+ {
+ part["maindev"] = dev;
+ return( part );
+ });
+ return( $[ dev: add(devmap, "partitions", partitions) ] );
+ });
+
+ ////////////////////////////////////////////////////////////
+ // Look for all partitions:
+ // no mountpoint
+ // id 0x83
+
+ list types_no = [ `btrfs, `extended ];
+ list types_ok = [ `sw_raid, `dm, `lvm ];
+ list fsids = [ Partitions::fsid_native, Partitions::fsid_lvm, Partitions::fsid_raid ];
+ list allowed_enc_types = [ `none ];
+
+ foreach( string dev, map devmap, targetMap,
+ ``{
+ y2milestone( "GetPossibleVols parts:%1", devmap["partitions"]:[] );
+ list<map> parts =
+ filter( map part, devmap["partitions"]:[],
+ ``( size(part["mount"]:"")==0 &&
+ !contains( types_no, part["type"]:`primary ) &&
+ contains(allowed_enc_types, part["enc_type"]:`none) &&
+ (!Storage::IsUsedBy(part) || part["used_by_type"]:`UB_NONE==`UB_BTRFS) &&
+ (contains( types_ok, part["type"]:`primary ) ||
+ contains( fsids, part["fsid"]:0 ))));
+ y2milestone( "GetPossibleVols filter:%1", parts );
+ if( devmap["used_by_type"]:`UB_NONE!=`UB_NONE )
+ {
+ parts = [];
+ y2milestone( "GetPossibleVols no parts, disk used by %1 %2",
+ devmap["used_by_type"]:`UB_NONE, devmap["used_by_device"]:"" );
+ }
+ /* currently disallow usage of whole disk devices as parts of BTRFS volumes
+ if( size(devmap["partitions"]:[])==0 &&
+ Storage::IsPartType(devmap["type"]:`CT_UNKNOWN) &&
+ (!Storage::IsUsedBy(devmap) || devmap["used_by_type"]:`UB_NONE==`UB_LVM))
+ {
+ map p = $[ "device":dev, "maindev":dev,
+ "size_k":devmap["size_k"]:0 ];
+ if( devmap["used_by_type"]:`UB_NONE != `UB_NONE )
+ {
+ p["used_by_type"] = devmap["used_by_type"]:`UB_NONE;
+ p["used_by_device"] = devmap["used_by_device"]:"";
+ }
+ parts = [ p ];
+ }
+ */
+ ret = (list<map>)merge( ret, parts );
+ });
+ y2milestone( "GetPossibleVols ret %1", ret );
+ return( ret );
+ }
+
+ boolean CheckNumberOfDevicesForVolume(integer num)
+ {
+ if (num < 1)
+ {
+ // error popup
+ Popup::Error(sformat(_("Select at least one device.")));
+ UI::SetFocus(`id(`unselected));
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ string MiniWorkflowStepResizeVolumeHelptext()
+ {
+ // helptext
+ string helptext = _("<p>Change the devices that are used by the BTRFS volume.</p>");
+
+ return helptext;
+ }
+
+
+ symbol MiniWorkflowStepResizeVolume(map &data)
+ {
+ y2milestone("MiniWorkflowStepResizeVolume data:%1", data);
+
+ string vgname = data["name"]:"error";
+ list<string> pvs_new = [];
+
+ list<symbol> fields = StorageSettings::FilterTable([ `device, `udev_path, `udev_id, `size, `encrypted, `type ]);
+
+ map target_map = Storage::GetTargetMap();
+ list<map> unused_pvs = filter(map pv, GetPossibleVols(target_map), { return !Storage::IsUsedBy(pv); });
+ list<map> used_pvs = filter(map pv, GetPossibleVols(target_map), { return pv["used_by_device"]:"" == data["uuid"]:""; });
+
+ term contents = `VBox();
+
+ contents = add(contents, DevicesSelectionBox::Create(unused_pvs, used_pvs, fields, nil,
+ _("Unused Devices:"),
+ _("Selected Devices:")));
+
+ MiniWorkflow::SetContents(Greasemonkey::Transform(contents), MiniWorkflowStepResizeVolumeHelptext());
+ MiniWorkflow::SetLastStep(true);
+
+ symbol widget = nil;
+
+ repeat
+ {
+ widget = MiniWorkflow::UserInput();
+ DevicesSelectionBox::Handle(widget);
+
+ switch (widget)
+ {
+ case `next:
+ {
+ pvs_new = maplist(map pv, DevicesSelectionBox::GetSelectedDevices(), {
+ return pv["device"]:"";
+ });
+
+ if (!CheckNumberOfDevicesForVolume(size(pvs_new)))
+ widget = `again;
+
+ // TODO: overall size check
+ }
+ break;
+ }
+ }
+ until (widget == `abort || widget == `back || widget == `next);
+
+ if (widget == `next)
+ {
+ data["devices_new"] = pvs_new;
+
+ widget = `finish;
+ }
+
+ y2milestone("MiniWorkflowStepResizeVg data:%1 ret:%2", data, widget);
+
+ return widget;
+ }
+
+
+ boolean DlgResizeBtrfsVolume(map &data, symbol() Commit)
+ {
+ map aliases = $[
+ "TheOne" : ``(MiniWorkflowStepResizeVolume(data)),
+ "Commit" : ``(Commit())
+ ];
+
+ map sequence = $[
+ "TheOne" : $[ `finish : "Commit" ],
+ "Commit" : $[ `finish : `finish ]
+ ];
+
+ y2milestone( "data:%1", data );
+
+ // dialog title
+ string title = sformat(_("Resize Btrfs Volume %1"), data["uuid"]:"error");
+
+ symbol widget = MiniWorkflow::Run(title, StorageIcons::lvm_icon, aliases, sequence, "TheOne");
+
+ return widget == `finish;
+ }
+
}
Modified: trunk/storage/storage/src/include/ep-btrfs-lib.ycp
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/storage/src/include/ep-btrfs-lib.ycp?rev=63670&r1=63669&r2=63670&view=diff
==============================================================================
--- trunk/storage/storage/src/include/ep-btrfs-lib.ycp (original)
+++ trunk/storage/storage/src/include/ep-btrfs-lib.ycp Thu Mar 24 17:28:28 2011
@@ -10,88 +10,140 @@
textdomain "storage";
- void EpEditBtrfsDevice(string device)
+void EpEditBtrfsDevice(string device)
{
- if (device == nil)
+ if (device == nil)
{
- // error popup
- Popup::Error(_("No BTRFS device selected."));
- return;
+ // error popup
+ Popup::Error(_("No BTRFS device selected."));
+ return;
}
- map target_map = Storage::GetTargetMap();
- map data = Storage::GetPartition(target_map, device);
- y2milestone( "EpEditBtrfsDevice device:%1 data:%2", device, data );
+ map target_map = Storage::GetTargetMap();
+ map data = Storage::GetPartition(target_map, device);
+ y2milestone( "EpEditBtrfsDevice device:%1 data:%2", device, data );
- if (Storage::IsUsedBy(data))
+ if (Storage::IsUsedBy(data))
{
- // error popup
- Popup::Error(sformat(_("The Btrfs %1 is in use. It cannot be
+ // error popup
+ Popup::Error(sformat(_("The Btrfs %1 is in use. It cannot be
edited. To edit %1, make sure it is not used."), data["uuid"]:""));
- return;
+ return;
}
- if (DlgEditBtrfsVolume(data))
+ if (DlgEditBtrfsVolume(data))
{
- Storage::ChangeVolumeProperties(data);
+ Storage::ChangeVolumeProperties(data);
- UpdateMainStatus();
- UpdateNavigationTree(nil);
- TreePanel::Create();
- UpdateTableFocus(device);
+ UpdateMainStatus();
+ UpdateNavigationTree(nil);
+ TreePanel::Create();
+ UpdateTableFocus(device);
}
}
- void EpDeleteBtrfsDevice(string device)
+void EpDeleteBtrfsDevice(string device)
{
- if (device == nil)
+ if (device == nil)
{
- // error popup
- Popup::Error(_("No BTRFS device selected."));
- return;
+ // error popup
+ Popup::Error(_("No BTRFS device selected."));
+ return;
}
- map target_map = Storage::GetTargetMap();
- map data = Storage::GetPartition(target_map, device);
- y2milestone( "EpDeletBtrfsDevice device:%1 data:%2", device, data );
+ map target_map = Storage::GetTargetMap();
+ map data = Storage::GetPartition(target_map, device);
+ y2milestone( "EpDeletBtrfsDevice device:%1 data:%2", device, data );
- if (!Storage::CanDelete(data, target_map["/dev/btrfs"]:$[], true))
- return;
+ if (!Storage::CanDelete(data, target_map["/dev/btrfs"]:$[], true))
+ return;
- if (EpDeleteDevice(device))
- {
- any new_focus = nil;
- if (UI::QueryWidget(`tree, `CurrentItem) == device)
- new_focus = `md;
- UpdateMainStatus();
- UpdateNavigationTree(new_focus);
- TreePanel::Create();
+ if (EpDeleteDevice(device))
+ {
+ any new_focus = nil;
+ if (UI::QueryWidget(`tree, `CurrentItem) == device)
+ new_focus = `md;
+ UpdateMainStatus();
+ UpdateNavigationTree(new_focus);
+ TreePanel::Create();
}
+ }
+
+boolean AddVols(string device, list<string> devs)
+ {
+ boolean ret = true;
+
+ foreach(string dev, devs, {
+ Storage::SetPartitionId(dev, Partitions::fsid_native);
+ Storage::SetPartitionFormat(dev, false, `none);
+ if (!Storage::ExtendBtrfsVolume(device, dev))
+ ret = false;
+ });
+ return ret;
+ }
+
+
+boolean RemoveVols(string device, list<string> devs)
+ {
+ boolean ret = true;
+ foreach(string dev, devs, {
+ Storage::UnchangePartitionId(dev);
+ if (!Storage::ReduceBtrfsVolume(device, dev))
+ ret = false;
+ });
+ return ret;
}
- void EpResizeBtrfsDevice(string device)
+void EpResizeBtrfsDevice(string device)
{
- if (device == nil)
+ if (device == nil)
{
- // error popup
- Popup::Error(_("No BTRFS device selected."));
- return;
+ // error popup
+ Popup::Error(_("No BTRFS device selected."));
+ return;
}
- map target_map = Storage::GetTargetMap();
- map data = Storage::GetPartition(target_map, device);
- y2milestone( "EpResizetrfsDevice device:%1 data:%2", device, data );
+ map target_map = Storage::GetTargetMap();
+ map data = Storage::GetPartition(target_map, device);
+ y2milestone( "EpResizeBtrfsDevice device:%1 data:%2", device, data );
- if (true/*EpDeleteDevice(device)*/)
+ symbol Commit()
+ {
+ list<string> devices_old = MergeDevices(data);
+ list<string> devices_new = data["devices_new"]:[];
+
+ list<string> devices_added = AddedToList(devices_old, devices_new);
+ list<string> devices_removed = RemovedFromList(devices_old, devices_new);
+
+ if(size(devices_added)>0)
+ y2milestone("EpResizeBtrfsDevice device_added:%1", devices_added );
+ if(size(devices_removed)>0)
+ y2milestone("EpResizeBtrfsDevice device_removed:%1", devices_removed );
+
+ if( size(devices_added) > 0 || size(devices_removed) > 0)
{
- any new_focus = nil;
- if (UI::QueryWidget(`tree, `CurrentItem) == device)
- new_focus = `btrfs;
- UpdateMainStatus();
- UpdateNavigationTree(new_focus);
- TreePanel::Create();
+ AddVols(device, devices_added);
+
+ if (!RemoveVols(device, devices_removed))
+ {
+ // error popup
+ Popup::Error(_("Failed to remove some physical devices."));
+
+ // TODO: update data
+
+ return `back;
+ }
+ }
+
+ return `finish;
}
+ if( DlgResizeBtrfsVolume(data, Commit))
+ {
+ UpdateMainStatus();
+ UpdateNavigationTree(nil);
+ TreePanel::Create();
+ }
}
}
Modified: trunk/storage/storage/src/include/ep-btrfs.ycp
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/storage/src/include/ep-btrfs.ycp?rev=63670&r1=63669&r2=63670&view=diff
==============================================================================
--- trunk/storage/storage/src/include/ep-btrfs.ycp (original)
+++ trunk/storage/storage/src/include/ep-btrfs.ycp Thu Mar 24 17:28:28 2011
@@ -16,7 +16,8 @@
void EpContextMenuBtrfs(string device)
{
symbol widget = ContextMenu::Simple([ `item(`id(`edit), _("Edit")),
- `item(`id(`delete), _("Delete"))]);
+ `item(`id(`delete), _("Delete")),
+ `item(`id(`resize), _("Resize"))]);
switch (widget)
{
@@ -26,6 +27,9 @@
case `delete:
EpDeleteBtrfsDevice(device);
break;
+ case `resize:
+ EpResizeBtrfsDevice(device);
+ break;
}
}
Modified: trunk/storage/storage/src/modules/Storage.ycp
URL: http://svn.opensuse.org/viewcvs/yast/trunk/storage/storage/src/modules/Storage.ycp?rev=63670&r1=63669&r2=63670&view=diff
==============================================================================
--- trunk/storage/storage/src/modules/Storage.ycp (original)
+++ trunk/storage/storage/src/modules/Storage.ycp Thu Mar 24 17:28:28 2011
@@ -1694,10 +1694,16 @@
p["fstype"] = Partitions::btrfs_name;
list<string> ls = splitstring(LibStorage::BtrfsInfo::swig_devices_get(info), "\n");
p["devices"] = ls;
+ ls = splitstring( LibStorage::BtrfsInfo::swig_devices_add_get(info), "\n" );
+ if( size(ls)>0 )
+ c["devices_add"] = ls;
+ ls = splitstring( LibStorage::BtrfsInfo::swig_devices_rem_get(info), "\n" );
+ if( size(ls)>0 )
+ c["devices_rem"] = ls;
ls = splitstring(LibStorage::BtrfsInfo::swig_subvol_get(info), "\n");
if( !isempty(ls) )
p["subvol"] = maplist( string s, ls, ``{ map m = $[ "name" : s ]; return( m ); });
- if( size(p["devices"]:[])>1 )
+ if( size(p["devices"]:[])+size(p["devices_add"]:[])>1 )
p["device"] = "UUID=" + p["uuid"]:"";
c["partitions"] = add( c["partitions"]:[], p );
});
@@ -2754,6 +2760,30 @@
return( ret==0 );
}
+global boolean ExtendBtrfsVolume( string uuid, string device )
+ {
+ y2milestone( "ExtendBtrfsVolume uuid:%1 device:%2", uuid, device );
+ integer ret = 0;
+ list<string> devs = [ device ];
+ ret = LibStorage::StorageInterface::extendBtrfsVolume( sint, uuid, devs );
+ if( ret<0 )
+ y2error( "ExtendBtrfsVolume sint ret:%1", ret );
+ UpdateTargetMap();
+ return( ret==0 );
+ }
+
+global boolean ReduceBtrfsVolume( string uuid, string device )
+ {
+ y2milestone( "ReduceBtrfsVolume uuid:%1 device:%2", uuid, device );
+ integer ret = 0;
+ list<string> devs = [ device ];
+ ret = LibStorage::StorageInterface::shrinkBtrfsVolume( sint, uuid, devs );
+ if( ret<0 )
+ y2error( "ReduceBtrfsVolume sint ret:%1", ret );
+ UpdateTargetMap();
+ return( ret==0 );
+ }
+
global boolean AddNfsVolume( string nfsdev, string opts, integer sz, string mp, boolean nfs4 )
{
y2milestone("AddNfsVolume dev:%1 opts:%2 size:%3 mp:%4 nfs4:%5", nfsdev, opts, sz, mp, nfs4);
--
To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org
For additional commands, e-mail: yast-commit+help@opensuse.org