Handle failure of statfs to return available disc space on Samba shares mounted via GVFS, reporting available space as unknown in this case (#4657).
git-svn-id: svn://localhost/ardour2/branches/3.0@12674 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
d1d08e3910
commit
92432f3e80
|
@ -1050,16 +1050,21 @@ ARDOUR_UI::update_disk_space()
|
|||
return;
|
||||
}
|
||||
|
||||
framecnt_t frames = _session->available_capture_duration();
|
||||
boost::optional<framecnt_t> opt_frames = _session->available_capture_duration();
|
||||
char buf[64];
|
||||
framecnt_t fr = _session->frame_rate();
|
||||
|
||||
if (frames == max_framecnt) {
|
||||
if (!opt_frames) {
|
||||
/* Available space is unknown */
|
||||
snprintf (buf, sizeof (buf), "%s", _("Disk: <span foreground=\"green\">Unknown</span>"));
|
||||
} else if (opt_frames.get_value_or (0) == max_framecnt) {
|
||||
snprintf (buf, sizeof (buf), "%s", _("Disk: <span foreground=\"green\">24hrs+</span>"));
|
||||
} else {
|
||||
rec_enabled_streams = 0;
|
||||
_session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
|
||||
|
||||
framecnt_t frames = opt_frames.get_value_or (0);
|
||||
|
||||
if (rec_enabled_streams) {
|
||||
frames /= rec_enabled_streams;
|
||||
}
|
||||
|
|
|
@ -669,7 +669,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
|
||||
/* s/w "RAID" management */
|
||||
|
||||
framecnt_t available_capture_duration();
|
||||
boost::optional<framecnt_t> available_capture_duration();
|
||||
|
||||
/* I/O bundles */
|
||||
|
||||
|
@ -1329,16 +1329,21 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
/* S/W RAID */
|
||||
|
||||
struct space_and_path {
|
||||
uint32_t blocks; /* 4kB blocks */
|
||||
uint32_t blocks; ///< 4kB blocks
|
||||
bool blocks_unknown; ///< true if blocks is unknown
|
||||
std::string path;
|
||||
|
||||
space_and_path() {
|
||||
blocks = 0;
|
||||
}
|
||||
space_and_path ()
|
||||
: blocks (0)
|
||||
, blocks_unknown (true)
|
||||
{}
|
||||
};
|
||||
|
||||
struct space_and_path_ascending_cmp {
|
||||
bool operator() (space_and_path a, space_and_path b) {
|
||||
if (a.blocks_unknown != b.blocks_unknown) {
|
||||
return !a.blocks_unknown;
|
||||
}
|
||||
return a.blocks > b.blocks;
|
||||
}
|
||||
};
|
||||
|
@ -1348,6 +1353,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
std::vector<space_and_path> session_dirs;
|
||||
std::vector<space_and_path>::iterator last_rr_session_dir;
|
||||
uint32_t _total_free_4k_blocks;
|
||||
/** If this is true, _total_free_4k_blocks is not definite,
|
||||
as one or more of the session directories' filesystems
|
||||
could not report free space.
|
||||
*/
|
||||
bool _total_free_4k_blocks_uncertain;
|
||||
Glib::Mutex space_lock;
|
||||
|
||||
bool no_questions_about_missing_files;
|
||||
|
|
|
@ -143,6 +143,7 @@ Session::Session (AudioEngine &eng,
|
|||
, _all_route_group (new RouteGroup (*this, "all"))
|
||||
, routes (new RouteList)
|
||||
, _total_free_4k_blocks (0)
|
||||
, _total_free_4k_blocks_uncertain (false)
|
||||
, _bundles (new BundleList)
|
||||
, _bundle_xml_node (0)
|
||||
, _current_trans (0)
|
||||
|
@ -3501,9 +3502,16 @@ Session::graph_reordered ()
|
|||
}
|
||||
}
|
||||
|
||||
framecnt_t
|
||||
/** @return Number of frames that there is disk space available to write,
|
||||
* if known.
|
||||
*/
|
||||
boost::optional<framecnt_t>
|
||||
Session::available_capture_duration ()
|
||||
{
|
||||
if (_total_free_4k_blocks_uncertain) {
|
||||
return boost::optional<framecnt_t> ();
|
||||
}
|
||||
|
||||
float sample_bytes_on_disk = 4.0; // keep gcc happy
|
||||
|
||||
switch (config.get_native_file_data_format()) {
|
||||
|
|
|
@ -46,6 +46,10 @@
|
|||
#include <sys/mount.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STATVFS_H
|
||||
#include <sys/statvfs.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <glibmm.h>
|
||||
|
@ -2079,23 +2083,48 @@ Session::save_template (string template_name)
|
|||
void
|
||||
Session::refresh_disk_space ()
|
||||
{
|
||||
#if HAVE_SYS_VFS_H
|
||||
struct statfs statfsbuf;
|
||||
vector<space_and_path>::iterator i;
|
||||
#if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
|
||||
|
||||
Glib::Mutex::Lock lm (space_lock);
|
||||
double scale;
|
||||
|
||||
/* get freespace on every FS that is part of the session path */
|
||||
|
||||
_total_free_4k_blocks = 0;
|
||||
_total_free_4k_blocks_uncertain = false;
|
||||
|
||||
for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
|
||||
statfs ((*i).path.c_str(), &statfsbuf);
|
||||
for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
|
||||
|
||||
scale = statfsbuf.f_bsize/4096.0;
|
||||
struct statfs statfsbuf;
|
||||
statfs (i->path.c_str(), &statfsbuf);
|
||||
|
||||
(*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
|
||||
_total_free_4k_blocks += (*i).blocks;
|
||||
double const scale = statfsbuf.f_bsize / 4096.0;
|
||||
|
||||
/* See if this filesystem is read-only */
|
||||
struct statvfs statvfsbuf;
|
||||
statvfs (i->path.c_str(), &statvfsbuf);
|
||||
|
||||
/* f_bavail can be 0 if it is undefined for whatever
|
||||
filesystem we are looking at; Samba shares mounted
|
||||
via GVFS are an example of this.
|
||||
*/
|
||||
if (statfsbuf.f_bavail == 0) {
|
||||
/* block count unknown */
|
||||
i->blocks = 0;
|
||||
i->blocks_unknown = true;
|
||||
} else if (statvfsbuf.f_flag & ST_RDONLY) {
|
||||
/* read-only filesystem */
|
||||
i->blocks = 0;
|
||||
i->blocks_unknown = false;
|
||||
} else {
|
||||
/* read/write filesystem with known space */
|
||||
i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
|
||||
i->blocks_unknown = false;
|
||||
}
|
||||
|
||||
_total_free_4k_blocks += i->blocks;
|
||||
if (i->blocks_unknown) {
|
||||
_total_free_4k_blocks_uncertain = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -289,6 +289,7 @@ def configure(conf):
|
|||
conf.define('CURRENT_SESSION_FILE_VERSION', CURRENT_SESSION_FILE_VERSION)
|
||||
|
||||
conf.check(header_name='sys/vfs.h', define_name='HAVE_SYS_VFS_H',mandatory=False)
|
||||
conf.check(header_name='sys/statvfs.h', define_name='HAVE_SYS_STATVFS_H',mandatory=False)
|
||||
|
||||
conf.check(header_name='jack/session.h', uselib = [ 'JACK' ],
|
||||
define_name='HAVE_JACK_SESSION')
|
||||
|
|
Loading…
Reference in New Issue