mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
src: replace gmtime_r/localtime_r/strftime with GDateTime
gmtime_r/localtime_r are mostly used in combination with strftime to format timestamps in libvirt. This can all be replaced with GDateTime resulting in simpler code that is also more portable. There is some boundary condition problem in parsing POSIX timezone offsets in GLib which tickles our test suite. The test suite is hacked to avoid the problem. The upsteam GLib bug report is https://gitlab.gnome.org/GNOME/glib/issues/1999 Reviewed-by: Pavel Hrdina <phrdina@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
7c828af858
commit
3caa28dc50
@ -26790,11 +26790,12 @@ virDomainGraphicsAuthDefFormatAttr(virBufferPtr buf,
|
|||||||
def->passwd);
|
def->passwd);
|
||||||
|
|
||||||
if (def->expires) {
|
if (def->expires) {
|
||||||
char strbuf[100];
|
g_autoptr(GDateTime) then = NULL;
|
||||||
struct tm tmbuf, *tm;
|
g_autofree char *thenstr = NULL;
|
||||||
tm = gmtime_r(&def->validTo, &tmbuf);
|
|
||||||
strftime(strbuf, sizeof(strbuf), "%Y-%m-%dT%H:%M:%S", tm);
|
then = g_date_time_new_from_unix_utc(def->validTo);
|
||||||
virBufferAsprintf(buf, " passwdValidTo='%s'", strbuf);
|
thenstr = g_date_time_format(then, "%Y-%m-%dT%H:%M:%S");
|
||||||
|
virBufferAsprintf(buf, " passwdValidTo='%s'", thenstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (def->connected)
|
if (def->connected)
|
||||||
|
@ -943,16 +943,14 @@ libxlDomainAutoCoreDump(libxlDriverPrivatePtr driver,
|
|||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
|
g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
|
||||||
time_t curtime = time(NULL);
|
g_autoptr(GDateTime) now = g_date_time_new_now_local();
|
||||||
char timestr[100];
|
g_autofree char *nowstr = NULL;
|
||||||
struct tm time_info;
|
|
||||||
char *dumpfile = NULL;
|
char *dumpfile = NULL;
|
||||||
|
|
||||||
localtime_r(&curtime, &time_info);
|
nowstr = g_date_time_format(now, "%Y-%m-%d-%H:%M:%S");
|
||||||
strftime(timestr, sizeof(timestr), "%Y-%m-%d-%H:%M:%S", &time_info);
|
|
||||||
|
|
||||||
dumpfile = g_strdup_printf("%s/%s-%s", cfg->autoDumpDir, vm->def->name,
|
dumpfile = g_strdup_printf("%s/%s-%s", cfg->autoDumpDir, vm->def->name,
|
||||||
timestr);
|
nowstr);
|
||||||
|
|
||||||
/* Unlock virDomainObj while dumping core */
|
/* Unlock virDomainObj while dumping core */
|
||||||
virObjectUnlock(vm);
|
virObjectUnlock(vm);
|
||||||
|
@ -6070,8 +6070,9 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: {
|
case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: {
|
||||||
time_t now = time(NULL);
|
g_autoptr(GDateTime) now = g_date_time_new_now_utc();
|
||||||
struct tm nowbits;
|
g_autoptr(GDateTime) then = NULL;
|
||||||
|
g_autofree char *thenstr = NULL;
|
||||||
|
|
||||||
if (def->data.variable.basis == VIR_DOMAIN_CLOCK_BASIS_LOCALTIME) {
|
if (def->data.variable.basis == VIR_DOMAIN_CLOCK_BASIS_LOCALTIME) {
|
||||||
long localOffset;
|
long localOffset;
|
||||||
@ -6094,8 +6095,8 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
|
|||||||
def->data.variable.basis = VIR_DOMAIN_CLOCK_BASIS_UTC;
|
def->data.variable.basis = VIR_DOMAIN_CLOCK_BASIS_UTC;
|
||||||
}
|
}
|
||||||
|
|
||||||
now += def->data.variable.adjustment;
|
then = g_date_time_add_seconds(now, def->data.variable.adjustment);
|
||||||
gmtime_r(&now, &nowbits);
|
thenstr = g_date_time_format(then, "%Y-%m-%dT%H:%M:%S");
|
||||||
|
|
||||||
/* when an RTC_CHANGE event is received from qemu, we need to
|
/* when an RTC_CHANGE event is received from qemu, we need to
|
||||||
* have the adjustment used at domain start time available to
|
* have the adjustment used at domain start time available to
|
||||||
@ -6105,13 +6106,7 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
|
|||||||
*/
|
*/
|
||||||
def->data.variable.adjustment0 = def->data.variable.adjustment;
|
def->data.variable.adjustment0 = def->data.variable.adjustment;
|
||||||
|
|
||||||
virBufferAsprintf(&buf, "base=%d-%02d-%02dT%02d:%02d:%02d",
|
virBufferAsprintf(&buf, "base=%s", thenstr);
|
||||||
nowbits.tm_year + 1900,
|
|
||||||
nowbits.tm_mon + 1,
|
|
||||||
nowbits.tm_mday,
|
|
||||||
nowbits.tm_hour,
|
|
||||||
nowbits.tm_min,
|
|
||||||
nowbits.tm_sec);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -4090,9 +4090,8 @@ getAutoDumpPath(virQEMUDriverPtr driver,
|
|||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
g_autofree char *domname = virDomainDefGetShortName(vm->def);
|
g_autofree char *domname = virDomainDefGetShortName(vm->def);
|
||||||
char timestr[100];
|
g_autoptr(GDateTime) now = g_date_time_new_now_local();
|
||||||
struct tm time_info;
|
g_autofree char *nowstr = NULL;
|
||||||
time_t curtime = time(NULL);
|
|
||||||
g_autoptr(virQEMUDriverConfig) cfg = NULL;
|
g_autoptr(virQEMUDriverConfig) cfg = NULL;
|
||||||
|
|
||||||
if (!domname)
|
if (!domname)
|
||||||
@ -4100,10 +4099,9 @@ getAutoDumpPath(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
cfg = virQEMUDriverGetConfig(driver);
|
cfg = virQEMUDriverGetConfig(driver);
|
||||||
|
|
||||||
localtime_r(&curtime, &time_info);
|
nowstr = g_date_time_format(now, "%Y-%m-%d-%H:%M:%S");
|
||||||
strftime(timestr, sizeof(timestr), "%Y-%m-%d-%H:%M:%S", &time_info);
|
|
||||||
|
|
||||||
return g_strdup_printf("%s/%s-%s", cfg->autoDumpPath, domname, timestr);
|
return g_strdup_printf("%s/%s-%s", cfg->autoDumpPath, domname, nowstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -302,8 +302,8 @@ char *virTimeStringThen(unsigned long long when)
|
|||||||
/**
|
/**
|
||||||
* virTimeLocalOffsetFromUTC:
|
* virTimeLocalOffsetFromUTC:
|
||||||
*
|
*
|
||||||
* This function is threadsafe, but is *not* async signal safe (due to
|
* This function is threadsafe, but is *not* async signal safe
|
||||||
* gmtime_r() and mktime()).
|
* due to use of GLib APIs.
|
||||||
*
|
*
|
||||||
* @offset: pointer to time_t that will be set to the difference
|
* @offset: pointer to time_t that will be set to the difference
|
||||||
* between localtime and UTC in seconds (east of UTC is a
|
* between localtime and UTC in seconds (east of UTC is a
|
||||||
@ -314,34 +314,11 @@ char *virTimeStringThen(unsigned long long when)
|
|||||||
int
|
int
|
||||||
virTimeLocalOffsetFromUTC(long *offset)
|
virTimeLocalOffsetFromUTC(long *offset)
|
||||||
{
|
{
|
||||||
struct tm gmtimeinfo;
|
g_autoptr(GDateTime) now = g_date_time_new_now_local();
|
||||||
time_t current, utc;
|
GTimeSpan diff = g_date_time_get_utc_offset(now);
|
||||||
|
|
||||||
/* time() gives seconds since Epoch in current timezone */
|
/* GTimeSpan measures microseconds, we want seconds */
|
||||||
if ((current = time(NULL)) == (time_t)-1) {
|
*offset = diff / 1000000;
|
||||||
virReportSystemError(errno, "%s",
|
|
||||||
_("failed to get current system time"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* treat current as if it were in UTC */
|
|
||||||
if (!gmtime_r(¤t, &gmtimeinfo)) {
|
|
||||||
virReportSystemError(errno, "%s",
|
|
||||||
_("gmtime_r failed"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tell mktime to figure out itself whether or not DST is in effect */
|
|
||||||
gmtimeinfo.tm_isdst = -1;
|
|
||||||
|
|
||||||
/* mktime() also obeys current timezone rules */
|
|
||||||
if ((utc = mktime(&gmtimeinfo)) == (time_t)-1) {
|
|
||||||
virReportSystemError(errno, "%s",
|
|
||||||
_("mktime failed"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*offset = current - utc;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,12 +47,14 @@ long virGetSystemPageSize(void)
|
|||||||
return 4096;
|
return 4096;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t time(time_t *t)
|
GDateTime *g_date_time_new_now_utc(void)
|
||||||
{
|
{
|
||||||
const time_t ret = 1234567890;
|
return g_date_time_new_from_unix_utc(1234567890);
|
||||||
if (t)
|
}
|
||||||
*t = ret;
|
|
||||||
return ret;
|
GDateTime *g_date_time_new_now_local(void)
|
||||||
|
{
|
||||||
|
return g_date_time_new_from_unix_local(1234567890);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -101,20 +101,12 @@ testTimeLocalOffset(const void *args)
|
|||||||
static bool
|
static bool
|
||||||
isNearYearEnd(void)
|
isNearYearEnd(void)
|
||||||
{
|
{
|
||||||
time_t current = time(NULL);
|
g_autoptr(GDateTime) now = g_date_time_new_now_local();
|
||||||
struct tm timeinfo;
|
|
||||||
|
|
||||||
if (current == (time_t)-1) {
|
return ((g_date_time_get_month(now) == 1 &&
|
||||||
VIR_DEBUG("time() failed");
|
g_date_time_get_day_of_month(now) == 1) ||
|
||||||
return false;
|
(g_date_time_get_month(now) == 12 &&
|
||||||
}
|
g_date_time_get_day_of_month(now) == 31));
|
||||||
if (!localtime_r(¤t, &timeinfo)) {
|
|
||||||
VIR_DEBUG("localtime_r() failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (timeinfo.tm_mon == 0 && timeinfo.tm_mday == 1) ||
|
|
||||||
(timeinfo.tm_mon == 11 && timeinfo.tm_mday == 31);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -186,14 +178,21 @@ mymain(void)
|
|||||||
/* test DST processing with timezones that always
|
/* test DST processing with timezones that always
|
||||||
* have DST in effect; what's more, cover a zone with
|
* have DST in effect; what's more, cover a zone with
|
||||||
* with an unusual DST different than a usual one hour
|
* with an unusual DST different than a usual one hour
|
||||||
|
*
|
||||||
|
* These tests originally used '0' as the first day,
|
||||||
|
* but changed to '1' due to GLib GTimeZone parsing bug:
|
||||||
|
* https://gitlab.gnome.org/GNOME/glib/issues/1999
|
||||||
|
*
|
||||||
|
* Once we depend on a new enough GLib, we can put then
|
||||||
|
* back to 0 again.
|
||||||
*/
|
*/
|
||||||
TEST_LOCALOFFSET("VIR-00:30VID,0/00:00:00,365/23:59:59",
|
TEST_LOCALOFFSET("VIR-00:30VID,1/00:00:00,364/23:59:59",
|
||||||
((1 * 60) + 30) * 60);
|
((1 * 60) + 30) * 60);
|
||||||
TEST_LOCALOFFSET("VIR-02:30VID,0/00:00:00,365/23:59:59",
|
TEST_LOCALOFFSET("VIR-02:30VID,1/00:00:00,364/23:59:59",
|
||||||
((3 * 60) + 30) * 60);
|
((3 * 60) + 30) * 60);
|
||||||
TEST_LOCALOFFSET("VIR-02:30VID-04:30,0/00:00:00,365/23:59:59",
|
TEST_LOCALOFFSET("VIR-02:30VID-04:30,1/00:00:00,364/23:59:59",
|
||||||
((4 * 60) + 30) * 60);
|
((4 * 60) + 30) * 60);
|
||||||
TEST_LOCALOFFSET("VIR-12:00VID-13:00,0/00:00:00,365/23:59:59",
|
TEST_LOCALOFFSET("VIR-12:00VID-13:00,1/00:00:00,364/23:59:59",
|
||||||
((13 * 60) + 0) * 60);
|
((13 * 60) + 0) * 60);
|
||||||
|
|
||||||
if (!isNearYearEnd()) {
|
if (!isNearYearEnd()) {
|
||||||
@ -209,11 +208,11 @@ mymain(void)
|
|||||||
* tests, except on Dec 31 and Jan 1.
|
* tests, except on Dec 31 and Jan 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TEST_LOCALOFFSET("VIR02:45VID00:45,0/00:00:00,365/23:59:59",
|
TEST_LOCALOFFSET("VIR02:45VID00:45,1/00:00:00,364/23:59:59",
|
||||||
-45 * 60);
|
-45 * 60);
|
||||||
TEST_LOCALOFFSET("VIR05:00VID04:00,0/00:00:00,365/23:59:59",
|
TEST_LOCALOFFSET("VIR05:00VID04:00,1/00:00:00,364/23:59:59",
|
||||||
((-4 * 60) + 0) * 60);
|
((-4 * 60) + 0) * 60);
|
||||||
TEST_LOCALOFFSET("VIR11:00VID10:00,0/00:00:00,365/23:59:59",
|
TEST_LOCALOFFSET("VIR11:00VID10:00,1/00:00:00,364/23:59:59",
|
||||||
((-10 * 60) + 0) * 60);
|
((-10 * 60) + 0) * 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,9 +719,8 @@ cmdCheckpointList(vshControl *ctl,
|
|||||||
char *doc = NULL;
|
char *doc = NULL;
|
||||||
virDomainCheckpointPtr checkpoint = NULL;
|
virDomainCheckpointPtr checkpoint = NULL;
|
||||||
long long creation_longlong;
|
long long creation_longlong;
|
||||||
time_t creation_time_t;
|
g_autoptr(GDateTime) then = NULL;
|
||||||
char timestr[100];
|
g_autofree gchar *thenstr = NULL;
|
||||||
struct tm time_info;
|
|
||||||
bool tree = vshCommandOptBool(cmd, "tree");
|
bool tree = vshCommandOptBool(cmd, "tree");
|
||||||
bool name = vshCommandOptBool(cmd, "name");
|
bool name = vshCommandOptBool(cmd, "name");
|
||||||
bool from = vshCommandOptBool(cmd, "from");
|
bool from = vshCommandOptBool(cmd, "from");
|
||||||
@ -835,21 +834,16 @@ cmdCheckpointList(vshControl *ctl,
|
|||||||
if (virXPathLongLong("string(/domaincheckpoint/creationTime)", ctxt,
|
if (virXPathLongLong("string(/domaincheckpoint/creationTime)", ctxt,
|
||||||
&creation_longlong) < 0)
|
&creation_longlong) < 0)
|
||||||
continue;
|
continue;
|
||||||
creation_time_t = creation_longlong;
|
|
||||||
if (creation_time_t != creation_longlong) {
|
then = g_date_time_new_from_unix_local(creation_longlong);
|
||||||
vshError(ctl, "%s", _("time_t overflow"));
|
thenstr = g_date_time_format(then, "%Y-%m-%d %H:%M:%S %z");
|
||||||
continue;
|
|
||||||
}
|
|
||||||
localtime_r(&creation_time_t, &time_info);
|
|
||||||
strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S %z",
|
|
||||||
&time_info);
|
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
if (vshTableRowAppend(table, chk_name, timestr,
|
if (vshTableRowAppend(table, chk_name, thenstr,
|
||||||
NULLSTR_EMPTY(parent_chk), NULL) < 0)
|
NULLSTR_EMPTY(parent_chk), NULL) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
if (vshTableRowAppend(table, chk_name, timestr, NULL) < 0)
|
if (vshTableRowAppend(table, chk_name, thenstr, NULL) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1534,17 +1534,13 @@ cmdDomTime(vshControl *ctl, const vshCmd *cmd)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (pretty) {
|
if (pretty) {
|
||||||
char timestr[100];
|
g_autoptr(GDateTime) then = NULL;
|
||||||
time_t cur_time = seconds;
|
g_autofree char *thenstr = NULL;
|
||||||
struct tm time_info;
|
|
||||||
|
|
||||||
if (!gmtime_r(&cur_time, &time_info)) {
|
then = g_date_time_new_from_unix_utc(seconds);
|
||||||
vshError(ctl, _("Unable to format time"));
|
thenstr = g_date_time_format(then, "%Y-%m-%d %H:%M:%S");
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", &time_info);
|
|
||||||
|
|
||||||
vshPrint(ctl, _("Time: %s"), timestr);
|
vshPrint(ctl, _("Time: %s"), thenstr);
|
||||||
} else {
|
} else {
|
||||||
vshPrint(ctl, _("Time: %lld"), seconds);
|
vshPrint(ctl, _("Time: %lld"), seconds);
|
||||||
}
|
}
|
||||||
|
@ -5492,9 +5492,8 @@ static const vshCmdOptDef opts_screenshot[] = {
|
|||||||
static char *
|
static char *
|
||||||
virshGenFileName(vshControl *ctl, virDomainPtr dom, const char *mime)
|
virshGenFileName(vshControl *ctl, virDomainPtr dom, const char *mime)
|
||||||
{
|
{
|
||||||
char timestr[100];
|
g_autoptr(GDateTime) now = g_date_time_new_now_local();
|
||||||
time_t cur_time;
|
g_autofree char *nowstr = NULL;
|
||||||
struct tm time_info;
|
|
||||||
const char *ext = NULL;
|
const char *ext = NULL;
|
||||||
char *ret = NULL;
|
char *ret = NULL;
|
||||||
|
|
||||||
@ -5509,12 +5508,10 @@ virshGenFileName(vshControl *ctl, virDomainPtr dom, const char *mime)
|
|||||||
ext = ".png";
|
ext = ".png";
|
||||||
/* add mime type here */
|
/* add mime type here */
|
||||||
|
|
||||||
time(&cur_time);
|
nowstr = g_date_time_format(now, "%Y-%m-%d-%H:%M:%S");
|
||||||
localtime_r(&cur_time, &time_info);
|
|
||||||
strftime(timestr, sizeof(timestr), "%Y-%m-%d-%H:%M:%S", &time_info);
|
|
||||||
|
|
||||||
ret = g_strdup_printf("%s-%s%s", virDomainGetName(dom), timestr,
|
ret = g_strdup_printf("%s-%s%s", virDomainGetName(dom),
|
||||||
NULLSTR_EMPTY(ext));
|
nowstr, NULLSTR_EMPTY(ext));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1433,11 +1433,10 @@ cmdNetworkDHCPLeases(vshControl *ctl, const vshCmd *cmd)
|
|||||||
const char *typestr = NULL;
|
const char *typestr = NULL;
|
||||||
g_autofree char *cidr_format = NULL;
|
g_autofree char *cidr_format = NULL;
|
||||||
virNetworkDHCPLeasePtr lease = leases[i];
|
virNetworkDHCPLeasePtr lease = leases[i];
|
||||||
time_t expirytime_tmp = lease->expirytime;
|
g_autoptr(GDateTime) then = g_date_time_new_from_unix_local(lease->expirytime);
|
||||||
struct tm ts;
|
g_autofree char *thenstr = NULL;
|
||||||
char expirytime[32];
|
|
||||||
localtime_r(&expirytime_tmp, &ts);
|
thenstr = g_date_time_format(then, "%Y-%m-%d %H:%M:%S");
|
||||||
strftime(expirytime, sizeof(expirytime), "%Y-%m-%d %H:%M:%S", &ts);
|
|
||||||
|
|
||||||
if (lease->type == VIR_IP_ADDR_TYPE_IPV4)
|
if (lease->type == VIR_IP_ADDR_TYPE_IPV4)
|
||||||
typestr = "ipv4";
|
typestr = "ipv4";
|
||||||
@ -1447,7 +1446,7 @@ cmdNetworkDHCPLeases(vshControl *ctl, const vshCmd *cmd)
|
|||||||
cidr_format = g_strdup_printf("%s/%d", lease->ipaddr, lease->prefix);
|
cidr_format = g_strdup_printf("%s/%d", lease->ipaddr, lease->prefix);
|
||||||
|
|
||||||
if (vshTableRowAppend(table,
|
if (vshTableRowAppend(table,
|
||||||
expirytime,
|
thenstr,
|
||||||
NULLSTR_MINUS(lease->mac),
|
NULLSTR_MINUS(lease->mac),
|
||||||
NULLSTR_MINUS(typestr),
|
NULLSTR_MINUS(typestr),
|
||||||
NULLSTR_MINUS(cidr_format),
|
NULLSTR_MINUS(cidr_format),
|
||||||
|
@ -1492,9 +1492,8 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
|
|||||||
virDomainSnapshotPtr snapshot = NULL;
|
virDomainSnapshotPtr snapshot = NULL;
|
||||||
char *state = NULL;
|
char *state = NULL;
|
||||||
long long creation_longlong;
|
long long creation_longlong;
|
||||||
time_t creation_time_t;
|
g_autoptr(GDateTime) then = NULL;
|
||||||
char timestr[100];
|
g_autofree gchar *thenstr = NULL;
|
||||||
struct tm time_info;
|
|
||||||
bool tree = vshCommandOptBool(cmd, "tree");
|
bool tree = vshCommandOptBool(cmd, "tree");
|
||||||
bool name = vshCommandOptBool(cmd, "name");
|
bool name = vshCommandOptBool(cmd, "name");
|
||||||
bool from = vshCommandOptBool(cmd, "from");
|
bool from = vshCommandOptBool(cmd, "from");
|
||||||
@ -1624,22 +1623,16 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
|
|||||||
if (virXPathLongLong("string(/domainsnapshot/creationTime)", ctxt,
|
if (virXPathLongLong("string(/domainsnapshot/creationTime)", ctxt,
|
||||||
&creation_longlong) < 0)
|
&creation_longlong) < 0)
|
||||||
continue;
|
continue;
|
||||||
creation_time_t = creation_longlong;
|
then = g_date_time_new_from_unix_local(creation_longlong);
|
||||||
if (creation_time_t != creation_longlong) {
|
thenstr = g_date_time_format(then, "%Y-%m-%d %H:%M:%S %z");
|
||||||
vshError(ctl, "%s", _("time_t overflow"));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
localtime_r(&creation_time_t, &time_info);
|
|
||||||
strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S %z",
|
|
||||||
&time_info);
|
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
if (vshTableRowAppend(table, snap_name, timestr, state,
|
if (vshTableRowAppend(table, snap_name, thenstr, state,
|
||||||
NULLSTR_EMPTY(parent_snap),
|
NULLSTR_EMPTY(parent_snap),
|
||||||
NULL) < 0)
|
NULL) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
if (vshTableRowAppend(table, snap_name, timestr, state,
|
if (vshTableRowAppend(table, snap_name, thenstr, state,
|
||||||
NULL) < 0)
|
NULL) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -69,40 +69,6 @@ vshAdmClientTransportToString(int transport)
|
|||||||
return str ? _(str) : _("unknown");
|
return str ? _(str) : _("unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* vshAdmGetTimeStr:
|
|
||||||
*
|
|
||||||
* Produces string representation (local time) of @then
|
|
||||||
* (seconds since epoch UTC) using format 'YYYY-MM-DD HH:MM:SS+ZZZZ'.
|
|
||||||
*
|
|
||||||
* Returns 0 if conversion finished successfully, -1 in case of an error.
|
|
||||||
* Caller is responsible for freeing the string returned.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
vshAdmGetTimeStr(vshControl *ctl, time_t then, char **result)
|
|
||||||
{
|
|
||||||
char *tmp = NULL;
|
|
||||||
struct tm timeinfo;
|
|
||||||
|
|
||||||
if (!localtime_r(&then, &timeinfo))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (VIR_ALLOC_N(tmp, VIRT_ADMIN_TIME_BUFLEN) < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (strftime(tmp, VIRT_ADMIN_TIME_BUFLEN, "%Y-%m-%d %H:%M:%S%z",
|
|
||||||
&timeinfo) == 0) {
|
|
||||||
VIR_FREE(tmp);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
*result = tmp;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
vshError(ctl, "%s", _("Timestamp string conversion failed"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vshAdmCatchDisconnect:
|
* vshAdmCatchDisconnect:
|
||||||
@ -646,19 +612,19 @@ cmdSrvClientsList(vshControl *ctl, const vshCmd *cmd)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
for (i = 0; i < nclts; i++) {
|
for (i = 0; i < nclts; i++) {
|
||||||
g_autofree char *timestr = NULL;
|
g_autoptr(GDateTime) then = NULL;
|
||||||
|
g_autofree gchar *thenstr = NULL;
|
||||||
g_autofree char *idStr = NULL;
|
g_autofree char *idStr = NULL;
|
||||||
virAdmClientPtr client = clts[i];
|
virAdmClientPtr client = clts[i];
|
||||||
id = virAdmClientGetID(client);
|
id = virAdmClientGetID(client);
|
||||||
|
then = g_date_time_new_from_unix_local(virAdmClientGetTimestamp(client));
|
||||||
transport = virAdmClientGetTransport(client);
|
transport = virAdmClientGetTransport(client);
|
||||||
if (vshAdmGetTimeStr(ctl, virAdmClientGetTimestamp(client),
|
|
||||||
×tr) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
|
thenstr = g_date_time_format(then, "%Y-%m-%d %H:%M:%S%z");
|
||||||
idStr = g_strdup_printf("%llu", id);
|
idStr = g_strdup_printf("%llu", id);
|
||||||
if (vshTableRowAppend(table, idStr,
|
if (vshTableRowAppend(table, idStr,
|
||||||
vshAdmClientTransportToString(transport),
|
vshAdmClientTransportToString(transport),
|
||||||
timestr, NULL) < 0)
|
thenstr, NULL) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -714,7 +680,8 @@ cmdClientInfo(vshControl *ctl, const vshCmd *cmd)
|
|||||||
size_t i;
|
size_t i;
|
||||||
unsigned long long id;
|
unsigned long long id;
|
||||||
const char *srvname = NULL;
|
const char *srvname = NULL;
|
||||||
char *timestr = NULL;
|
g_autoptr(GDateTime) then = NULL;
|
||||||
|
g_autofree gchar *thenstr = NULL;
|
||||||
virAdmServerPtr srv = NULL;
|
virAdmServerPtr srv = NULL;
|
||||||
virAdmClientPtr clnt = NULL;
|
virAdmClientPtr clnt = NULL;
|
||||||
virTypedParameterPtr params = NULL;
|
virTypedParameterPtr params = NULL;
|
||||||
@ -739,12 +706,13 @@ cmdClientInfo(vshControl *ctl, const vshCmd *cmd)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vshAdmGetTimeStr(ctl, virAdmClientGetTimestamp(clnt), ×tr) < 0)
|
|
||||||
goto cleanup;
|
then = g_date_time_new_from_unix_local(virAdmClientGetTimestamp(clnt));
|
||||||
|
thenstr = g_date_time_format(then, "%Y-%m-%d %H:%M:%S%z");
|
||||||
|
|
||||||
/* this info is provided by the client object itself */
|
/* this info is provided by the client object itself */
|
||||||
vshPrint(ctl, "%-15s: %llu\n", "id", virAdmClientGetID(clnt));
|
vshPrint(ctl, "%-15s: %llu\n", "id", virAdmClientGetID(clnt));
|
||||||
vshPrint(ctl, "%-15s: %s\n", "connection_time", timestr);
|
vshPrint(ctl, "%-15s: %s\n", "connection_time", thenstr);
|
||||||
vshPrint(ctl, "%-15s: %s\n", "transport",
|
vshPrint(ctl, "%-15s: %s\n", "transport",
|
||||||
vshAdmClientTransportToString(virAdmClientGetTransport(clnt)));
|
vshAdmClientTransportToString(virAdmClientGetTransport(clnt)));
|
||||||
|
|
||||||
@ -760,7 +728,6 @@ cmdClientInfo(vshControl *ctl, const vshCmd *cmd)
|
|||||||
virTypedParamsFree(params, nparams);
|
virTypedParamsFree(params, nparams);
|
||||||
virAdmServerFree(srv);
|
virAdmServerFree(srv);
|
||||||
virAdmClientFree(clnt);
|
virAdmClientFree(clnt);
|
||||||
VIR_FREE(timestr);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
tools/vsh.c
16
tools/vsh.c
@ -2182,8 +2182,8 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format,
|
|||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
size_t len;
|
size_t len;
|
||||||
const char *lvl = "";
|
const char *lvl = "";
|
||||||
time_t stTime;
|
g_autoptr(GDateTime) now = g_date_time_new_now_local();
|
||||||
struct tm stTm;
|
g_autofree gchar *nowstr = NULL;
|
||||||
|
|
||||||
if (ctl->log_fd == -1)
|
if (ctl->log_fd == -1)
|
||||||
return;
|
return;
|
||||||
@ -2193,15 +2193,9 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format,
|
|||||||
*
|
*
|
||||||
* [YYYY.MM.DD HH:MM:SS SIGNATURE PID] LOG_LEVEL message
|
* [YYYY.MM.DD HH:MM:SS SIGNATURE PID] LOG_LEVEL message
|
||||||
*/
|
*/
|
||||||
time(&stTime);
|
nowstr = g_date_time_format(now, "%Y.%m.%d %H:%M:%S");
|
||||||
localtime_r(&stTime, &stTm);
|
virBufferAsprintf(&buf, "[%s %s %d] ",
|
||||||
virBufferAsprintf(&buf, "[%d.%02d.%02d %02d:%02d:%02d %s %d] ",
|
nowstr,
|
||||||
(1900 + stTm.tm_year),
|
|
||||||
(1 + stTm.tm_mon),
|
|
||||||
stTm.tm_mday,
|
|
||||||
stTm.tm_hour,
|
|
||||||
stTm.tm_min,
|
|
||||||
stTm.tm_sec,
|
|
||||||
ctl->progname,
|
ctl->progname,
|
||||||
(int) getpid());
|
(int) getpid());
|
||||||
switch (log_level) {
|
switch (log_level) {
|
||||||
|
Loading…
Reference in New Issue
Block a user