josh
josh

Reputation: 1554

Python causing: IOError: [Errno 28] No space left on device: '../results/32766.html' on disk with lots of space

I am running a Python script that is causing the above error. The unusual thing is this script is running on a different machine and is having no problems.

The difference is that on the machine that is causing the problems I am writing to an external hard drive. To make things even weirder this script has run on the problem machine and already written over 30,000 files.

Some relevant information (The code that is causing the error):

nPage = 0
while nPage != -1:
    for d in data:
        if len(d.contents) > 1:
            if '<script' in str(d.contents):
                l = str(d.contents[1])
                start = l.find('http://')
                end = l.find('>',start)
                out = get_records.openURL(l[start:end])
                print COUNT

                with open('../results/'+str(COUNT)+'.html','w') as f:
                    f.write(out)
                COUNT += 1

    nPage = nextPage(mOut,False)

The directory I'm writing to:

10:32@lorax:~/econ/estc/bin$ ll ../
total 56
drwxr-xr-x 3 boincuser boincuser  4096 2011-07-31 14:29 ./
drwxr-xr-x 3 boincuser boincuser  4096 2011-07-31 14:20 ../
drwxr-xr-x 2 boincuser boincuser  4096 2011-08-09 10:38 bin/
lrwxrwxrwx 1 boincuser boincuser    47 2011-07-31 14:21 results -> /media/cavalry/server_backup/econ/estc/results//
-rw-r--r-- 1 boincuser boincuser 44759 2011-08-09 10:32 test.html

Proof there is enough space:

10:38@lorax:~/econ/estc/bin$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda1             9.0G  5.3G  3.3G  63% /
none                  495M  348K  495M   1% /dev
none                  500M  164K  500M   1% /dev/shm
none                  500M  340K  500M   1% /var/run
none                  500M     0  500M   0% /var/lock
none                  9.0G  5.3G  3.3G  63% /var/lib/ureadahead/debugfs
/dev/sdc10            466G  223G  244G  48% /media/cavalry

Some things I have tried:

Upvotes: 57

Views: 254204

Answers (10)

Minimal reproducible error example with too many files in a single directory

The approximate maximum number of files per directory for different filesystems can be seen at: How many files can I put in a directory?

The following example eventually blows up giving us a concrete estimate to the size limit:

#!/usr/bin/env python

import os
import shutil

tmpdir = 'tmp'
if os.path.isdir(tmpdir):
    shutil.rmtree(tmpdir)
os.mkdir(tmpdir)
for i in range(10000000):
    print(i)
    with open(os.path.join(tmpdir, f'{i:064}'), 'w') as f:
        pass

and always blows up on my test system at:

5590508
Traceback (most recent call last):
  File "/home/ciro/test/tmp/./main.py", line 12, in <module>
    with open(os.path.join(tmpdir, f'{i:064}'), 'w') as f:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 28] No space left on device: 'tmp/0000000000000000000000000000000000000000000000000000000005590508'

so near 5.6M files.

But also note that the length of files names in the directory matters a lot. If you reduced them down from 64 bytes e.g. with:

    with open(os.path.join(tmpdir, f'{i}'), 'w') as f:

you would then be able to store way more files in the directory, that went up to 20M files and then I lost patience. So you can't just easily put a single specific value to it. I first came across this issue exactly when storing a large number of file with large basenames because the basenames were Bitcoin transaction IDs which have 64 hex bytes each.

Tested on Python 3.11.6, Ubuntu 23.10, Linux kernel 6.5.0 on an ext4 filesystem with:

df -hT

containing:

Filesystem                        Type      Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv ext4      1.9T  1.5T  246G  87% /

and:

sudo file -L -s /dev/mapper/ubuntu--vg-ubuntu--lv ext4

giving:

sudo dumpe2fs /dev/mapper/ubuntu--vg-ubuntu--lv | grep 'Filesystem features'
dumpe2fs 1.47.0 (5-Feb-2023)

giving:

Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum

so no large_dir.

Note that the total size of the file names themselves in the above example is 64 B * 10000000 = 640 MB, so there was more than enough space in the disk for them.

All of this just makes part of me just want to use one big indexed SQLite file everywhere. 5 million is a small enough number for a modern computer!

The underlying system call is open itself which can create a file, as opposed to write which writes data to a file, and would instead blow up if you ran out of total space. man 2 open documents:

ERRORS

ENOSPC pathname was to be created but the device containing pathname has no room for the new file.

and we can confirm that the cryptic "28" is ENOSPC by running as per https://unix.stackexchange.com/questions/326766/what-are-the-standard-error-codes-in-linux

errno -ls

which contains:

ENOSPC 28 No space left on device

On the Linux kernel it is at: https://github.com/torvalds/linux/blob/a4145ce1e7bc247fd6f2846e8699473448717b37/include/uapi/asm-generic/errno-base.h#L32

Upvotes: 1

xxrlgame
xxrlgame

Reputation: 1

I have the same problem, but found the root cause is "print too frequently" at last. On my code I have some "print(...)" logic which running in loop. When I comment those code, the "No space left on device" error disappeared. Perhaps it is a Python implementation problem. You may try this solution.

For more detail, sample descriptive code will look like following:

loop:
    do some logic 
    call "print" to check result

When your logic code running very fast, you will call "print" very frequently. Then sometimes "[Errno 28] No space left on device" error will appear.

I think this is an implementation limitation of Python "print" code, though I not read the code yet. My Python version is 3.9.7

Thanks for Community reply.

Upvotes: 0

Evgeny Urubkov
Evgeny Urubkov

Reputation: 151

I ran into this problem when running tests. The Django app I was running was inside a docker container, so I had to log in to the container as a root, run rm -r /tmp/ and it fixed the issue.

Upvotes: 0

shanky
shanky

Reputation: 403

Try to delete the temp files

rm -r /tmp/

Upvotes: 24

Hossein A
Hossein A

Reputation: 1260

I faced a similar issue. The above solutions for deleting the /tmp directory worked for me.

Instead of using the default /tmp location where the service account might not have full access (if following best practices and not using sudo to install Python packages), I moved the /tmp directory to the user's home directory, with TMPDIR environment setting honored by pip install --user ... command.

I faced the issue above of running out space, as mentioned in the answeres above most likely due to so many files/directories being created and not actually running out of volume storage. The solution that worked for me was to delete the /home/<some_domain>/$USER/tmp directory and recreate it every time my continuous deployment pipeline ran. rm -rf /tmp

Upvotes: 0

Colonel_Old
Colonel_Old

Reputation: 932

  1. Show where memory is allocated sudo du -x -h / | sort -h | tail -40
  2. Delete from either your /tmp or /home/user_name/.cache folder if these are taking up a lot of memory. You can do this by running sudo rm -R /path/to/folder

Step 2 outlines fairly common folders to delete from (/tmp and /home/user_name/.cache). If you get back other results when running the first command showing you have lots of memory being used elsewhere, I advise being a bit more cautious when deleting from those locations.

Upvotes: 8

Chandan
Chandan

Reputation: 49

run "export TEMPDIR=/someDir" where some dir is a valid directory other than /tmp. Run this on prompt before running your python command. In my case it is "pip install rasa[spacy]" which was earlier failing.

The export command allows you to temporarily use the specified dir as temp dir.

Upvotes: 4

ARKhan
ARKhan

Reputation: 1975

In my case, when I run df -i it shows me that my number of inodes are full and then I have to delete some of the small files or folder. Otherwise it will not allow us to create files or folders once inodes get full.

All you have to do is delete files or folder that has not taken up full space but is responsible for filling inodes.

Upvotes: 5

josh
josh

Reputation: 1554

It turns out the best solution for me here was to just reformat the drive. Once reformatted all these problems were no longer problems.

Upvotes: 10

Rosh Oxymoron
Rosh Oxymoron

Reputation: 21055

The ENOSPC ("No space left on device") error will be triggered in any situation in which the data or the metadata associated with an I/O operation can't be written down anywhere because of lack of space. This doesn't always mean disk space – it could mean physical disk space, logical space (e.g. maximum file length), space in a certain data structure or address space. For example you can get it if there isn't space in the directory table (vfat) or there aren't any inodes left. It roughly means “I can't find where to write this down”.

Particularly in Python, this can happen on any write I/O operation. It can happen during f.write, but it can also happen on open, on f.flush and even on f.close. Where it happened provides a vital clue for the reason that it did – if it happened on open there wasn't enough space to write the metadata for the entry, if it happened during f.write, f.flush or f.close there wasn't enough disk space left or you've exceeded the maximum file size.

If the filesystem in the given directory is vfat you'd hit the maximum file limit at about the same time that you did. The limit is supposed to be 2^16 directory entries, but if I recall correctly some other factors can affect it (e.g. some files require more than one entry).

It would be best to avoid creating so many files in a directory. Few filesystems handle so many directory entries with ease. Unless you're certain that your filesystem deals well with many files in a directory, you can consider another strategy (e.g. create more directories).

P.S. Also do not trust the remaining disk space – some file systems reserve some space for root and others miscalculate the free space and give you a number that just isn't true.

Upvotes: 72

Related Questions