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/alpm.h | 1 + lib/libalpm/diskspace.c | 43 ++++++++++++++++++++++++++++++++++++++++++- lib/libalpm/error.c | 2 ++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 237e2356..4d0ca501 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -479,6 +479,7 @@ enum _pmerrno_t { PM_ERR_NOT_A_FILE, PM_ERR_NOT_A_DIR, PM_ERR_WRONG_ARGS, + PM_ERR_DISK_SPACE, /* Interface */ PM_ERR_HANDLE_NULL, PM_ERR_HANDLE_NOT_NULL, 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; } diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c index c83f606e..78a78667 100644 --- a/lib/libalpm/error.c +++ b/lib/libalpm/error.c @@ -60,6 +60,8 @@ const char SYMEXPORT *alpm_strerror(int err) return _("could not find or read directory"); case PM_ERR_WRONG_ARGS: return _("wrong or NULL argument passed"); + case PM_ERR_DISK_SPACE: + return _("not enough disk space"); /* Interface */ case PM_ERR_HANDLE_NULL: return _("library not initialized"); -- cgit v1.2.3-24-g4f1b