Reputation: 1554
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
Reputation: 382822
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
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
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
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
Reputation: 932
sudo du -x -h / | sort -h | tail -40
/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
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
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
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
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