From 3f0d98c124db1547d6595762bd2d125b4350b861 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Tue, 16 Nov 2010 16:43:45 +1000 Subject: Implement disk space checking Pull together the work of the previous commits to implement a check for enough free space before performing an install transaction. Abort if there is not enough free space with an appropriate pm_errno.. Signed-off-by: Allan McRae Signed-off-by: Dan McGee --- lib/libalpm/diskspace.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'lib/libalpm/diskspace.c') diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c index 919d1590..e57b4246 100644 --- a/lib/libalpm/diskspace.c +++ b/lib/libalpm/diskspace.c @@ -254,7 +254,10 @@ cleanup: int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db) { - alpm_list_t *mount_points; + alpm_list_t *mount_points, *i; + int replaces = 0, abort = 0; + alpm_list_t *targ; + pmpkg_t *pkg; mount_points = mount_point_list(); if(mount_points == NULL) { @@ -262,6 +265,40 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db) return -1; } + replaces = alpm_list_count(trans->remove); + if(replaces) { + for(targ = trans->remove; targ; targ = targ->next) { + pkg = (pmpkg_t*)targ->data; + calculate_removed_size(pkg, mount_points); + } + } + + for(targ = trans->add; targ; targ = targ->next) { + pkg = (pmpkg_t*)targ->data; + if(_alpm_db_get_pkgfromcache(db, pkg->name)) { + calculate_removed_size(pkg, mount_points); + } + calculate_installed_size(pkg, mount_points); + + for(i = mount_points; i; i = alpm_list_next(i)) { + alpm_mountpoint_t *data = i->data; + if(data->blocks_needed > data->max_blocks_needed) { + data->max_blocks_needed = data->blocks_needed; + } + } + } + + for(i = mount_points; i; i = alpm_list_next(i)) { + alpm_mountpoint_t *data = i->data; + if(data->used == 1) { + _alpm_log(PM_LOG_DEBUG, "partition %s, needed %ld, free %ld\n", + data->mount_dir, data->max_blocks_needed, (long int)(data->fsp->f_bfree)); + if(data->max_blocks_needed > data->fsp->f_bfree) { + abort = 1; + } + } + } + for(i = mount_points; i; i = alpm_list_next(i)) { alpm_mountpoint_t *data = i->data; FREE(data->mount_dir); @@ -269,6 +306,10 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db) } FREELIST(mount_points); + if(abort) { + RET_ERR(PM_ERR_DISK_SPACE, -1); + } + return 0; } -- cgit v1.2.3-2-g168b