The access, birth, modification and change times are added to
storage volumes and corresponding xml representations.
---
bootstrap.conf | 1 +
docs/formatstorage.html.in | 16 ++++++++++++++++
docs/schemas/storagevol.rng | 34 ++++++++++++++++++++++++++++++++++
src/conf/storage_conf.c | 20 ++++++++++++++++++++
src/conf/storage_conf.h | 13 +++++++++++++
src/storage/storage_backend.c | 6 ++++++
6 files changed, 90 insertions(+)
diff --git a/bootstrap.conf b/bootstrap.conf
index 9b42cbf..d80d92d 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -90,6 +90,7 @@ sigaction
sigpipe
snprintf
socket
+stat-time
stdarg
stpcpy
strchrnul
diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in
index d0e4319..2a578e9 100644
--- a/docs/formatstorage.html.in
+++ b/docs/formatstorage.html.in
@@ -141,6 +141,11 @@
<mode>0744</mode>
<label>virt_image_t</label>
</permissions>
+ <timestamps>
+ <atime>1341933637.27319099</atime>
+ <ctime>1341930622.47245868</ctime>
+ <mtime>1341930622.47245868</mtime>
+ </timestamps>
<encryption type='...'>
...
</encryption>
@@ -172,6 +177,17 @@
contains the MAC (eg SELinux) label string.
<span class="since">Since 0.4.1</span>
</dd>
+ <dt><code>timestamps</code></dt>
+ <dd>Provides timing information about the volume. Up to four sub-elements
are
+ present, where <code>atime</code>, <code>btime</code>,
<code>ctime</code>
+ and <code>mtime</code> hold the access, birth, change and
modification time
+ of the volume, where known. The used time format is
+ <seconds>.<nanoseconds> since the beginning of the
epoch. If
+ nanosecond resolution isn't supported by the host OS or filesystem then the
+ nanoseconds part is omitted. It is also omitted when zero. This is a
+ readonly attribute and is ignored when creating a volume.
+ <span class="since">Since 0.10.0</span>
+ </dd>
<dt><code>encryption</code></dt>
<dd>If present, specifies how the volume is encrypted. See
the <a href="formatstorageencryption.html">Storage
Encryption</a> page
diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng
index 7a74331..f981b47 100644
--- a/docs/schemas/storagevol.rng
+++ b/docs/schemas/storagevol.rng
@@ -63,6 +63,39 @@
</optional>
</define>
+ <define name='timestamps'>
+ <optional>
+ <element name='timestamps'>
+ <optional>
+ <element name='atime'>
+ <ref name='timestamp'/>
+ </element>
+ </optional>
+ <optional>
+ <element name='btime'>
+ <ref name='timestamp'/>
+ </element>
+ </optional>
+ <optional>
+ <element name='ctime'>
+ <ref name='timestamp'/>
+ </element>
+ </optional>
+ <optional>
+ <element name='mtime'>
+ <ref name='timestamp'/>
+ </element>
+ </optional>
+ </element>
+ </optional>
+ </define>
+
+ <define name='timestamp'>
+ <data type='string'>
+ <param name="pattern">[0-9]+(\.[0-9]+)?</param>
+ </data>
+ </define>
+
<define name='target'>
<element name='target'>
<optional>
@@ -72,6 +105,7 @@
</optional>
<ref name='format'/>
<ref name='permissions'/>
+ <ref name='timestamps'/>
<optional>
<ref name='encryption'/>
</optional>
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 36a3bb9..bc8e8be 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -1241,6 +1241,19 @@ virStorageVolDefParseFile(virStoragePoolDefPtr pool,
return virStorageVolDefParse(pool, NULL, filename);
}
+static void
+virStorageVolTimestampFormat(virBufferPtr buf, const char *name,
+ struct timespec *ts)
+{
+ if (ts->tv_nsec < 0)
+ return;
+ virBufferAsprintf(buf, " <%s>%llu", name,
+ (unsigned long long) ts->tv_sec);
+ if (ts->tv_nsec)
+ virBufferAsprintf(buf, ".%09ld", ts->tv_nsec);
+ virBufferAsprintf(buf, "</%s>\n", name);
+}
+
static int
virStorageVolTargetDefFormat(virStorageVolOptionsPtr options,
virBufferPtr buf,
@@ -1277,6 +1290,13 @@ virStorageVolTargetDefFormat(virStorageVolOptionsPtr options,
virBufferAddLit(buf," </permissions>\n");
+ virBufferAddLit(buf, " <timestamps>\n");
+ virStorageVolTimestampFormat(buf, "atime", &def->timestamps.atime);
+ virStorageVolTimestampFormat(buf, "btime", &def->timestamps.btime);
+ virStorageVolTimestampFormat(buf, "ctime", &def->timestamps.ctime);
+ virStorageVolTimestampFormat(buf, "mtime", &def->timestamps.mtime);
+ virBufferAddLit(buf, " </timestamps>\n");
+
if (def->encryption) {
virBufferAdjustIndent(buf, 4);
if (virStorageEncryptionFormat(buf, def->encryption) < 0)
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index 5733b57..b67ef64 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -46,6 +46,18 @@ struct _virStoragePerms {
/* Storage volumes */
+typedef struct _virStorageTimestamps virStorageTimestamps;
+typedef virStorageTimestamps *virStorageTimestampsPtr;
+struct _virStorageTimestamps {
+ struct timespec atime;
+ /* if btime.tv_nsec == -1 then
+ * birth time is unknown
+ */
+ struct timespec btime;
+ struct timespec ctime;
+ struct timespec mtime;
+};
+
/*
* How the volume's data is stored on underlying
@@ -77,6 +89,7 @@ struct _virStorageVolTarget {
char *path;
int format;
virStoragePerms perms;
+ virStorageTimestamps timestamps;
int type; /* only used by disk backend for partition type */
/* Currently used only in virStorageVolDef.target, not in .backingstore. */
virStorageEncryptionPtr encryption;
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 6ea0881..c665711 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -57,6 +57,7 @@
#include "storage_backend.h"
#include "logging.h"
#include "virfile.h"
+#include "stat-time.h"
#if WITH_STORAGE_LVM
# include "storage_backend_logical.h"
@@ -1208,6 +1209,11 @@ virStorageBackendUpdateVolTargetInfoFD(virStorageVolTargetPtr
target,
target->perms.uid = sb.st_uid;
target->perms.gid = sb.st_gid;
+ target->timestamps.atime = get_stat_atime(&sb);
+ target->timestamps.btime = get_stat_birthtime(&sb);
+ target->timestamps.ctime = get_stat_ctime(&sb);
+ target->timestamps.mtime = get_stat_mtime(&sb);
+
VIR_FREE(target->perms.label);
#if HAVE_SELINUX
--
1.7.9.5