Wednesday, June 20, 2012

Build Firewall Builder 'FWbuilder' 5.1.0 for Fedora 17

Howdy, FirewallBuilder released version 5.1.0 without providing an officially built rpm for Fedora 17. This post will build an rpm for Fedora 17 using the src rpm for Fedora 16 If you need help configuring the rpmbuild environment, start here. First, download the fwbuilder-5.1.0.3599-1.fc16.src.rpm file to your local directory. Next, extract the src.rpm
$ cd ~/tmp/fwbuilder
$ rpm2cpio fwbuilder-5.1.0.3599-1.fc16.src.rpm | cpio -idvm
$ mv fwbuilder-5.1.0.3599.tar.gz ~/rpmbuild/SOURCES/
$ mv fwbuilder-5.1.0.3599.spec ~/rpmbuild/SPECS/
A patch file is required due to the following build error:
../fwbuilder/uint128.h: In member function 'std::string uint128::to_string() const':
../fwbuilder/uint128.h:469:95: warning: format '%lX' expects argument of type 'long unsigned int', but argument 3 has type 'long long unsigned int' [-Wformat]
../fwbuilder/uint128.h:469:95: warning: format '%lX' expects argument of type 'long unsigned int', but argument 4 has type 'long long unsigned int' [-Wformat]
../fwbuilder/uint128.h:471:58: warning: format '%lX' expects argument of type 'long unsigned int', but argument 3 has type 'long long unsigned int' [-Wformat]
In file included from ThreadTools.cpp:31:0:
../fwbuilder/ThreadTools.h:168:5: error: 'ssize_t' does not name a type
ThreadTools.cpp:182:82: error: no 'ssize_t libfwbuilder::TimeoutCounter::read(int, void*, size_t) const' member function declared in class 'libfwbuilder::TimeoutCounter'
make[4]: *** [.obj/ThreadTools.o] Error 1
The patch was built using the following diff (patch credit debian bug 674349)
$ diff -u src/libfwbuilder/src/fwbuilder/ThreadTools.h.orig src/libfwbuilder/src/fwbuilder/ThreadTools.h > ~/rpmbuild/SOURCES/fwbuilder-5.1.0.3599.ssize_t.patch
--- src/libfwbuilder/src/fwbuilder/ThreadTools.h.orig 2012-06-20 11:31:12.029364056 -0500
+++ src/libfwbuilder/src/fwbuilder/ThreadTools.h 2012-06-20 11:09:36.000000000 -0500
@@ -31,6 +31,7 @@
 
 #include  //for time_t definition
 #include 
+#include 
 
 #include 
 #include 
Either run through the diff to generate the patch file or copy and paste the above diff into the new patch file ~/rpmbuild/SOURCES/fwbuilder-5.1.0.3599.ssize_t.patch Now edit the fwbuilder-5.1.0.3599.spec file to include the new patch file
--- fwbuilder-5.1.0.3599.spec.orig 2012-03-22 04:17:55.000000000 -0500
+++ fwbuilder-5.1.0.3599.spec 2012-06-20 11:51:09.901734348 -0500
@@ -20,6 +20,7 @@
 Group:          %{guigroup}
 Url:            http://www.fwbuilder.org/
 Source:         http://prdownloads.sourceforge.net/fwbuilder/%{name}-%{version}.tar.gz
+Patch1:         fwbuilder-5.1.0.3599.ssize_t.patch
 Packager:       Vadim Kurland 
 
 Buildroot:      %{_tmppath}/%{name}-%{version}-root
@@ -48,6 +49,7 @@
 
 %prep
 %setup 
+%patch1 -p0
 ./autogen.sh
 
 %build

Then run the build
$ cd ~/rpmbuild/SPECS
$ rpmbuild -ba fwbuilder-5.1.0.3599.spec
The result is the rpm containing
$ rpm -qpl ../RPMS/x86_64/fwbuilder-5.1.0.3599-1.fc17.uabeng.x86_64.rpm |more
/usr/bin/fwb_iosacl
/usr/bin/fwb_ipf
/usr/bin/fwb_ipfw
/usr/bin/fwb_ipt
/usr/bin/fwb_pf
/usr/bin/fwb_pix
/usr/bin/fwb_procurve_acl
/usr/bin/fwbedit
/usr/bin/fwbuilder
/usr/share/applications/fwbuilder.desktop
/usr/share/doc/fwbuilder-5.1.0.3599
...
Install the rpm using yum
$ sudo yum install ../RPMS/x86_64/fwbuilder-5.1.0.3599-1.fc17.uabeng.x86_64.rpm 
Loaded plugins: fs-snapshot, langpacks, presto, refresh-packagekit
Examining ../RPMS/x86_64/fwbuilder-5.1.0.3599-1.fc17.uabeng.x86_64.rpm: fwbuilder-5.1.0.3599-1.fc17.uabeng.x86_64
Marking ../RPMS/x86_64/fwbuilder-5.1.0.3599-1.fc17.uabeng.x86_64.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package fwbuilder.x86_64 0:5.1.0.3599-1.fc17.uabeng will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=====================================================================================================================
 Package         Arch         Version                         Repository                                        Size
=====================================================================================================================
Installing:
 fwbuilder       x86_64       5.1.0.3599-1.fc17.uabeng        /fwbuilder-5.1.0.3599-1.fc17.uabeng.x86_64        36 M

Transaction Summary
=====================================================================================================================
Install  1 Package
Hope this helps other FC17 FWbuilder users out there!

Friday, June 1, 2012

HowTo: Converting EXT4 to BTRFS in Fedora 17

This HowTo documents the steps I used on a Fedora 17 x86_64 test machine to convert the root file system from Ext4 to Btrfs.

Anaconda (Fedora installer) doesn't support the creation or manipulation of Btrfs file systems in the graphical installer. Support for this is slated for Fedora 18, at which time, Btrfs may become the default file system!

It is possible, however, to create Btrfs file systems at install time via Kickstart.

The virtual machine was installed with Fedora 17 x86_64 using default partitioning (LVM and Ext4) and selecting the Desktop profile.

If possible, create the partitions without LVM. (see section at the bottom for an example of this and UUID)

In the examples, the root file system is a logical volume: /dev/mapper/vg_f17vm-lv_root

Following the install and the initial boot, I rebooted using the Fedora 17 x86_64 Live CD and chose the option to Try Fedora.

I initially tried to perform the conversion using the Fedora 17 DVD and rescue mode, however the btrfs-convert utility isn't included. The live CD, however, includes the Btrfs utilities.

Convert EXT4 root

All of the steps are performed using the terminal, so open a Gnome Terminal and SU to root:
$ su -

Run fsck on the file system
# fsck.ext4 -f /dev/mapper/vg_f17vm-lv_root

Convert from ext4 to btrfs. The metadata stage can take a while on a large populated file system (on an 1.5TB ext4 file system with approx 500GB of data, a good mix of large and small files, this step took about 1.5 hours)
# btrfs-convert /dev/mapper/vg_f17vm-lv_root

creating btrfs metadata.
creating ext2fs image file.
cleaning up system chunk.
conversion complete.

Mount the freshly converted btrfs root file system so that we can make some modifications (fstab, SELinux)
# mkdir /mnt/btrfs
# mount -t btrfs /dev/mapper/vg_f17vm-lv_root /mnt/btrfs

Edit fstab to change the root file system from ext4 to btrfs
# vi /mnt/btrfs/etc/fstab

#/dev/mapper/vg_f17vm-lv_root              ext4   defaults    1 1
/dev/mapper/vg_f17vm-lv_root              btrfs   defaults    1 1

Force the system to automatically relabel the SELinux context for the root file system during boot.
# touch /mnt/btrfs/.autorelabel

NOTE: In my test, the Fedora 17 system would hang with systemd library permissions errors prior to getting to the SELinux auto relabel step.

To work around this, I rebooted back into the Live CD and change the SELinux policy to "permissive" from "enforcing". During the next boot, the permission errors went by and then the SELinux autorelabel ran to completion.
# vi /mnt/btrfs/etc/selinux/config

#SELINUX=enforcing
SELINUX=permissive

The Btrfs conversion process created a subvolume of the old ext4 file system. The following commands mount the subvolume and file system, demonstrating the power of Btrfs.
# mkdir /mnt/{ext2_saved,ext4}
# mount -t btrfs -o subvol=ext2_saved /dev/mapper/vg_f17vm-lv_root /mnt/ext2_saved
# mount -t ext4 -o loop,ro /mnt/ext2_saved/image /mnt/ext4

The contents of the ext4 and btrfs mounts should be identical, sans the changes made above to fstab and config.

It's possible to roll back the conversion by first unmounting the file systems and then rolling it back using the -r switch
# umount /dev/mapper/vg_f17vm-lv_root
# btrfs-convert -r /dev/mapper/vg_f17vm-lv_root

If you decide to stay with btrfs, you can delete the subvolume snapshot of the original ext4 system
# btrfs subvolume delete /mnt/btrfs/ext2_saved

Reboot into the installed OS and the system should perform the relabel and then come up with your shiny new btrfs file system.

To make things really cool, install the yum-plugin-fs-snapshot Yum plugin. This plugin will create a btrfs subvolume of your root file system prior to installing updates. The end result, you can roll back from yum updates. Test that you can mount the snapshot of the ext4 file system

Once the system is up and running, don't forget to set the SELinux policy back to "enforcing"

Issues:
  1. It appears that some of the systemd services attempt to start prior to the SELinux .autorelabel step. This results in permission errors that prevent the system from booting. Temporarily change the SELinux policy to "permissive" to work past this.
  2. During boot, you may see errors logged by the systemd-fsck service failing for lv_root due to missing fsck.btrfs. I suspect that the btrfs-progs rpm failed to create a symlink of fsck.btrf pointing to /usr/sbin/btrfsck
systemd-fsck[858]: fsck: fsck.btrfs: not found
systemd-fsck[858]: fsck: error 2 while executing fsck.btrfs for /dev/mapper/vg_f17vm-lv_root

Convert Luks Encrypted EXT4 home

If your file system is encrypted with Luks, you'll have the additional step of decrypting the file system prior to running the conversion
# cryptsetup luksOpen /dev/mapper/vg_f17vm-lv_home luks_home
# fsck.ext4 -f /dev/mapper/luks_home
# btrfs-convert /dev/mapper/luks_home

creating btrfs metadata.
creating ext2fs image file.
cleaning up system chunk.
conversion complete.

Converting Non LVM Ext4 and UUID in /etc/fstab

If you don't use LVM (recommended based on everything I've ready, since it's not needed for btrfs), your /etc/fstab may mount the partitions using the UUID. After converting the file system to btrfs, the UUID will change.

These steps demonstrate how to convert the root file syste, a non LVM ext4 partition, /dev/sda2.
# fsck.ext4 -f /dev/sda2
# btrfs-convert /dev/sda2

creating btrfs metadata.
creating ext2fs image file.
cleaning up system chunk.
conversion complete.
Identify the UUID using blkid (can also look under /dev/disk/by-uuid
# blkid /dev/sda2

/dev/sda2: UUID="56d1e02b-3120-44c3-b8f8-d3289012e447" UUID_SUB="13f7b26b-42b1-41bb-a9dc-c928ad033f6d" TYPE="btrfs" 


# mkdir /mnt/btrfs
# mount -t btrfs /dev/sda2 /mnt/btrfs


Edit fstab to change the root file system from ext4 to btrfs and replace the UUID with the new UUID
# vi /mnt/btrfs/etc/fstab

#UUID=e14bd8d6-ac8a-4f15-8169-f0a9bdf4b69e /                       ext4    defaults        1 1
UUID=56d1e02b-3120-44c3-b8f8-d3289012e447 /                       btrfs    defaults        1 1
UUID=f4cdf95d-66eb-4428-960d-23b289ffb63e /boot                   ext4    defaults        1 2

Chroot to the real root file system and update grub.cfg using grub2-mkconfig

# mount -o bind /dev /mnt/btrfs/dev
# mount -o bind /proc /mnt/btrfs/proc
# mount -o bind /sys /mnt/btrfs/sys
# mount /dev/sda1 /mnt/btrfs/boot

# chroot /mnt/btrfs

# grub2-mkconfig -o /boot/grub2/grub.cfg 

Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.4.3-1.fc17.x86_64
Found initrd image: /boot/initramfs-3.4.3-1.fc17.x86_64.img
Found linux image: /boot/vmlinuz-3.3.4-5.fc17.x86_64
Found initrd image: /boot/initramfs-3.3.4-5.fc17.x86_64.img
Warning: Please don't use old title `Fedora Linux, with Linux 3.3.4-5.fc17.x86_64' for GRUB_DEFAULT, use `Advanced options for Fedora Linux>Fedora Linux, with Linux 3.3.4-5.fc17.x86_64' (for versions before 2.00) or `gnulinux-advanced-/dev/sda2>gnulinux-3.3.4-5.fc17.x86_64-advanced-/dev/sda2' (for 2.00 or later)
done
Exit out of the chroot and unmount the file systems
# exit
# umount /mnt/btrfs/boot
# umount /mnt/btrfs/dev
# umount /mnt/btrfs/proc
# umount /mnt/btrfs/sys
# umount /mnt/btrfs


Reboot and you should be good to go. The selinux relabeling can take a while!

References: