The access, birth, modification and change times are added to storage volumes and corresponding xml representations. --- docs/formatstorage.html.in | 27 +++++++++++++++++++++++++++ docs/schemas/storagevol.rng | 39 +++++++++++++++++++++++++++++++++++++++ src/conf/storage_conf.c | 21 +++++++++++++++++++++ src/conf/storage_conf.h | 13 +++++++++++++ src/storage/storage_backend.c | 21 +++++++++++++++++++++ 5 files changed, 121 insertions(+) diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in index d0e4319..d8ffbea 100644 --- a/docs/formatstorage.html.in +++ b/docs/formatstorage.html.in @@ -141,6 +141,20 @@ <mode>0744</mode> <label>virt_image_t</label> </permissions> + <timestamps> + <atime> + <sec>1341933637</sec> + <nsec>27319099</nsec> + </atime> + <ctime> + <sec>1341930622</sec> + <nsec>47245868</nsec> + </ctime> + <mtime> + <sec>1341930622</sec> + <nsec>47245868</nsec> + </mtime> + </timestamps> <encryption type='...'> ... </encryption> @@ -172,6 +186,19 @@ 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. Each timestamp is represented by an attribute + <code>sec</code> and and optional attribute <code>nsec</code>. The first + attribute holds the seconds since the beginning of the epoch and the second + attribute the additional nanoseconds. If nanosecond resolution isn't supported + by the host OS or filesystem then the <code>nsec</code> attribute is omitted. + For technical reasons the attribute is also omitted when zero. All timestamps + are readonly attributes and are 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..af48bd2 100644 --- a/docs/schemas/storagevol.rng +++ b/docs/schemas/storagevol.rng @@ -63,6 +63,44 @@ </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'> + <element name='sec'> + <ref name='unsignedLong'/> + </element> + <optional> + <element name='nsec'> + <ref name='unsignedLong'/> + </element> + </optional> + </define> + <define name='target'> <element name='target'> <optional> @@ -72,6 +110,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..5651b76 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -1241,6 +1241,20 @@ 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>\n", name); + virBufferAsprintf(buf, " <sec>%llu</sec>\n", + (unsigned long long) ts->tv_sec); + if (ts->tv_nsec) + virBufferAsprintf(buf, " <nsec>%ld</nsec>\n", ts->tv_nsec); + virBufferAsprintf(buf, " </%s>\n", name); +} + static int virStorageVolTargetDefFormat(virStorageVolOptionsPtr options, virBufferPtr buf, @@ -1277,6 +1291,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..1ef6df9 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -1155,6 +1155,11 @@ virStorageBackendUpdateVolTargetInfoFD(virStorageVolTargetPtr target, unsigned long long *capacity) { struct stat sb; + struct timespec *const atime = &target->timestamps.atime, + *const btime = &target->timestamps.btime, + *const catime = &target->timestamps.ctime, + *const mtime = &target->timestamps.mtime; + #if HAVE_SELINUX security_context_t filecon = NULL; #endif @@ -1208,6 +1213,22 @@ virStorageBackendUpdateVolTargetInfoFD(virStorageVolTargetPtr target, target->perms.uid = sb.st_uid; target->perms.gid = sb.st_gid; + atime->tv_sec = sb.st_atime; + mtime->tv_sec = sb.st_mtime; + catime->tv_sec = sb.st_ctime; +#if _BSD_SOURCE || _SVID_SOURCE || \ + _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700 + atime->tv_nsec = sb.st_atim.tv_nsec; + mtime->tv_nsec = sb.st_mtim.tv_nsec; + catime->tv_nsec = sb.st_ctim.tv_nsec; +#else + atime->tv_nsec = sb.st_atimensec; + mtime->tv_nsec = sb.st_mtimensec; + catime->tv_nsec = sb.st_ctimensec; +#endif + btime->tv_sec = -1; + btime->tv_nsec = -1; + 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