Results 1 to 10 of 45

Thread: HOWTO: Use swapfile instead of partition and hibernate

Threaded View

  1. #1
    Join Date
    Apr 2006
    Location
    Silicon Valley
    Beans
    19

    Post HOWTO: Use swapfile instead of swap partition and have working hibernation

    This HOWTO explains how to use swapfile and still have hibernation working.

    (For advanced console users / cmdline junkies - you may find compressed list of commands at the end of this HOWTO)

    Why would you want a swapfile? Isn't the traditional swap partition working fine?
    Swap partition does work fine, but there are 3 cases when you may want a swapfile instead:
    1. You forgot to make a swap partition
    2. You need to have no swap partition, for instance to have Mac trippleboot Ubuntu/MacOSX/Win* and comply with all of the OS's limitations (which in my case allowed only 4 primary MBR partitions, one taken by GUID/GPT/EFI which makes MacOSX comfortable)
    3. Have flexibility of resizing swap at any time. Partition may be impossible to change/resize later.


    This HOWTO was tested only on Intrepid, but may work on other versions.
    UPDATE 7 Sept 2011: I tested it with Ubuntu 10.04 LTS (Lucid Lynx) and made appropriate edits.
    To reverse back to swap partition: http://ubuntuforums.org/showpost.php...0&postcount=13

    DISCLAIMER: Messing up with disk partitions may make your system unusable, cause loss of data, loss of hair and/or sleep. Knowledge of terminal and command line is required. You're warned - proceed at your own risk.

    PREREQUISITES
    • Ubuntu installed on disk drive and running
    • IMPORTANT! Hibernation and resume should already work OK before this change
    • Enough free space on "/" partition
    • You should have your sudo password and be on the sudoers list


    PART 1 - SWAPFILE

    Attention: If you have swap partition and hibernation does not work, STOP HERE. First fix hibernation (seek help elsewhere, try "sudo apt-get install hibernation") before proceeding.

    Note: Using swapfile breaks hibernation. We will fix it in PART 2 below.

    Boot into your system (reboot is recommended to close all extra applications). Open terminal. Copy & paste one command at a time (making necessary edits as denoted by "<...>").

    Code:
    cat /proc/meminfo
    Note memory size (first line saying "MemTotal"). Graphics card may eat a chunk out of the main RAM, so it is not necessarily a multiple of GiB.

    For RAM of size N Bytes we will need a swapfile size of N to 2*N Bytes for both virtual memory and hibernation to work properly. Having swap larger than 2*N Bytes is usually unnecessary and just wastes space, unless you are planning to upgrade RAM in the near future. You can rerun this HOWTO prior to RAM upgrade, or allocate enough swap space now.

    Code:
    sudo dd if=/dev/zero of=/swapfile bs=1024 count=XX
    The swapfile size is equal to [count*bs] (in Bytes), So XX = desired swap size in Bytes / 1024 (bs parameter implies Bytes).

    dd can take standard multiplier letters, e.g. count=2M or count=2048K will both result in 1024*2M=2G (note that count parameter has special decoding of multipliers - adding letter B changes from computer 1024 to metric 1000, i.e 1M = 1024*1024, while 1MB=1000*1000). You can dry-run dd with of=/dev/null to see if your numbers will get the desired swapfile size. See "man dd" if you need more information.

    You can go ahead and check stock quotes while dd creates the new file for a few minutes.

    Code:
    sudo chmod 600 /swapfile && sudo mkswap /swapfile
    Important Note: The UUID that mkswap returns is absolutely useless.

    Code:
    sudo swapoff -a
    sudo swapon /swapfile
    sudo -b gedit /etc/fstab
    Edit /etc/fstab and :
    1. Remove or comment out ALL old swap partitions
    2. Add new line:

    Code:
    /swapfile   none   swap   sw   0   0
    Verify that everything is done OK:
    Code:
    free -m
    You will see your swap reported.
    Code:
    swapon -s
    - will show you that you are indeed using swapfile


    PART 2 - HIBERNATION

    Now we will make the hibernation work again. Intrepid kernel has all the provisions (thanks to Rafael J. Wysocki), but surrounding files do not tell it how to use the swapfile. Even more:
    1. Reinstall or update of initramf-tools won't make the right setup, though it should (maybe it will someday)
    2. Hibernate does not work with swapfiles out of the box and will exhibit behavior similar to this bug: [Ubuntu bug 313724, Red Hat bug 466408] "PM: Swap header not found!

    So we do it by hand:

    Code:
    mount | grep " / "
    Note your /dev/... for "/" disk.
    Code:
    sudo blkid -g
    sudo blkid
    Note UUID of /dev/... that corresponds to "/", we will use it in resume=UUID= below.

    Code:
    sudo filefrag -v /swapfile | grep "First block:"
    Note first block, we will use it for resume_offset below.
    If there is no output from this command, you have a new filefrag which changed its output. Do this instead:
    Code:
    sudo filefrag -v /swapfile
    ...and note the number in the first line under "physical" (3rd column)
    Here is an example of the output, the number for resume_offset is 154484:
    Code:
    Filesystem type is: 58465342
    File size of /swapfile is 8261935104 (2017074 blocks, blocksize 4096)
     ext logical physical expected length flags
       0       0   154484          1241648 
       1 1241648  6233816  1396131 775426 eof
    /swapfile: 2 extents found
    Replace UUID and resume_offset:
    Code:
    echo "resume=UUID=<your UUID> resume_offset=<youroffset>" | sudo tee /etc/initramfs-tools/conf.d/resume
    Now edit GRUB configuration:
    (for old grub, before grub2)
    Code:
    sudo -b gedit /boot/grub/menu.lst
    Find the line "# kopt=root=UUID=..."
    and add to it "resume=UUID=<your UUID> resume_offset=<youroffset>" (without quotes).
    Note that your UUID will match root=UUID, unless you have placed swapfile on different partition than "/".

    It should look like this (with your UUID and offset):
    Code:
    # kopt=root=UUID=... ro resume=UUID=cd71de6f-907a-40d7-bf26-c17f201e5718 resume_offset=66050
    Make sure you have no carriage returns in this line.

    (for new grub2)
    Code:
    sudo -b gedit /etc/default/grub
    Find the line "GRUB_CMDLINE_LINUX_DEFAULT=..."
    and add to it "resume=UUID=<your UUID> resume_offset=<youroffset>" (so it stays inside quotes with whatether text was there).
    Note that your UUID will match root=UUID in /boot/grub/grub.cfg, unless you have placed swapfile on different partition than "/".

    Now let's run the tools to make them work:

    For pre-grub2:
    Code:
    sudo update-grub -y
    For grub2:
    Code:
    sudo update-grub
    Answer "instal the package maintainer's version" if it asks.

    Code:
    sudo update-initramfs -u
    Verify that all your kernel stanzas (menu entries) got updated in /boot/grub/menu.lst (or in /boot/grub/grub.cfg for grub2) with resume=... and resume_offset=..., if not - verify your # kopt= line - it should have # and space (GRUB_CMDLINE_LINUX_DEFAULT= line for grub2 should have quotes). Rerun update-grub if necessary. It may keep your old file if you chose wrong answer above.

    Now reboot before trying to hibernate (important), so kernel gets the right resume_offset parameter.

    After reboot, try to hibernate. It should get right back to this window after you power your computer back up.

    Now you can get rid of the old swap partition and use it for other stuff.


    CONCLUSION

    This is a quick command summary:
    Part 1 - make swap file
    Code:
    cat /proc/meminfo
    ## Note memory size. Graphics card may eat a chunk of main RAM
    ## We will need swapfile the size of N to 2*N of RAM
    sudo swapoff -a
    sudo dd if=/dev/zero of=/swapfile bs=1024 count=8M	;## 2*N of RAM, swap size=count*bs
    sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile
    sudo -b gedit /etc/fstab
    # Remove ALL old swap partitions
    # Add: /swapfile   none   swap   sw   0   0
    free -m
    swapon -s
    Part 2 - use swap file for hibernation
    Code:
    mount | grep " / "    ;# Note your /dev/... on /
    sudo blkid -g
    sudo blkid    ;## get / -> /dev/... -> partition UUID -> resume=UUID=
    sudo filefrag -v /swapfile | grep "First block:"	;## get First block -> resume_offset
    # for grub2:
    sudo filefrag -v /swapfile	;## get first "physical" number -> resume_offset
    echo "resume=UUID=cdXX--X18 resume_offset=66050" | sudo tee /etc/initramfs-tools/conf.d/resume
    sudo -b gedit /boot/grub/menu.lst
    # kopt=root=UUID=... ro resume=UUID=cdXX--X18 resume_offset=66050 
    # for grub2:
    sudo -b gedit /etc/default/grub
    GRUB_CMDLINE_LINUX_DEFAULT="... resume=UUID=cdXX--X18 resume_offset=66050"
    sudo update-grub -y
    # Answer "use maintainer version" if it asks
    sudo update-initramfs -u

    APPENDIX - SAME OR SEPARATE FILES FOR SWAP AND HIBERNATION?

    There is some controversy going on in regards to using the same file or partition for both swap and hibernation. If swapfile is not big enough, hibernation may fail, depending on how many applications and documents are open. Some argue rightfully for 2 separate files - one for swap, one for hibernation.

    Swapfile approach should make it very easy to have 2 separate files and avoid problems. Given RAM size of N Bytes the above instructions could be used as follows to create two files:
    1. /swapfile of size N Bytes for "swapon /swapfile" only.
    2. /hiberfile of size N Bytes for PART2 - HIBERNATION (use instructions in PART1 to create it, but don't add it to fstab or swapon)

    Unfortunately, when done this way, hibernation fails with kernel message "PM: Cannot find swap device, try swapon -a". It looks like a deficiency of PM code in current kernel. So the answer is no, not yet. For now use single file that is big enough and hope you never run out of space in it and get failing hibernation.
    Last edited by iva2k; September 11th, 2011 at 06:20 AM. Reason: Added notes for grub2 and latest filefrag

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •