diff options
author | Allan McRae <allan@archlinux.org> | 2010-11-16 16:43:45 +1000 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2010-12-12 20:29:59 -0600 |
commit | 3f0d98c124db1547d6595762bd2d125b4350b861 (patch) | |
tree | f4169db4b041783e010843c7333b9afbdfb9da9e /lib/libalpm/diskspace.c | |
parent | e527699dddca41e3af6c1872e851405a4f5212a0 (diff) | |
download | pacman-3f0d98c124db1547d6595762bd2d125b4350b861.tar.xz |
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 <allan@archlinux.org>
Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'lib/libalpm/diskspace.c')
-rw-r--r-- | lib/libalpm/diskspace.c | 43 |
1 files changed, 42 insertions, 1 deletions
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; } |