From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:52498) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S6Ldd-0007kn-7e for qemu-devel@nongnu.org; Sat, 10 Mar 2012 07:43:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S6LdZ-0004rU-Gi for qemu-devel@nongnu.org; Sat, 10 Mar 2012 07:43:08 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55466) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S6LdZ-0004rG-4v for qemu-devel@nongnu.org; Sat, 10 Mar 2012 07:43:05 -0500 Date: Sat, 10 Mar 2012 12:42:46 +0000 From: "Daniel P. Berrange" Message-ID: <20120310124246.GA4408@redhat.com> References: <20111218095816.GG21664@redhat.com> <20120309205652.GA6807@otherpad.lan.raisama.net> <20120309210403.GA2319@redhat.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="xHFwDpU9dbj6ez1V" Content-Disposition: inline In-Reply-To: <20120309210403.GA2319@redhat.com> Subject: Re: [Qemu-devel] [libvirt] Modern CPU models cannot be used with libvirt Reply-To: "Daniel P. Berrange" List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: libvir-list@redhat.com, qemu-devel@nongnu.org, Gleb Natapov , Anthony Liguori , Jiri Denemark , Avi Kivity --xHFwDpU9dbj6ez1V Content-Type: text/plain; charset=utf-8 Content-Disposition: inline On Fri, Mar 09, 2012 at 09:04:03PM +0000, Daniel P. Berrange wrote: > On Fri, Mar 09, 2012 at 05:56:52PM -0300, Eduardo Habkost wrote: > > Resurrecting an old thread: > > > > I didn't see any clear conclusion in this thread (this is why I am > > resurrecting it), except that many were arguing that libvirt should > > simply copy and/or generate the CPU model definitions from Qemu. I > > really don't think it's reasonable to expect that. > > > > On Thu, Dec 15, 2011 at 03:54:15PM +0100, Jiri Denemark wrote: > > > Hi, > > > > > > Recently I realized that all modern CPU models defined in > > > /etc/qemu/target-x86_64.conf are useless when qemu is used through libvirt. > > > That's because we start qemu with -nodefconfig which results in qemu ignoring > > > that file with CPU model definitions. We have a very good reason for using > > > -nodefconfig because we need to control the ABI presented to a guest OS and we > > > don't want any configuration file that can contain lots of things including > > > device definitions to be read by qemu. However, we would really like the new > > > CPU models to be understood by qemu even if used through libvirt. What would > > > be the best way to solve this? > > > > > > I suspect this could have been already discussed in the past but obviously a > > > workable solution was either not found or just not implemented. > > > > So, our problem today is basically: > > > > A) libvirt uses -nodefconfig; > > B) -nodefconfig makes Qemu not load the config file containing the CPU > > model definitions; and > > C) libvirt expects the full CPU model list from Qemu to be available. > > I could have sworn we had this discussion a year ago or so, and had decided > that the default CPU models would be in something like /usr/share/qemu/cpu-x86_64.conf > and loaded regardless of the -nodefconfig setting. /etc/qemu/target-x86_64.conf > would be solely for end user configuration changes, not for QEMU builtin > defaults. > > But looking at the code in QEMU, it doesn't seem we ever implemented this ? Arrrgggh. It seems this was implemented as a patch in RHEL-6 qemu RPMs but, contrary to our normal RHEL development practice, it was not based on a cherry-pick of an upstream patch :-( For sake of reference, I'm attaching the two patches from the RHEL6 source RPM that do what I'm describing NB, I'm not neccessarily advocating these patches for upstream. I still maintain that libvirt should write out a config file containing the exact CPU model description it desires and specify that with -readconfig. The end result would be identical from QEMU's POV and it would avoid playing games with QEMU's config loading code. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| --xHFwDpU9dbj6ez1V Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename="kvm-Move-CPU-definitions-to-usr-share-.-BZ-610805.patch" >>From ab8e4c035638685f1e579ce472dd8b4c957f8097 Mon Sep 17 00:00:00 2001 From: john cooper Date: Thu, 8 Jul 2010 04:17:13 -0300 Subject: [PATCH 1/3] Move CPU definitions to /usr/share/... BZ #610805 RH-Author: john cooper Message-id: <4C355149.2050800@redhat.com> Patchwork-id: 10557 O-Subject: [RHEL6 PATCH] Move CPU definitions to /usr/share/... BZ #610805 Bugzilla: 610805 RH-Acked-by: Markus Armbruster RH-Acked-by: Jes Sorensen RH-Acked-by: Juan Quintela Description: libvirt requested the cpu model configuration file be relocated to /usr/share to more clearly signify it was not to be modified by users. In addition the model file is now loaded even in the presence of the "-nodefconfig" command line flag. Note this is intended as an interim work-around for rhel6.0. While the new location of the config file should remain the same, the mechanism to direct qemu to it will likely differ going forward. Minor Caveat: Although the model definitions have moved from /etc/qemu/target-x86_64.conf to /usr/share/qemu-kvm/cpu-model/cpu-x86_64.conf an open of the former default config file is still attempted by qemu. In a new installation of the rpm this is a non-issue as well as when "-nodefconfig" is specified. However if the former config file exists, and is allowed to be read, and and contains model definitions conflicting with those in cpu-x86_64.conf, they will override those from the new config file. This realistically is only an issue for development testing and may be detected by "-readconfig ?" which will indicate when the old file had been found or "-cpu ?" which will display replicated model definitions. Verification: # /usr/libexec/qemu-kvm -nodefconfig -readconfig ? -cpu ? parsed config file /usr/share/qemu-kvm/cpu-model/cpu-x86_64.conf x86 Opteron_G3 x86 Opteron_G2 x86 Opteron_G1 x86 Nehalem x86 Penryn x86 Conroe x86 [n270] x86 [athlon] x86 [pentium3] x86 [pentium2] x86 [pentium] x86 [486] x86 [coreduo] x86 [qemu32] x86 [kvm64] x86 [core2duo] x86 [phenom] x86 [qemu64] Brew build: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=2581001 Signed-off-by: john cooper --- Move cpu model config to /usr/share/qemu-kvm/cpu-model. Enforce loading at startup. Add cpu model config path to specfile. Signed-off-by: Eduardo Habkost --- Makefile | 8 ++-- configure | 9 ++++ sysconfigs/target/cpu-x86_64.conf | 85 ++++++++++++++++++++++++++++++++++ sysconfigs/target/target-x86_64.conf | 85 ---------------------------------- vl.c | 7 +++ 6 files changed, 109 insertions(+), 90 deletions(-) create mode 100644 sysconfigs/target/cpu-x86_64.conf delete mode 100644 sysconfigs/target/target-x86_64.conf diff --git a/Makefile b/Makefile index c1dadd0..d147632 100644 --- a/Makefile +++ b/Makefile @@ -319,11 +319,11 @@ ifdef CONFIG_POSIX $(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8" endif -install-sysconfig: - $(INSTALL_DIR) "$(sysconfdir)/qemu" - $(INSTALL_DATA) sysconfigs/target/target-x86_64.conf "$(sysconfdir)/qemu" +install-cpuconfig: + $(INSTALL_DIR) "$(DESTDIR)$(cpuconfdir)" + $(INSTALL_DATA) sysconfigs/target/cpu-x86_64.conf "$(DESTDIR)$(cpuconfdir)" -install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig +install: all $(if $(BUILD_DOCS),install-doc) install-cpuconfig $(INSTALL_DIR) "$(DESTDIR)$(bindir)" ifneq ($(TOOLS),) $(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) "$(DESTDIR)$(bindir)" diff --git a/configure b/configure index 9e62b0d..be78a0c 100755 --- a/configure +++ b/configure @@ -33,6 +33,7 @@ prefix="" interp_prefix="/usr/gnemul/qemu-%M" static="no" sysconfdir="" +cpuconfdir="" sparc_cpu="" cross_prefix="" cc="gcc" @@ -480,6 +481,8 @@ for opt do ;; --sysconfdir=*) sysconfdir="$optarg" ;; + --cpuconfdir=*) cpuconfdir="$optarg" + ;; --disable-sdl) sdl="no" ;; --enable-sdl) sdl="yes" @@ -739,6 +742,7 @@ echo " --make=MAKE use specified make [$make]" echo " --install=INSTALL use specified install [$install]" echo " --static enable static build [$static]" echo " --sysconfdir=PATH install config in PATH" +echo " --cpuconfdir=PATH install cpu model config in PATH" echo " --enable-debug-tcg enable TCG debugging" echo " --disable-debug-tcg disable TCG debugging (default)" echo " --enable-debug enable common debug build options" @@ -2058,6 +2062,9 @@ else if test -z "$sysconfdir" ; then sysconfdir="${prefix}/etc" fi + if test -z "$cpuconfdir" ; then + cpuconfdir="$sysconfdir/qemu" + fi fi if test -f kvm/kernel/configure; then @@ -2159,6 +2166,7 @@ if test "$mingw32" = "yes" ; then echo "CONFIG_QEMU_CONFDIR=\"$sysconfdir\"" >> $config_host_mak else echo "CONFIG_QEMU_CONFDIR=\"${sysconfdir}/qemu\"" >> $config_host_mak + echo "CONFIG_QEMU_CPUCONFDIR=\"${cpuconfdir}\"" >> $config_host_mak fi case "$cpu" in @@ -2426,6 +2434,7 @@ echo "bindir=\${prefix}$binsuffix" >> $config_host_mak echo "mandir=\${prefix}$mansuffix" >> $config_host_mak echo "datadir=\${prefix}$datasuffix" >> $config_host_mak echo "sysconfdir=$sysconfdir" >> $config_host_mak +echo "cpuconfdir=$cpuconfdir" >> $config_host_mak echo "docdir=\${prefix}$docsuffix" >> $config_host_mak echo "MAKE=$make" >> $config_host_mak echo "INSTALL=$install" >> $config_host_mak diff --git a/sysconfigs/target/cpu-x86_64.conf b/sysconfigs/target/cpu-x86_64.conf new file mode 100644 index 0000000..ca07088 --- /dev/null +++ b/sysconfigs/target/cpu-x86_64.conf @@ -0,0 +1,85 @@ +# x86 CPU MODELS + +[cpudef] + name = "Conroe" + level = "2" + vendor = "GenuineIntel" + family = "6" + model = "2" + stepping = "3" + feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36" + feature_ecx = "sse3 ssse3 x2apic" + extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx" + extfeature_ecx = "lahf_lm" + xlevel = "0x8000000A" + model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)" + +[cpudef] + name = "Penryn" + level = "2" + vendor = "GenuineIntel" + family = "6" + model = "2" + stepping = "3" + feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36" + feature_ecx = "sse3 cx16 ssse3 sse4.1 x2apic" + extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx" + extfeature_ecx = "lahf_lm" + xlevel = "0x8000000A" + model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)" + +[cpudef] + name = "Nehalem" + level = "2" + vendor = "GenuineIntel" + family = "6" + model = "2" + stepping = "3" + feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36" + feature_ecx = "sse3 cx16 ssse3 sse4.1 sse4.2 x2apic popcnt" + extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx" + extfeature_ecx = "lahf_lm" + xlevel = "0x8000000A" + model_id = "Intel Core i7 9xx (Nehalem Class Core i7)" + +[cpudef] + name = "Opteron_G1" + level = "5" + vendor = "AuthenticAMD" + family = "15" + model = "6" + stepping = "1" + feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36" + feature_ecx = "sse3" + extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx" +# extfeature_ecx = "" + xlevel = "0x80000008" + model_id = "AMD Opteron 240 (Gen 1 Class Opteron)" + +[cpudef] + name = "Opteron_G2" + level = "5" + vendor = "AuthenticAMD" + family = "15" + model = "6" + stepping = "1" + feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36" + feature_ecx = "sse3 cx16" + extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx rdtscp" + extfeature_ecx = "svm lahf_lm" + xlevel = "0x80000008" + model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)" + +[cpudef] + name = "Opteron_G3" + level = "5" + vendor = "AuthenticAMD" + family = "15" + model = "6" + stepping = "1" + feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36" + feature_ecx = "sse3 cx16 monitor popcnt" + extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx rdtscp" + extfeature_ecx = "svm sse4a abm misalignsse lahf_lm" + xlevel = "0x80000008" + model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)" diff --git a/sysconfigs/target/target-x86_64.conf b/sysconfigs/target/target-x86_64.conf deleted file mode 100644 index ca07088..0000000 --- a/sysconfigs/target/target-x86_64.conf +++ /dev/null @@ -1,85 +0,0 @@ -# x86 CPU MODELS - -[cpudef] - name = "Conroe" - level = "2" - vendor = "GenuineIntel" - family = "6" - model = "2" - stepping = "3" - feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36" - feature_ecx = "sse3 ssse3 x2apic" - extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx" - extfeature_ecx = "lahf_lm" - xlevel = "0x8000000A" - model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)" - -[cpudef] - name = "Penryn" - level = "2" - vendor = "GenuineIntel" - family = "6" - model = "2" - stepping = "3" - feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36" - feature_ecx = "sse3 cx16 ssse3 sse4.1 x2apic" - extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx" - extfeature_ecx = "lahf_lm" - xlevel = "0x8000000A" - model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)" - -[cpudef] - name = "Nehalem" - level = "2" - vendor = "GenuineIntel" - family = "6" - model = "2" - stepping = "3" - feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36" - feature_ecx = "sse3 cx16 ssse3 sse4.1 sse4.2 x2apic popcnt" - extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx" - extfeature_ecx = "lahf_lm" - xlevel = "0x8000000A" - model_id = "Intel Core i7 9xx (Nehalem Class Core i7)" - -[cpudef] - name = "Opteron_G1" - level = "5" - vendor = "AuthenticAMD" - family = "15" - model = "6" - stepping = "1" - feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36" - feature_ecx = "sse3" - extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx" -# extfeature_ecx = "" - xlevel = "0x80000008" - model_id = "AMD Opteron 240 (Gen 1 Class Opteron)" - -[cpudef] - name = "Opteron_G2" - level = "5" - vendor = "AuthenticAMD" - family = "15" - model = "6" - stepping = "1" - feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36" - feature_ecx = "sse3 cx16" - extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx rdtscp" - extfeature_ecx = "svm lahf_lm" - xlevel = "0x80000008" - model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)" - -[cpudef] - name = "Opteron_G3" - level = "5" - vendor = "AuthenticAMD" - family = "15" - model = "6" - stepping = "1" - feature_edx = "sse2 sse fxsr mmx pat cmov pge sep apic cx8 mce pae msr tsc pse de fpu mtrr clflush mca pse36" - feature_ecx = "sse3 cx16 monitor popcnt" - extfeature_edx = "fxsr mmx pat cmov pge apic cx8 mce pae msr tsc pse de fpu lm syscall nx rdtscp" - extfeature_ecx = "svm sse4a abm misalignsse lahf_lm" - xlevel = "0x80000008" - model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)" diff --git a/vl.c b/vl.c index a3b682d..eb993d6 100644 --- a/vl.c +++ b/vl.c @@ -5141,6 +5141,13 @@ int main(int argc, char **argv, char **envp) } } + /* load local cpu config, NB: may possibly be overridden by defconfigs + */ + if (qemu_read_config_file( + CONFIG_QEMU_CPUCONFDIR "/cpu-" TARGET_ARCH ".conf", + defconfig_verbose) == -EINVAL) { + exit(1); + } if (defconfig) { int ret; -- 1.7.0.3 --xHFwDpU9dbj6ez1V Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename="kvm-Bug-625333-qemu-treatment-of-nodefconfig-and-readcon.patch" >>From 4eb647d7081b3090ba949a129756f7f7a42abf5a Mon Sep 17 00:00:00 2001 From: john cooper Date: Sat, 11 Dec 2010 04:30:10 -0200 Subject: [PATCH 01/24] Bug #625333 - qemu treatment of -nodefconfig and -readconfig problematic for debug RH-Author: john cooper Message-id: <4D02FE52.7050405@redhat.com> Patchwork-id: 14538 O-Subject: [RHEL6.1 PATCH v3] Bug #625333 - qemu treatment of -nodefconfig and -readconfig problematic for debug Bugzilla: 625333 RH-Acked-by: Amit Shah RH-Acked-by: Marcelo Tosatti RH-Acked-by: Alex Williamson The prior version of this patch had the side effect of allowing a -readconfig specified config file to be overridden by a wired-in default config file. Although this scenario would not occur in the context of a libvirt launch, altering semantics relative to upstream qemu is best avoided. Details: The problem is qemu currently has only two discrete scans of CLI arguments. Trying to live within that structure while supporting flags which affect other flags is problematic. Qemu attempts to implement flag semantics simultaneous with their parsing. As such semantic actions follow the unpredictable sequence of args appearing on the command like. This patch therefore enforces consistent ordering of the following semantics as: - interpret config file parse modifiers - conditionally read default qemu configs - read local cpu config - read any -readconfig configs - interpret all other options Testing: - The config file processing order above should be in effect. Specifically an identical data item in a later config file should redefine the same introduced by a prior config file. - Default and local config files may or may not exist on the host. If they do not exist, they are quietly ignored unless verbose handling by "-readconfig ?" is specified. However if any do exist and contain config file format errors, qemu will error exit. - Handling of config files specified by "-readconfig " is the same as default/local config files with the addition qemu will error exit if cannot be opened for read. - any sequence of "-readconfig" | "-nodefconfig" | "-cpu" has the same effect irrespective of relative location in the command line Upstream Status: This patch has seen modification in the process of trying to push it upstream, which resulted in minor syntax changes to the CLI. We will need to accommodate this when we rebase qemu. Signed-off-by: john cooper --- Signed-off-by: Luiz Capitulino --- vl.c | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 38 insertions(+), 13 deletions(-) diff --git a/vl.c b/vl.c index 734a5b2..cac6921 100644 --- a/vl.c +++ b/vl.c @@ -5325,7 +5325,8 @@ int main(int argc, char **argv, char **envp) tb_size = 0; autostart= 1; - /* first pass of option parsing */ + /* first pass of CLI options -- interpret config file parse modifiers + */ optind = 1; while (optind < argc) { if (argv[optind][0] != '-') { @@ -5349,13 +5350,8 @@ int main(int argc, char **argv, char **envp) } } - /* load local cpu config, NB: may possibly be overridden by defconfigs + /* pull in default configs unless explicitly disabled */ - if (qemu_read_config_file( - CONFIG_QEMU_CPUCONFDIR "/cpu-" TARGET_ARCH ".conf", - defconfig_verbose) == -EINVAL) { - exit(1); - } if (defconfig) { int ret; @@ -5372,11 +5368,45 @@ int main(int argc, char **argv, char **envp) exit(1); } } + + /* load local cpu config + */ + if (qemu_read_config_file( + CONFIG_QEMU_CPUCONFDIR "/cpu-" TARGET_ARCH ".conf", + defconfig_verbose) == -EINVAL) { + exit(1); + } + + /* second pass of CLI options -- bring in any -readconfig flags + */ + optind = 1; + while (optind < argc) { + if (argv[optind][0] != '-') { + /* disk image */ + optind++; + continue; + } else { + const QEMUOption *popt; + + popt = lookup_opt(argc, argv, &optarg, &optind); + switch (popt->index) { + case QEMU_OPTION_readconfig: + /* pull in cli specified config files in advance of general + * flag parsing which may reference their content + */ + if (strcmp(optarg, "?") && + qemu_read_config_file(optarg, defconfig_verbose) < 0) + exit(1); + break; + } + } + } #if defined(cpudef_setup) cpudef_setup(); /* parse cpu definitions in target config file */ #endif - /* second pass of option parsing */ + /* third pass of CLI options -- general flag interpretation + */ optind = 1; for(;;) { if (optind >= argc) @@ -6084,11 +6114,6 @@ int main(int argc, char **argv, char **envp) xen_mode = XEN_ATTACH; break; #endif - case QEMU_OPTION_readconfig: - if (!!strcmp(optarg, "?") && - qemu_read_config_file(optarg, defconfig_verbose) < 0) - exit(1); - break; case QEMU_OPTION_spice: olist = qemu_find_opts("spice"); if (!olist) { -- 1.7.4.rc1.16.gd2f15e --xHFwDpU9dbj6ez1V--