4

I'm able to auto detect RAM in GB as below and round off to the nearest integer:

printf "%.f\n" $(grep MemTotal /proc/meminfo | awk '$3=="kB"{$2=$2/1024^2;$3="GB";} 1' | awk '{print $2}')

Output:

4

I multiply by 2 to determine the required swap as 8GB

ans=`expr $(printf "%.f\n" $(grep MemTotal /proc/meminfo | awk '$3=="kB"{$2=$2/1024^2;$3="GB";} 1' | awk '{print $2}')) \* 2`
echo "$ans"G

Output:

8G

With the below commands I try to create 8GB swap memory.

echo "Creating $ans GB swap memory"
sudo dd if=/dev/zero of=/swapfile bs="$ans"G count=1048576

sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile sudo swapon --show

However, I get the below error:

Creating 8 GB swap memory
dd: memory exhausted by input buffer of size 8589934592 bytes (8.0 GiB)
mkswap: error: swap area needs to be at least 40 KiB
swapon: /swapfile: read swap header failed.

Can you please suggest and help me auto-create swap memory which Ideally should be double of that of the RAM.

System details:

root@DKERP:~# uname -a
Linux DKERP 5.4.0-124-generic #140-Ubuntu SMP Thu Aug 4 02:23:37 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
root@DKERP:~# free -g -h -t
              total        used        free      shared  buff/cache   available
Mem:          3.8Gi       1.0Gi       207Mi        54Mi       2.6Gi       2.5Gi
Swap:            0B          0B          0B
Total:        3.8Gi       1.0Gi       207Mi
Ashar
  • 491
  • 6
    The advice to have 2x swap size was for 2 decades ago and was obsolete long ago, just don't do that and use zram instead – phuclv Sep 04 '22 at 12:32
  • 2
    swap size > RAM is still useful on systems that will be suspended to disk - e.g. laptops. A machine can't suspend if there's nowhere to store the RAM contents, and Linux uses swap space for that. – cas Sep 05 '22 at 00:52
  • Use bs=1M and set count to the number of megabytes you want the swapfile to be – abligh Sep 05 '22 at 06:27

3 Answers3

11

The reason why your dd command didn't work is because you set dd's block size to 8 GB. i.e. you told it to read and write 8 GiB at a time, which would require a RAM buffer of 8 GB. As Marcus said, 8 GiB is more RAM than you have, so a buffer of that size isn't going to work.

And ~ 8 billion megabytes (8 GiB x 1M = 8 petabytes, 9,007,199,254,740,992 bytes) is way more disk space than you have too....it's way more than most high-end storage clusters in the world would have.

It would work if you used reasonable values for both bs and count. For example, 1 MiB x 8K = 8 GiB:

dd if=/dev/zero of=/swapfile bs=1048576 count=8192

or

dd if=/dev/zero of=/swapfile bs=1M count=8K
cas
  • 78,579
  • Surprised if this works. Quoting swapon(8): "truncate(1) create files with holes. These files will be rejected by swapon." I normally use fallocate instead. However: "files created by fallocate(1) may be interpreted as files with holes too depending of the filesystem." Not sure what FSes that's referring to, but it's at least not a problem with ext4. – JoL Sep 05 '22 at 00:26
  • I'm fairly sure I've use truncate for swap files (and for VM image files) in the past, and it worked. On the rare occasion I need them, I use ZFS ZVOLs now. Using dd with reasonable parameters definitely works, so I'll just edit out the truncate stuff. – cas Sep 05 '22 at 00:32
  • @JoL It is a problem for ext4, but it's mitigated if, for whatever reason, the filesystem is already on a loopback device (e.g. if you're using LVM or LUKS). The reason is that swapon will directly map the blocks as swap, completely bypassing the filesystem, so all the blocks must exist (this is what holes interferes with). If you're using a loopback device, then any access will necessarily not be "direct". – forest Sep 06 '22 at 22:43
5

You're explicitly instructing dd to read a block of twice the RAM size into RAM. That cannot succeed.

Instead, simply ... not do that.

  • Thus far, i have been manually creating swap by the same approach where I used to give dd bs=<twice the memory as that of the RAM. I roughly remember that swap can be twice that of RAM. Can you suggest how can I get optimal swap memory created automatically? @Marcus-Müller – Ashar Sep 04 '22 at 11:35
  • 4
    You are telling dd to read 1 billion blocks, where each block is 8 GB in size. That a) requires dd to have 8 GB of RAM available so that it can buffer at least one block, and b) will result in a swapfile of 8 petabytes, which means you need to have 8 petabytes of free disk space. As this answer says, just don't do that, and it will work. – Jörg W Mittag Sep 04 '22 at 22:04
  • @Ashar it is important to realize two things, the size of the file you will create is BS * COUNT. The second is that even though /dev/zero is fictional, dd does not know that, and it will read at least a BS of it into memory. keep BS at 1M and modify count to the number of gigs * 1024. – toppk Sep 05 '22 at 18:01
2

Don't bother with dd and manually setting block sizes. They don't matter for correctness in most cases, at least not on Linux with regular files or block devices. Use something more user-friendly instead.

You usual Linux installations, you probably have the GNU coreutils versions of the standard tools. If so, you can just use e.g.

gigs=8
head -c "${gigs}G" /dev/zero > /swapfile

to create that 8-gig zero-filled file.

If you don't have the GNU tools, many versions of head support the -c option with a bare number, so e.g.

gigs=8
head -c $((gigs * 1024 * 1024 * 1024)) /dev/zero > /swapfile
ilkkachu
  • 138,973