summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan McRae <allan@archlinux.org>2010-11-16 16:43:45 +1000
committerDan McGee <dan@archlinux.org>2010-12-12 20:29:59 -0600
commit3f0d98c124db1547d6595762bd2d125b4350b861 (patch)
treef4169db4b041783e010843c7333b9afbdfb9da9e
parente527699dddca41e3af6c1872e851405a4f5212a0 (diff)
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>
-rw-r--r--lib/libalpm/alpm.h1
-rw-r--r--lib/libalpm/diskspace.c43
-rw-r--r--lib/libalpm/error.c2
3 files changed, 45 insertions, 1 deletions
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");