Understanding XFS Inodes: A Deep Dive into Filesystem Management
Learn how to effectively manage and monitor XFS filesystem inodes to prevent exhaustion and maintain optimal system performance.
Understanding XFS Inodes
What are Inodes?
Inodes are fundamental filesystem structures that:
- Store metadata about files
- Track file permissions
- Maintain file locations
- Handle file attributes
- Manage file links
XFS Inode Management
1. Checking Inode Usage
# View filesystem information
df -i
# Detailed XFS information
xfs_info /mount/point
# Find directories with most inodes
find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n
2. Monitoring Tools
#!/bin/bash
# monitor-inodes.sh
check_inodes() {
local mount_point=$1
local threshold=90
# Get inode usage percentage
usage=$(df -i $mount_point | tail -1 | awk '{print $5}' | sed 's/%//')
if [ $usage -gt $threshold ]; then
echo "Warning: Inode usage on $mount_point is at ${usage}%"
# Find top inode-using directories
echo "Top inode-consuming directories:"
find $mount_point -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n | tail -5
fi
}
# Check all XFS filesystems
for fs in $(df -t xfs | tail -n+2 | awk '{print $6}'); do
check_inodes $fs
done
Preventing Inode Exhaustion
1. Filesystem Creation
# Create XFS with custom inode size
mkfs.xfs -i size=512 /dev/sda1
# Specify inode ratio
mkfs.xfs -i maxpct=25 /dev/sda1
2. Runtime Management
# Monitor file creation patterns
#!/bin/bash
# track-file-creation.sh
log_file_creation() {
local dir=$1
inotifywait -m -r $dir -e create |
while read path action file; do
echo "$(date): New file created - $path$file"
current_inodes=$(df -i $dir | tail -1 | awk '{print $3}')
echo "Current inode usage: $current_inodes"
done
}
# Start monitoring
log_file_creation /path/to/monitor
Performance Optimization
1. Inode Allocation
# Optimize inode allocation
xfs_io -c "extsize=64k" /mount/point
# Set project quota for inode limits
xfs_quota -x -c 'project -s myproject' /mount/point
2. Directory Indexing
# Enable directory indexing
xfs_io -c "chattr +i" /path/to/directory
# Check directory attributes
xfs_io -c "lsattr" /path/to/directory
Maintenance and Recovery
1. Filesystem Check
# Check XFS filesystem
xfs_repair -n /dev/sda1
# Force check and repair
xfs_repair /dev/sda1
2. Backup and Restore
# Backup XFS metadata
xfs_metadump /dev/sda1 metadata.img
# Restore from backup
xfs_mdrestore metadata.img /dev/sda1
Monitoring Scripts
1. Automated Inode Monitoring
#!/usr/bin/env python3
# inode_monitor.py
import os
import subprocess
import time
def get_inode_usage(mount_point):
df = subprocess.check_output(['df', '-i', mount_point]).decode()
usage = df.split('\n')[1].split()[4].rstrip('%')
return int(usage)
def alert_high_usage(mount_point, threshold=90):
usage = get_inode_usage(mount_point)
if usage > threshold:
print(f"Alert: High inode usage ({usage}%) on {mount_point}")
return True
return False
def find_large_directories(mount_point):
cmd = f"find {mount_point} -xdev -type d -exec sh -c 'echo $(find \"$1\" -maxdepth 1 | wc -l) $1' _ {{}} \\;"
output = subprocess.check_output(cmd, shell=True).decode()
return sorted(output.split('\n'), key=lambda x: int(x.split()[0]) if len(x.split()) > 1 else 0)
def main():
mount_points = [line.split()[1] for line in open('/proc/mounts')
if line.split()[2] == 'xfs']
for mount in mount_points:
if alert_high_usage(mount):
print("\nLargest directories by file count:")
large_dirs = find_large_directories(mount)[-5:]
for dir_info in large_dirs:
if dir_info:
count, path = dir_info.split(' ', 1)
print(f"{path}: {count} files")
if __name__ == "__main__":
main()
2. Trend Analysis
#!/usr/bin/env python3
# inode_trends.py
import sqlite3
import time
from datetime import datetime
def init_db():
conn = sqlite3.connect('inode_history.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS inode_usage
(timestamp TEXT, mount_point TEXT,
total_inodes INTEGER, used_inodes INTEGER)''')
return conn
def record_usage(conn, mount_point):
c = conn.cursor()
df = subprocess.check_output(['df', '-i', mount_point]).decode()
_, total, used, _, _, _ = df.split('\n')[1].split()
c.execute('''INSERT INTO inode_usage VALUES
(?, ?, ?, ?)''',
(datetime.now().isoformat(), mount_point,
int(total), int(used)))
conn.commit()
def analyze_trends(conn, mount_point, days=30):
c = conn.cursor()
c.execute('''SELECT date(timestamp), avg(used_inodes * 100.0 / total_inodes)
FROM inode_usage
WHERE mount_point = ?
GROUP BY date(timestamp)
ORDER BY timestamp DESC
LIMIT ?''', (mount_point, days))
return c.fetchall()
Best Practices
Planning
- Size inodes appropriately
- Monitor usage patterns
- Plan for growth
Maintenance
- Regular monitoring
- Proactive cleanup
- Trend analysis
Documentation
- Track configuration changes
- Document cleanup procedures
- Maintain usage history
Remember that proper inode management is crucial for maintaining healthy XFS filesystems. Regular monitoring and proactive management can prevent inode-related issues before they impact system performance.