mirror of
https://github.com/moparisthebest/pacman
synced 2024-10-31 15:45:03 -04:00
Add functions to calculate approximate disk usage by packages
Two helper function are added to calculate the disk usage from packages that are either currently installed on the system or from a package archive. Some minor approximations have been made: 1. Size for directories is not considered when removing a package from the filesystem to avoid multiple counting across packages. Also, these are reported to take zero size while installing. 2. Symlinks are reported to contribute zero size towards removal as libarchive reports them to have zero size for install. 3. Package data files (.PKGINFO, .INSTALL, .CHANGELOG) are counted towards usage on dbpath on install, but their size is not counted on package removal. 4. No handling of extra size needed for .pacsave/.pacnew files. Signed-off-by: Allan McRae <allan@archlinux.org> Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
695656d252
commit
e527699ddd
@ -133,6 +133,9 @@ AC_PATH_PROGS([BASH_SHELL], [bash bash4 bash3], [false])
|
|||||||
AM_GNU_GETTEXT([external])
|
AM_GNU_GETTEXT([external])
|
||||||
AM_GNU_GETTEXT_VERSION(0.13.1)
|
AM_GNU_GETTEXT_VERSION(0.13.1)
|
||||||
|
|
||||||
|
# Check for lm
|
||||||
|
AC_CHECK_LIB([m], [ceil])
|
||||||
|
|
||||||
# Check for libarchive
|
# Check for libarchive
|
||||||
AC_CHECK_LIB([archive], [archive_read_data], ,
|
AC_CHECK_LIB([archive], [archive_read_data], ,
|
||||||
AC_MSG_ERROR([libarchive is needed to compile pacman!]))
|
AC_MSG_ERROR([libarchive is needed to compile pacman!]))
|
||||||
|
@ -33,6 +33,12 @@
|
|||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/* libarchive */
|
||||||
|
#include <archive.h>
|
||||||
|
#include <archive_entry.h>
|
||||||
|
|
||||||
/* libalpm */
|
/* libalpm */
|
||||||
#include "diskspace.h"
|
#include "diskspace.h"
|
||||||
#include "alpm_list.h"
|
#include "alpm_list.h"
|
||||||
@ -152,6 +158,100 @@ static alpm_list_t *match_mount_point(const alpm_list_t *mount_points, const cha
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int calculate_removed_size(pmpkg_t *pkg, const alpm_list_t *mount_points)
|
||||||
|
{
|
||||||
|
alpm_list_t *file;
|
||||||
|
|
||||||
|
alpm_list_t *files = alpm_pkg_get_files(pkg);
|
||||||
|
for(file = files; file; file = file->next) {
|
||||||
|
alpm_list_t *mp;
|
||||||
|
alpm_mountpoint_t *data;
|
||||||
|
struct stat st;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
|
/* skip directories to be consistent with libarchive that reports them to be zero size
|
||||||
|
and to prevent multiple counting across packages */
|
||||||
|
if(*((char *)(file->data) + strlen(file->data) - 1) == '/') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp = match_mount_point(mount_points, file->data);
|
||||||
|
if(mp == NULL) {
|
||||||
|
_alpm_log(PM_LOG_WARNING, _("could not determine mount point for file %s"), (char *)(file->data));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(path, PATH_MAX, "%s%s", handle->root, (char *)file->data);
|
||||||
|
_alpm_lstat(path, &st);
|
||||||
|
|
||||||
|
/* skip symlinks to be consistent with libarchive that reports them to be zero size */
|
||||||
|
if(S_ISLNK(st.st_mode)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = mp->data;
|
||||||
|
data->blocks_needed -= ceil((double)(st.st_size) /
|
||||||
|
(double)(data->fsp->f_bsize));
|
||||||
|
data->used = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int calculate_installed_size(pmpkg_t *pkg, const alpm_list_t *mount_points)
|
||||||
|
{
|
||||||
|
int ret=0;
|
||||||
|
struct archive *archive;
|
||||||
|
struct archive_entry *entry;
|
||||||
|
const char *file;
|
||||||
|
|
||||||
|
if ((archive = archive_read_new()) == NULL) {
|
||||||
|
pm_errno = PM_ERR_LIBARCHIVE;
|
||||||
|
ret = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
archive_read_support_compression_all(archive);
|
||||||
|
archive_read_support_format_all(archive);
|
||||||
|
|
||||||
|
if(archive_read_open_filename(archive, pkg->origin_data.file,
|
||||||
|
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
|
||||||
|
pm_errno = PM_ERR_PKG_OPEN;
|
||||||
|
ret = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
|
||||||
|
alpm_list_t *mp;
|
||||||
|
alpm_mountpoint_t *data;
|
||||||
|
|
||||||
|
file = archive_entry_pathname(entry);
|
||||||
|
|
||||||
|
/* approximate space requirements for db entries */
|
||||||
|
if(strcmp(file, ".PKGINFO") == 0 ||
|
||||||
|
strcmp(file, ".INSTALL") == 0 ||
|
||||||
|
strcmp(file, ".CHANGELOG") == 0) {
|
||||||
|
file = alpm_option_get_dbpath();
|
||||||
|
}
|
||||||
|
|
||||||
|
mp = match_mount_point(mount_points, file);
|
||||||
|
if(mp == NULL) {
|
||||||
|
_alpm_log(PM_LOG_WARNING, _("could not determine mount point for file %s"), archive_entry_pathname(entry));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = mp->data;
|
||||||
|
data->blocks_needed += ceil((double)(archive_entry_size(entry)) /
|
||||||
|
(double)(data->fsp->f_bsize));
|
||||||
|
data->used = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
archive_read_finish(archive);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db)
|
int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db)
|
||||||
{
|
{
|
||||||
alpm_list_t *mount_points;
|
alpm_list_t *mount_points;
|
||||||
|
Loading…
Reference in New Issue
Block a user