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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
framecnt_t frames = _session->available_capture_duration();
|
boost::optional<framecnt_t> opt_frames = _session->available_capture_duration();
|
||||||
char buf[64];
|
char buf[64];
|
||||||
framecnt_t fr = _session->frame_rate();
|
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>"));
|
snprintf (buf, sizeof (buf), "%s", _("Disk: <span foreground=\"green\">24hrs+</span>"));
|
||||||
} else {
|
} else {
|
||||||
rec_enabled_streams = 0;
|
rec_enabled_streams = 0;
|
||||||
_session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
|
_session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
|
||||||
|
|
||||||
|
framecnt_t frames = opt_frames.get_value_or (0);
|
||||||
|
|
||||||
if (rec_enabled_streams) {
|
if (rec_enabled_streams) {
|
||||||
frames /= rec_enabled_streams;
|
frames /= rec_enabled_streams;
|
||||||
}
|
}
|
||||||
|
|
|
@ -669,7 +669,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||||
|
|
||||||
/* s/w "RAID" management */
|
/* s/w "RAID" management */
|
||||||
|
|
||||||
framecnt_t available_capture_duration();
|
boost::optional<framecnt_t> available_capture_duration();
|
||||||
|
|
||||||
/* I/O bundles */
|
/* I/O bundles */
|
||||||
|
|
||||||
|
@ -1329,16 +1329,21 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
||||||
/* S/W RAID */
|
/* S/W RAID */
|
||||||
|
|
||||||
struct space_and_path {
|
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;
|
std::string path;
|
||||||
|
|
||||||
space_and_path() {
|
space_and_path ()
|
||||||
blocks = 0;
|
: blocks (0)
|
||||||
}
|
, blocks_unknown (true)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct space_and_path_ascending_cmp {
|
struct space_and_path_ascending_cmp {
|
||||||
bool operator() (space_and_path a, space_and_path b) {
|
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;
|
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> session_dirs;
|
||||||
std::vector<space_and_path>::iterator last_rr_session_dir;
|
std::vector<space_and_path>::iterator last_rr_session_dir;
|
||||||
uint32_t _total_free_4k_blocks;
|
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;
|
Glib::Mutex space_lock;
|
||||||
|
|
||||||
bool no_questions_about_missing_files;
|
bool no_questions_about_missing_files;
|
||||||
|
|
|
@ -143,6 +143,7 @@ Session::Session (AudioEngine &eng,
|
||||||
, _all_route_group (new RouteGroup (*this, "all"))
|
, _all_route_group (new RouteGroup (*this, "all"))
|
||||||
, routes (new RouteList)
|
, routes (new RouteList)
|
||||||
, _total_free_4k_blocks (0)
|
, _total_free_4k_blocks (0)
|
||||||
|
, _total_free_4k_blocks_uncertain (false)
|
||||||
, _bundles (new BundleList)
|
, _bundles (new BundleList)
|
||||||
, _bundle_xml_node (0)
|
, _bundle_xml_node (0)
|
||||||
, _current_trans (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 ()
|
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
|
float sample_bytes_on_disk = 4.0; // keep gcc happy
|
||||||
|
|
||||||
switch (config.get_native_file_data_format()) {
|
switch (config.get_native_file_data_format()) {
|
||||||
|
|
|
@ -46,6 +46,10 @@
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_STATVFS_H
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
|
@ -2079,23 +2083,48 @@ Session::save_template (string template_name)
|
||||||
void
|
void
|
||||||
Session::refresh_disk_space ()
|
Session::refresh_disk_space ()
|
||||||
{
|
{
|
||||||
#if HAVE_SYS_VFS_H
|
#if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
|
||||||
struct statfs statfsbuf;
|
|
||||||
vector<space_and_path>::iterator i;
|
|
||||||
Glib::Mutex::Lock lm (space_lock);
|
Glib::Mutex::Lock lm (space_lock);
|
||||||
double scale;
|
|
||||||
|
|
||||||
/* get freespace on every FS that is part of the session path */
|
/* get freespace on every FS that is part of the session path */
|
||||||
|
|
||||||
_total_free_4k_blocks = 0;
|
_total_free_4k_blocks = 0;
|
||||||
|
_total_free_4k_blocks_uncertain = false;
|
||||||
|
|
||||||
for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
|
for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
|
||||||
statfs ((*i).path.c_str(), &statfsbuf);
|
|
||||||
|
|
||||||
scale = statfsbuf.f_bsize/4096.0;
|
struct statfs statfsbuf;
|
||||||
|
statfs (i->path.c_str(), &statfsbuf);
|
||||||
|
|
||||||
(*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
|
double const scale = statfsbuf.f_bsize / 4096.0;
|
||||||
_total_free_4k_blocks += (*i).blocks;
|
|
||||||
|
/* 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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,6 +289,7 @@ def configure(conf):
|
||||||
conf.define('CURRENT_SESSION_FILE_VERSION', CURRENT_SESSION_FILE_VERSION)
|
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/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' ],
|
conf.check(header_name='jack/session.h', uselib = [ 'JACK' ],
|
||||||
define_name='HAVE_JACK_SESSION')
|
define_name='HAVE_JACK_SESSION')
|
||||||
|
|
Loading…
Reference in New Issue