[pacman-dev] Checking free space before transaction

Dan McGee dpmcgee at gmail.com
Thu Nov 11 19:40:38 CET 2010


On Thu, Nov 11, 2010 at 10:03 AM, Nezmer <git at nezmer.info> wrote:
> On Thu, Nov 11, 2010 at 09:42:13AM -0600, Dan McGee wrote:
>> On Thu, Nov 11, 2010 at 9:05 AM, Allan McRae <allan at archlinux.org> wrote:
>> > On 12/11/10 00:49, Nezmer wrote:
>> >>
>> >> On Thu, Nov 11, 2010 at 04:46:44PM +0200, Nezmer wrote:
>> >>>
>> >>> On Thu, Nov 11, 2010 at 09:09:27AM +1000, Allan McRae wrote:
>> >>>>
>> >>>> On 11/11/10 07:29, Nezmer wrote:
>> >>>>>
>> >>>>> But with those changes pacman did not like my ZFS pool.
>> >>>>
>> >>>>  From a bit of google, it looks like the statvfs call is probably
>> >>>> returning EOVERFLOW on that so we can probably just assume LOTS of
>> >>>> space and move on in those conditions...
>> >>>>
>> >>>> Allan
>> >>>>
>> >>>>
>> >>>
>> >>> That's over-simplification. This is the quick patch I needed to make
>> >>> this even compile.
>> >>
>> >>> diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c
>> >>> index 51c25ed..f382d3c 100644
>> >>> --- a/lib/libalpm/diskspace.c
>> >>> +++ b/lib/libalpm/diskspace.c
>> >>> @@ -80,7 +80,7 @@ static alpm_list_t *mount_point_list()
>> >>>        endmntent(fp);
>> >>>  #elif defined HAVE_GETMNTINFO
>> >>>        int entries;
>> >>> -       struct statvfs *fsp;
>> >>> +       struct statfs *fsp;
>> >>>
>> >>>        entries = getmntinfo(&fsp, MNT_NOWAIT);
>> >>>
>> >>
>> >> from /usr/include/sys/mount.h:
>> >> int getmntinfo(struct statfs **, int);
>> >
>> > And here comes the joys of various BSDs doing whatever they feel like...   I
>> > have programmed based on the NetBSD man page which does use a statvfs
>> > struct...
>>
>> This seems to explain it well:
>> http://stackoverflow.com/questions/1653163/difference-between-statvfs-and-statfs-system-calls
>>
>> FreeBSD also seems to define the function and type elsewhere, so we
>> might just need to be smarter about what header we include:
>> http://www.cygwin.com/ml/cygwin-developers/2003-12/msg00020.html
>>
>> So we shouldn't be using statfs() if possible. What was the error,
>> Nezmer? Compile output would have been nice; is it that the type and
>> function aren't even defined? Can you grep /usr/include/ for us to see
>> if statvfs is defined but needs some sort of #define to turn it on?
>>
>> -Dan
>>
>
> I'm probably not the best person to answer those questions (Did I
> mention I don't know much in C ?).
>
> The 1st error was as I already mentioned in getmntinfo expecting statfs
> struct.
>
> statfs is defined in sys/mount.h :
>
> struct statfs {
>  uint32_t f_version;   /* structure version number */
>  uint32_t f_type;    /* type of filesystem */
>  uint64_t f_flags;   /* copy of mount exported flags */
>  uint64_t f_bsize;   /* filesystem fragment size */
>  uint64_t f_iosize;    /* optimal transfer block size */
>  uint64_t f_blocks;    /* total data blocks in filesystem */
>  uint64_t f_bfree;   /* free blocks in filesystem */
>  int64_t  f_bavail;    /* free blocks avail to non-superuser */
>  uint64_t f_files;   /* total file nodes in filesystem */
>  int64_t  f_ffree;   /* free nodes avail to non-superuser */
>  uint64_t f_syncwrites;    /* count of sync writes since mount */
>  uint64_t f_asyncwrites;   /* count of async writes since mount */
>  uint64_t f_syncreads;   /* count of sync reads since mount */
>  uint64_t f_asyncreads;    /* count of async reads since mount */
>  uint64_t f_spare[10];   /* unused spare */
>  uint32_t f_namemax;   /* maximum filename length */
>  uid_t   f_owner;    /* user that mounted the filesystem */
>  fsid_t    f_fsid;   /* filesystem id */
>  char    f_charspare[80];      /* spare string space */
>  char    f_fstypename[MFSNAMELEN]; /* filesystem type name */
>  char    f_mntfromname[MNAMELEN];  /* mounted filesystem */
>  char    f_mntonname[MNAMELEN];    /* directory on which mounted */
> };
>
>
> statvfs is defined in sys/statvfs.h :
>
> struct statvfs {
>  fsblkcnt_t  f_bavail; /* Number of blocks */
>  fsblkcnt_t  f_bfree;
>  fsblkcnt_t  f_blocks;
>  fsfilcnt_t  f_favail; /* Number of files (e.g., inodes) */
>  fsfilcnt_t  f_ffree;
>  fsfilcnt_t  f_files;
>  unsigned long f_bsize;  /* Size of blocks counted above */
>  unsigned long f_flag;
>  unsigned long f_frsize; /* Size of fragments */
>  unsigned long f_fsid;   /* Not meaningful */
>  unsigned long f_namemax;  /* Same as pathconf(_PC_NAME_MAX) */
> };

More potentially useful info to make this work a little better everywhere:
http://www.gnu.org/software/hello/manual/autoconf/Particular-Functions.html#AC_005fFUNC_005fGETMNTENT

-Dan


More information about the pacman-dev mailing list