9

I was doing dpkg --configure -a in my Debian wheezy. And got this error:

dpkg --configure -a
dpkg: failed to write status record about `libcairo2' to `/var/lib/dpkg/status': No space left on device

I am chrooted into a .img file. What can I do?

JohnnyBoy
  • 159
  • What do you mean by "chrooted into a .img file"? – Stephen Kitt Jul 19 '15 at 15:13
  • 1
    please include the output of df -h command and yes what @StephenKitt asked too! – Munai Das Udasin Jul 19 '15 at 15:14
  • @MunaiDasUdasin Thank you for responding. Df -h gets me / is 100% of it used. StephenKitt I have an image that I usr to chroot into. I mean, with losetup i mounted it and chrooted into it. Thank you both im trying the answer beneath atm though – JohnnyBoy Jul 19 '15 at 19:41
  • Btw @JohnnyBoy there's a convenient shortcut mount -oloop file /path that does the losetup bit for you automatically. – sourcejedi Jul 20 '15 at 20:24

2 Answers2

7

If the chroot filesystem is full, you can enlarge the image file.

E.g. using dd conv=notrunc oflag=append bs=1M count=X of=file.img. Be very, very careful :). It is strongly recommended to unmount the chroot and backup the .img file first, if you can.

Then resize the filesystem, so it can use the extra space. For an ext4 filesystem the command would be resize2fs. The manpage suggests you'll have to run that last command on a loop device, not the file:

# losetup -f file.img
# losetup -l
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0         0      0         0  0 /home/alan/file.img
# resize2fs /dev/loop0
...
# losetup -d /dev/loop0

Command will be different for different filesystems, e.g. btrfs filesystem resize /dev/loop0 max, or xfs_growfs /test.img/is/mounted/here.

sourcejedi
  • 50,249
  • Hey thanks for the answer. I get "invalid conversion append" after the dd command and I resize2fs says the "filesystem is already 183105 (4k) bytes long. Nothing to do! " – JohnnyBoy Jul 19 '15 at 20:26
  • 1
    @JohnnyBoy Don't bother with dd, it's hard to use and harder to use reliably. Just use something like truncate -s 10G foo.img where 10G is the new size you want for the image (larger than the current size!). Do that with the image unmounted. Then resize the filesystem. – Gilles 'SO- stop being evil' Jul 19 '15 at 21:50
  • Sorry, fixed. truncate works too, and there is a difference in the result w.r.t possible performance (commented on the other answer). – sourcejedi Jul 20 '15 at 20:22
  • I got this error: resize2fs: Bad magic number in super-block while trying to open /dev/loop6 Couldn't find valid filesystem superblock. – Felipe Oct 05 '21 at 06:32
  • @Felipe Maybe the dd command you used was wrong, and it won't mount anymore? If it does mount, are you sure it's an ext4 filesystem? What does blkid or file / file -s think about it? – sourcejedi Oct 05 '21 at 20:13
  • It was a qcow2 image (instead raw), that's why it didn't work. I was able to expand following this tutorial: https://www.cyberithub.com/resize-qcow2-image-with-virt-resize-kvm-tools/ – Felipe Oct 06 '21 at 20:40
5

To do this correctly you need to:

  1. First expand the .img file.
  2. Next expand the filesystem within.

The best way to do the first thing is with dd. For whatever reason some people attribute a kind of mystery to the way dd works, but there really is none. For example, to append a hole to the end of your .img file:

dd bs=1kx1k seek=100 of=.img </dev/null

On any POSIX system that will truncate the file to 100MiBs. On a GNU system the 1kx1k bit can be shortened to just M. dd seeks 100MiBs into the file, encounters EOF on its first read, and closes the file. It is a single action, and requires no reads (beyond the first empty one) or writes - it's very nearly atomic.

If the file was 50MiBs before, it will now be allocated 50MiBs more. If the file was 150MiBs before, that will chop the last 50MiBs off the tail. On a filesystem which understands sparse files, the appended file hole will use no disk-space, really, and will only use what is necessary as you fill it.

Other ways to do the same on some systems:

fallocate -l100M .img
truncate -s100M .img

...both of those commands will do the exact same thing dd will. I recommend dd because neither of those tools is portable where dd's behavior is POSIX-spec'd, and once you learn how to use the disk-destroyer properly, no disk will ever again dare to stand in your way.

If you are merely adding to your .img you can do the above thing whether or not it is mounted (though if you were to take some of a mounted .img away it may not work as expected), but you will very likely need to umount.img first to resize its constituent filesystem anyway, and so might as well. You do not need to -destroy the loop device, though.

How you handle the second thing depends on whether .img is partitioned or not. If it is not, as I guess is the case based on your comments elsewhere, then you'll only need to address the fs by its type. For an ext[234] .img file you should use resize2fs and be done with it. For others you'll want to look at the relevant user-space tools and their man pages.

If .img is partitioned it can be more complicated. In such cases how you handle the situation will depend on what kind of partition table is used (such as GPT vs MBR vs hybrid-MBR), whether it is the last partition in the file's partition table and much else. I hesitate to venture any specifics here without more information: if you require advice on how to handle a partitioned .img please let me know with some more details and I will offer what I can.

mikeserv
  • 58,310
  • Thanks a lot. However dd bs=1M count=500 >> .img works too. Just saying. Great answer – JohnnyBoy Jul 20 '15 at 10:02
  • @Johnnyboy - Ok... but what is the input there? – mikeserv Jul 20 '15 at 10:09
  • @JohnnyBoy - and anyway, while it will work, you actually will have to copy something in that case. That means you need to 500 reads/writes. If you just seek, though, you only have to do 1. – mikeserv Jul 20 '15 at 10:31
  • Both are useful. The seek / truncate method creates a "sparse file", where the space is not allocated until content is written to it. The result may become more fragmented on-disk as a result. – sourcejedi Jul 20 '15 at 20:17
  • Nice, I see the seek method doesn't require conv=notrunc (but there's still the possibility to botch it if you get the size too small, in the same way as truncate). The manpage says dd sets the size it truncates to to the value of the seek argument. – sourcejedi Jul 20 '15 at 20:21
  • @sourcejedi - yes, kind of. seek=n Skip n blocks (using the specified output block size)* from the beginning of the output file before copying. On non-seekable files, existing blocks shall be read and space from the current end-of-file to the specified offset, if any, filled with null bytes; on seekable files, the implementation shall seek to the specified offset or read the blocks as described for non-seekable files.* So the of output-file is set to at least the size of $((seek*obs)). – mikeserv Jul 20 '15 at 21:59
  • 1
    @sourcejedi - it is fun, too. seq 20 >nums; seq 20 | (</dev/null dd bs=20 seek=1; cat) 1<>nums; cat nums - try it. You can achieve the same purpose with <> as you might with conv=notrunc. Some other dd stuff: a dd ring-buffer and a hidden partition. – mikeserv Jul 20 '15 at 22:06
  • Wow, great explanation! – Bill Burdick Sep 29 '19 at 16:09