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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list