The virDomainTimerDefParseXML() function uses old style of
parsing XML (virXMLPropString + str2enum conversion). Use
virXMLPropEnumDefault() which encapsulates those steps.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/conf/domain_conf.c | 105 +++++++++++++--------------------------
src/conf/domain_conf.h | 14 +++---
src/libxl/libxl_conf.c | 6 ++-
src/libxl/xen_common.c | 6 ++-
src/lxc/lxc_cgroup.c | 2 +-
src/lxc/lxc_controller.c | 2 +-
src/qemu/qemu_command.c | 11 +++-
src/qemu/qemu_validate.c | 8 ++-
8 files changed, 69 insertions(+), 85 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 52a34cd131..27fe6c9fbf 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11962,98 +11962,61 @@ virDomainTimerDefParseXML(xmlNodePtr node,
virDomainTimerDef *def;
VIR_XPATH_NODE_AUTORESTORE(ctxt)
xmlNodePtr catchup;
- int ret;
- g_autofree char *name = NULL;
- g_autofree char *tickpolicy = NULL;
- g_autofree char *track = NULL;
- g_autofree char *mode = NULL;
def = g_new0(virDomainTimerDef, 1);
ctxt->node = node;
- name = virXMLPropString(node, "name");
- if (name == NULL) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("missing timer name"));
+ if (virXMLPropEnum(node, "name",
+ virDomainTimerNameTypeFromString,
+ VIR_XML_PROP_REQUIRED,
+ &def->name) < 0)
goto error;
- }
- if ((def->name = virDomainTimerNameTypeFromString(name)) < 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("unknown timer name '%s'"), name);
- goto error;
- }
if (virXMLPropTristateBool(node, "present",
VIR_XML_PROP_NONE,
&def->present) < 0)
goto error;
- tickpolicy = virXMLPropString(node, "tickpolicy");
- if (tickpolicy != NULL) {
- if ((def->tickpolicy = virDomainTimerTickpolicyTypeFromString(tickpolicy)) <= 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("unknown timer tickpolicy '%s'"), tickpolicy);
- goto error;
- }
- }
+ if (virXMLPropEnum(node, "tickpolicy",
+ virDomainTimerTickpolicyTypeFromString,
+ VIR_XML_PROP_NONZERO,
+ &def->tickpolicy) < 0)
+ goto error;
- track = virXMLPropString(node, "track");
- if (track != NULL) {
- if ((def->track = virDomainTimerTrackTypeFromString(track)) <= 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("unknown timer track '%s'"), track);
- goto error;
- }
- }
+ if (virXMLPropEnum(node, "track",
+ virDomainTimerTrackTypeFromString,
+ VIR_XML_PROP_NONZERO,
+ &def->track) < 0)
+ goto error;
- ret = virXPathULongLong("string(./@frequency)", ctxt, &def->frequency);
- if (ret == -1) {
- def->frequency = 0;
- } else if (ret < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("invalid timer frequency"));
+ if (virXMLPropULongLong(node, "frequency", 10,
+ VIR_XML_PROP_NONE,
+ &def->frequency) < 0)
goto error;
- }
- mode = virXMLPropString(node, "mode");
- if (mode != NULL) {
- if ((def->mode = virDomainTimerModeTypeFromString(mode)) <= 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("unknown timer mode '%s'"), mode);
- goto error;
- }
- }
+ if (virXMLPropEnum(node, "mode",
+ virDomainTimerModeTypeFromString,
+ VIR_XML_PROP_NONZERO,
+ &def->mode) < 0)
+ goto error;
catchup = virXPathNode("./catchup", ctxt);
if (catchup != NULL) {
- ret = virXPathULong("string(./catchup/@threshold)", ctxt,
- &def->catchup.threshold);
- if (ret == -1) {
- def->catchup.threshold = 0;
- } else if (ret < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("invalid catchup threshold"));
+ if (virXMLPropUInt(catchup, "threshold", 10,
+ VIR_XML_PROP_NONE,
+ &def->catchup.threshold) < 0)
goto error;
- }
- ret = virXPathULong("string(./catchup/@slew)", ctxt, &def->catchup.slew);
- if (ret == -1) {
- def->catchup.slew = 0;
- } else if (ret < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("invalid catchup slew"));
+ if (virXMLPropUInt(catchup, "slew", 10,
+ VIR_XML_PROP_NONE,
+ &def->catchup.slew) < 0)
goto error;
- }
- ret = virXPathULong("string(./catchup/@limit)", ctxt, &def->catchup.limit);
- if (ret == -1) {
- def->catchup.limit = 0;
- } else if (ret < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("invalid catchup limit"));
+ if (virXMLPropUInt(catchup, "limit", 10,
+ VIR_XML_PROP_NONE,
+ &def->catchup.limit) < 0)
goto error;
- }
}
return def;
@@ -26197,11 +26160,11 @@ virDomainTimerDefFormat(virBuffer *buf,
}
if (def->catchup.threshold > 0)
- virBufferAsprintf(&catchupAttr, " threshold='%lu'", def->catchup.threshold);
+ virBufferAsprintf(&catchupAttr, " threshold='%u'", def->catchup.threshold);
if (def->catchup.slew > 0)
- virBufferAsprintf(&catchupAttr, " slew='%lu'", def->catchup.slew);
+ virBufferAsprintf(&catchupAttr, " slew='%u'", def->catchup.slew);
if (def->catchup.limit > 0)
- virBufferAsprintf(&catchupAttr, " limit='%lu'", def->catchup.limit);
+ virBufferAsprintf(&catchupAttr, " limit='%u'", def->catchup.limit);
virXMLFormatElement(&timerChld, "catchup", &catchupAttr, NULL);
virXMLFormatElement(buf, "timer", &timerAttr, &timerChld);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index cad19a3d5d..a6acffb4a4 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2442,24 +2442,24 @@ struct _virDomainThreadSchedParam {
};
struct _virDomainTimerCatchupDef {
- unsigned long threshold;
- unsigned long slew;
- unsigned long limit;
+ unsigned int threshold;
+ unsigned int slew;
+ unsigned int limit;
};
struct _virDomainTimerDef {
- int name;
+ virDomainTimerNameType name;
virTristateBool present;
- int tickpolicy; /* enum virDomainTimerTickpolicyType */
+ virDomainTimerTickpolicyType tickpolicy;
virDomainTimerCatchupDef catchup;
/* track is only valid for name='platform|rtc' */
- int track; /* enum virDomainTimerTrackType */
+ virDomainTimerTrackType track;
/* frequency & mode are only valid for name='tsc' */
unsigned long long frequency; /* in Hz, unspecified = 0 */
- int mode; /* enum virDomainTimerModeType */
+ virDomainTimerModeType mode;
};
typedef enum {
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 82af406e2d..6aba458281 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -406,7 +406,7 @@ libxlMakeDomBuildInfo(virDomainDef *def,
}
for (i = 0; i < clock.ntimers; i++) {
- switch ((virDomainTimerNameType) clock.timers[i]->name) {
+ switch (clock.timers[i]->name) {
case VIR_DOMAIN_TIMER_NAME_TSC:
switch (clock.timers[i]->mode) {
case VIR_DOMAIN_TIMER_MODE_NATIVE:
@@ -418,6 +418,10 @@ libxlMakeDomBuildInfo(virDomainDef *def,
case VIR_DOMAIN_TIMER_MODE_EMULATE:
b_info->tsc_mode = LIBXL_TSC_MODE_ALWAYS_EMULATE;
break;
+ case VIR_DOMAIN_TIMER_MODE_NONE:
+ case VIR_DOMAIN_TIMER_MODE_AUTO:
+ case VIR_DOMAIN_TIMER_MODE_SMPSAFE:
+ case VIR_DOMAIN_TIMER_MODE_LAST:
default:
b_info->tsc_mode = LIBXL_TSC_MODE_DEFAULT;
}
diff --git a/src/libxl/xen_common.c b/src/libxl/xen_common.c
index 6487cb63df..f8c63d5f92 100644
--- a/src/libxl/xen_common.c
+++ b/src/libxl/xen_common.c
@@ -2106,7 +2106,7 @@ xenFormatHypervisorFeatures(virConf *conf, virDomainDef *def)
}
for (i = 0; i < def->clock.ntimers; i++) {
- switch ((virDomainTimerNameType)def->clock.timers[i]->name) {
+ switch (def->clock.timers[i]->name) {
case VIR_DOMAIN_TIMER_NAME_TSC:
switch (def->clock.timers[i]->mode) {
case VIR_DOMAIN_TIMER_MODE_NATIVE:
@@ -2121,6 +2121,10 @@ xenFormatHypervisorFeatures(virConf *conf, virDomainDef *def)
if (xenConfigSetString(conf, "tsc_mode", "always_emulate") < 0)
return -1;
break;
+ case VIR_DOMAIN_TIMER_MODE_NONE:
+ case VIR_DOMAIN_TIMER_MODE_AUTO:
+ case VIR_DOMAIN_TIMER_MODE_SMPSAFE:
+ case VIR_DOMAIN_TIMER_MODE_LAST:
default:
if (xenConfigSetString(conf, "tsc_mode", "default") < 0)
return -1;
diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index d31fff5f98..420ec07650 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -335,7 +335,7 @@ static int virLXCCgroupSetupDeviceACL(virDomainDef *def,
if (timer->present == VIR_TRISTATE_BOOL_NO)
continue;
- switch ((virDomainTimerNameType)timer->name) {
+ switch (timer->name) {
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
case VIR_DOMAIN_TIMER_NAME_TSC:
case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index d936f34793..42356eb1c9 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -1506,7 +1506,7 @@ virLXCControllerSetupTimers(virLXCController *ctrl)
if (timer->present == VIR_TRISTATE_BOOL_NO)
continue;
- switch ((virDomainTimerNameType)timer->name) {
+ switch (timer->name) {
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
case VIR_DOMAIN_TIMER_NAME_TSC:
case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index b863fd1c32..6574c4c58b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6200,6 +6200,8 @@ qemuBuildClockArgStr(virDomainClockDef *def)
case VIR_DOMAIN_TIMER_TRACK_REALTIME:
virBufferAddLit(&buf, ",clock=rt");
break;
+ case VIR_DOMAIN_TIMER_TRACK_LAST:
+ break;
}
switch (def->timers[i]->tickpolicy) {
@@ -6215,6 +6217,8 @@ qemuBuildClockArgStr(virDomainClockDef *def)
case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
case VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD:
return NULL;
+ case VIR_DOMAIN_TIMER_TICKPOLICY_LAST:
+ break;
}
break; /* no need to check other timers - there is only one rtc */
}
@@ -6246,7 +6250,7 @@ qemuBuildClockCommandLine(virCommand *cmd,
}
for (i = 0; i < def->clock.ntimers; i++) {
- switch ((virDomainTimerNameType)def->clock.timers[i]->name) {
+ switch (def->clock.timers[i]->name) {
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
/* qemuDomainDefValidateClockTimers will handle this
* error condition */
@@ -6286,6 +6290,8 @@ qemuBuildClockCommandLine(virCommand *cmd,
case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
/* no way to support this mode for pit in qemu */
return -1;
+ case VIR_DOMAIN_TIMER_TICKPOLICY_LAST:
+ return -1;
}
break;
@@ -6640,7 +6646,7 @@ qemuBuildCpuCommandLine(virCommand *cmd,
for (i = 0; i < def->clock.ntimers; i++) {
virDomainTimerDef *timer = def->clock.timers[i];
- switch ((virDomainTimerNameType)timer->name) {
+ switch (timer->name) {
case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
if (timer->present != VIR_TRISTATE_BOOL_ABSENT) {
/* QEMU expects on/off -> virTristateSwitch. */
@@ -6667,6 +6673,7 @@ qemuBuildCpuCommandLine(virCommand *cmd,
case VIR_DOMAIN_TIMER_TICKPOLICY_NONE:
case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
+ case VIR_DOMAIN_TIMER_TICKPOLICY_LAST:
break;
}
break;
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index f54b4587c0..a48b81c9c6 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -393,7 +393,7 @@ qemuValidateDomainDefClockTimers(const virDomainDef *def,
for (i = 0; i < def->clock.ntimers; i++) {
virDomainTimerDef *timer = def->clock.timers[i];
- switch ((virDomainTimerNameType)timer->name) {
+ switch (timer->name) {
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported timer type (name) '%s'"),
@@ -426,6 +426,7 @@ qemuValidateDomainDefClockTimers(const virDomainDef *def,
case VIR_DOMAIN_TIMER_TRACK_REALTIME:
break;
case VIR_DOMAIN_TIMER_TRACK_BOOT:
+ case VIR_DOMAIN_TIMER_TRACK_LAST:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported rtc timer track '%s'"),
virDomainTimerTrackTypeToString(timer->track));
@@ -443,6 +444,7 @@ qemuValidateDomainDefClockTimers(const virDomainDef *def,
break;
case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
case VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD:
+ case VIR_DOMAIN_TIMER_TICKPOLICY_LAST:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported rtc timer tickpolicy '%s'"),
virDomainTimerTickpolicyTypeToString(
@@ -474,6 +476,8 @@ qemuValidateDomainDefClockTimers(const virDomainDef *def,
virDomainTimerTickpolicyTypeToString(
timer->tickpolicy));
return -1;
+ case VIR_DOMAIN_TIMER_TICKPOLICY_LAST:
+ break;
}
break;
@@ -526,6 +530,8 @@ qemuValidateDomainDefClockTimers(const virDomainDef *def,
virDomainTimerNameTypeToString(timer->name),
virDomainTimerTickpolicyTypeToString(timer->tickpolicy));
return -1;
+ case VIR_DOMAIN_TIMER_TICKPOLICY_LAST:
+ break;
}
break;
}
--
2.35.1
On 5/23/22 3:08 PM, Michal Privoznik wrote:
> The virDomainTimerDefParseXML() function uses old style of
> parsing XML (virXMLPropString + str2enum conversion). Use
> virXMLPropEnumDefault() which encapsulates those steps.
virXMLPropEnum, virXMLPropULongLong and virXMLPropUInt ...
>
> Signed-off-by: Michal Privoznik<mprivozn@redhat.com>
> ---
> src/conf/domain_conf.c | 105 +++++++++++++--------------------------
> src/conf/domain_conf.h | 14 +++---
> src/libxl/libxl_conf.c | 6 ++-
> src/libxl/xen_common.c | 6 ++-
> src/lxc/lxc_cgroup.c | 2 +-
> src/lxc/lxc_controller.c | 2 +-
> src/qemu/qemu_command.c | 11 +++-
> src/qemu/qemu_validate.c | 8 ++-
> 8 files changed, 69 insertions(+), 85 deletions(-)
--
Mit freundlichen Grüßen/Kind regards
Boris Fiuczynski
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Gregor Pillen
Geschäftsführung: David Faller
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
On 5/23/22 3:08 PM, Michal Privoznik wrote:
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 52a34cd131..27fe6c9fbf 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -11962,98 +11962,61 @@ virDomainTimerDefParseXML(xmlNodePtr node,
> virDomainTimerDef *def;
> VIR_XPATH_NODE_AUTORESTORE(ctxt)
> xmlNodePtr catchup;
> - int ret;
> - g_autofree char *name = NULL;
> - g_autofree char *tickpolicy = NULL;
> - g_autofree char *track = NULL;
> - g_autofree char *mode = NULL;
>
> def = g_new0(virDomainTimerDef, 1);
>
> ctxt->node = node;
>
> - name = virXMLPropString(node, "name");
> - if (name == NULL) {
> - virReportError(VIR_ERR_INTERNAL_ERROR,
> - "%s", _("missing timer name"));
> + if (virXMLPropEnum(node, "name",
> + virDomainTimerNameTypeFromString,
> + VIR_XML_PROP_REQUIRED,
> + &def->name) < 0)
> goto error;
> - }
> - if ((def->name = virDomainTimerNameTypeFromString(name)) < 0) {
> - virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> - _("unknown timer name '%s'"), name);
> - goto error;
> - }
>
> if (virXMLPropTristateBool(node, "present",
> VIR_XML_PROP_NONE,
> &def->present) < 0)
> goto error;
>
> - tickpolicy = virXMLPropString(node, "tickpolicy");
> - if (tickpolicy != NULL) {
> - if ((def->tickpolicy = virDomainTimerTickpolicyTypeFromString(tickpolicy)) <= 0) {
> - virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> - _("unknown timer tickpolicy '%s'"), tickpolicy);
> - goto error;
> - }
> - }
> + if (virXMLPropEnum(node, "tickpolicy",
> + virDomainTimerTickpolicyTypeFromString,
> + VIR_XML_PROP_NONZERO,
> + &def->tickpolicy) < 0)
> + goto error;
>
> - track = virXMLPropString(node, "track");
> - if (track != NULL) {
> - if ((def->track = virDomainTimerTrackTypeFromString(track)) <= 0) {
> - virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> - _("unknown timer track '%s'"), track);
> - goto error;
> - }
> - }
> + if (virXMLPropEnum(node, "track",
> + virDomainTimerTrackTypeFromString,
> + VIR_XML_PROP_NONZERO,
> + &def->track) < 0)
> + goto error;
>
> - ret = virXPathULongLong("string(./@frequency)", ctxt, &def->frequency);
> - if (ret == -1) {
> - def->frequency = 0;
Is the above case covered in virXMLPropULongLong?
A few other cases like following below.
> - } else if (ret < 0) {
> - virReportError(VIR_ERR_INTERNAL_ERROR,
> - "%s", _("invalid timer frequency"));
> + if (virXMLPropULongLong(node, "frequency", 10,
> + VIR_XML_PROP_NONE,
> + &def->frequency) < 0)
> goto error;
> - }
>
> - mode = virXMLPropString(node, "mode");
> - if (mode != NULL) {
> - if ((def->mode = virDomainTimerModeTypeFromString(mode)) <= 0) {
> - virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> - _("unknown timer mode '%s'"), mode);
> - goto error;
> - }
> - }
> + if (virXMLPropEnum(node, "mode",
> + virDomainTimerModeTypeFromString,
> + VIR_XML_PROP_NONZERO,
> + &def->mode) < 0)
> + goto error;
>
> catchup = virXPathNode("./catchup", ctxt);
> if (catchup != NULL) {
> - ret = virXPathULong("string(./catchup/@threshold)", ctxt,
> - &def->catchup.threshold);
> - if (ret == -1) {
> - def->catchup.threshold = 0;
> - } else if (ret < 0) {
> - virReportError(VIR_ERR_INTERNAL_ERROR,
> - "%s", _("invalid catchup threshold"));
> + if (virXMLPropUInt(catchup, "threshold", 10,
> + VIR_XML_PROP_NONE,
> + &def->catchup.threshold) < 0)
> goto error;
> - }
>
> - ret = virXPathULong("string(./catchup/@slew)", ctxt, &def->catchup.slew);
> - if (ret == -1) {
> - def->catchup.slew = 0;
> - } else if (ret < 0) {
> - virReportError(VIR_ERR_INTERNAL_ERROR,
> - "%s", _("invalid catchup slew"));
> + if (virXMLPropUInt(catchup, "slew", 10,
> + VIR_XML_PROP_NONE,
> + &def->catchup.slew) < 0)
> goto error;
> - }
>
> - ret = virXPathULong("string(./catchup/@limit)", ctxt, &def->catchup.limit);
> - if (ret == -1) {
> - def->catchup.limit = 0;
> - } else if (ret < 0) {
> - virReportError(VIR_ERR_INTERNAL_ERROR,
> - "%s", _("invalid catchup limit"));
> + if (virXMLPropUInt(catchup, "limit", 10,
> + VIR_XML_PROP_NONE,
> + &def->catchup.limit) < 0)
> goto error;
> - }
> }
>
> return def;
> @@ -26197,11 +26160,11 @@ virDomainTimerDefFormat(virBuffer *buf,
> }
>
> if (def->catchup.threshold > 0)
> - virBufferAsprintf(&catchupAttr, " threshold='%lu'", def->catchup.threshold);
> + virBufferAsprintf(&catchupAttr, " threshold='%u'", def->catchup.threshold);
> if (def->catchup.slew > 0)
> - virBufferAsprintf(&catchupAttr, " slew='%lu'", def->catchup.slew);
> + virBufferAsprintf(&catchupAttr, " slew='%u'", def->catchup.slew);
> if (def->catchup.limit > 0)
> - virBufferAsprintf(&catchupAttr, " limit='%lu'", def->catchup.limit);
> + virBufferAsprintf(&catchupAttr, " limit='%u'", def->catchup.limit);
>
> virXMLFormatElement(&timerChld, "catchup", &catchupAttr, NULL);
> virXMLFormatElement(buf, "timer", &timerAttr, &timerChld);
--
Mit freundlichen Grüßen/Kind regards
Boris Fiuczynski
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Gregor Pillen
Geschäftsführung: David Faller
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
© 2016 - 2026 Red Hat, Inc.