[PATCH 1/4] qemu: Generate shorter channel target paths

Michal Privoznik posted 4 patches 2 years, 7 months ago
There is a newer version of this series
[PATCH 1/4] qemu: Generate shorter channel target paths
Posted by Michal Privoznik 2 years, 7 months ago
A <channel/> device is basically an UNIX socket into guest.
Whatever is sent from the host, appears in the guest and vice
versa. But because of that, the length of the path to the socket
is important (underscored by fact that we derive the path from
domain short name). But there are still cases where we might not
fit into UNIX_PATH_MAX limit (usually 108 characters), because
the path is derived also from other variables, e.g.
XDG_CONFIG_HOME for session domains.

There is one component though, that's needless: "/target/". Drop
it. This is safe to do, because running domains have their path
saved in status XML and even though paths are dropped on
migration, they are not part of guest ABI and thus we are free to
change them.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
 libvirt.spec.in                                          | 1 -
 src/qemu/qemu_conf.c                                     | 6 +++---
 src/qemu/qemu_domain.c                                   | 9 ++++++---
 .../qemuhotplug-qemu-agent-detach.xml                    | 2 +-
 .../qemuhotplug-base-live+qemu-agent-detach.xml          | 2 +-
 .../qemuhotplug-base-live+qemu-agent.xml                 | 2 +-
 tests/qemuxml2argvdata/channel-unix-source-path.xml      | 4 ++++
 .../channel-unix-source-path-active.xml                  | 5 +++++
 .../channel-unix-source-path-inactive.xml                | 4 ++++
 9 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/libvirt.spec.in b/libvirt.spec.in
index 1f77cd90b7..8aee709e42 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -2125,7 +2125,6 @@ exit 0
 %ghost %dir %{_rundir}/libvirt/qemu/swtpm/
 %dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
 %dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/
-%dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/
 %dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/checkpoint/
 %dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/dump/
 %dir %attr(0751, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index bd984448a3..532fe36be3 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -151,7 +151,7 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged,
         cfg->snapshotDir = g_strdup_printf("%s/snapshot", cfg->libDir);
         cfg->checkpointDir = g_strdup_printf("%s/checkpoint", cfg->libDir);
         cfg->autoDumpPath = g_strdup_printf("%s/dump", cfg->libDir);
-        cfg->channelTargetDir = g_strdup_printf("%s/channel/target", cfg->libDir);
+        cfg->channelTargetDir = g_strdup_printf("%s/channel", cfg->libDir);
         cfg->nvramDir = g_strdup_printf("%s/nvram", cfg->libDir);
         cfg->memoryBackingDir = g_strdup_printf("%s/ram", cfg->libDir);
     } else if (privileged) {
@@ -173,7 +173,7 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged,
         cfg->snapshotDir = g_strdup_printf("%s/snapshot", cfg->libDir);
         cfg->checkpointDir = g_strdup_printf("%s/checkpoint", cfg->libDir);
         cfg->autoDumpPath = g_strdup_printf("%s/dump", cfg->libDir);
-        cfg->channelTargetDir = g_strdup_printf("%s/channel/target", cfg->libDir);
+        cfg->channelTargetDir = g_strdup_printf("%s/channel", cfg->libDir);
         cfg->nvramDir = g_strdup_printf("%s/nvram", cfg->libDir);
         cfg->memoryBackingDir = g_strdup_printf("%s/ram", cfg->libDir);
         cfg->swtpmStorageDir = g_strdup_printf("%s/lib/libvirt/swtpm",
@@ -201,7 +201,7 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged,
         cfg->checkpointDir = g_strdup_printf("%s/qemu/checkpoint",
                                              cfg->configBaseDir);
         cfg->autoDumpPath = g_strdup_printf("%s/qemu/dump", cfg->configBaseDir);
-        cfg->channelTargetDir = g_strdup_printf("%s/qemu/channel/target",
+        cfg->channelTargetDir = g_strdup_printf("%s/qemu/channel",
                                                 cfg->configBaseDir);
         cfg->nvramDir = g_strdup_printf("%s/qemu/nvram", cfg->configBaseDir);
         cfg->memoryBackingDir = g_strdup_printf("%s/qemu/ram", cfg->configBaseDir);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 94587638c3..b4844351ba 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1780,7 +1780,7 @@ qemuDomainSetPrivatePaths(virQEMUDriver *driver,
         priv->libDir = g_strdup_printf("%s/domain-%s", cfg->libDir, domname);
 
     if (!priv->channelTargetDir)
-        priv->channelTargetDir = g_strdup_printf("%s/domain-%s",
+        priv->channelTargetDir = g_strdup_printf("%s/%s",
                                                  cfg->channelTargetDir, domname);
 
     return 0;
@@ -5352,9 +5352,12 @@ qemuDomainDefaultNetModel(const virDomainDef *def,
  * libvirt 1.2.19 - 1.3.2:
  *     {cfg->channelTargetDir}/domain-{dom-name}/{target-name}
  *
- * libvirt 1.3.3 and newer:
+ * libvirt 1.3.3 - 9.4.0:
  *     {cfg->channelTargetDir}/domain-{dom-id}-{short-dom-name}/{target-name}
  *
+ * libvirt 9.6.0 and newer:
+ *     {cfg->channelTargetDir}/{dom-id}-{short-dom-name}/{target-name}
+ *
  * The unix socket path was stored in config XML until libvirt 1.3.0.
  * If someone specifies the same path as we generate, they shouldn't do it.
  *
@@ -5379,7 +5382,7 @@ qemuDomainChrDefDropDefaultPath(virDomainChrDef *chr,
     cfg = virQEMUDriverGetConfig(driver);
 
     virBufferEscapeRegex(&buf, "^%s", cfg->channelTargetDir);
-    virBufferAddLit(&buf, "/([^/]+\\.)|(domain-[^/]+/)");
+    virBufferAddLit(&buf, "/(target/)?([^/]+\\.)|(domain-[^/]+/)|([0-9]+-[^/]+/)");
     virBufferEscapeRegex(&buf, "%s$", chr->target.name);
 
     regexp = virBufferContentAndReset(&buf);
diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml b/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml
index 0c3c70a78e..2e5cbfe09c 100644
--- a/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml
+++ b/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml
@@ -1,5 +1,5 @@
     <channel type='unix'>
-      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-7-hotplug/org.qemu.guest_agent.0'/>
+      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/7-hotplug/org.qemu.guest_agent.0'/>
       <target type='virtio' name='org.qemu.guest_agent.0'/>
       <address type='virtio-serial' controller='0' bus='0' port='1'/>
     </channel>
diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+qemu-agent-detach.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+qemu-agent-detach.xml
index 728af3391e..0469760737 100644
--- a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+qemu-agent-detach.xml
+++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+qemu-agent-detach.xml
@@ -39,7 +39,7 @@
       <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
     </controller>
     <channel type='unix'>
-      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-7-hotplug/org.qemu.guest_agent.0'/>
+      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/7-hotplug/org.qemu.guest_agent.0'/>
       <target type='virtio' name='org.qemu.guest_agent.0'/>
       <alias name='channel0'/>
       <address type='virtio-serial' controller='0' bus='0' port='1'/>
diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+qemu-agent.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+qemu-agent.xml
index 0e4c3907bf..8635a686e9 100644
--- a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+qemu-agent.xml
+++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+qemu-agent.xml
@@ -42,7 +42,7 @@
       <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
     </controller>
     <channel type='unix'>
-      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-7-hotplug/org.qemu.guest_agent.0'/>
+      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/7-hotplug/org.qemu.guest_agent.0'/>
       <target type='virtio' name='org.qemu.guest_agent.0'/>
       <alias name='channel0'/>
       <address type='virtio-serial' controller='0' bus='0' port='1'/>
diff --git a/tests/qemuxml2argvdata/channel-unix-source-path.xml b/tests/qemuxml2argvdata/channel-unix-source-path.xml
index f24c636147..db0e99c3d1 100644
--- a/tests/qemuxml2argvdata/channel-unix-source-path.xml
+++ b/tests/qemuxml2argvdata/channel-unix-source-path.xml
@@ -24,6 +24,10 @@
       <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/QEMUGuest1/org.qemu.guest_agent.3'/>
       <target type='virtio' name='org.qemu.guest_agent.3'/>
     </channel>
+    <channel type='unix'>
+      <source mode='bind' path='/var/lib/libvirt/qemu/channel/1-QEMUGuest1/org.qemu.guest_agent.4'/>
+      <target type='virtio' name='org.qemu.guest_agent.4'/>
+    </channel>
     <memballoon model='none'/>
   </devices>
 </domain>
diff --git a/tests/qemuxml2xmloutdata/channel-unix-source-path-active.xml b/tests/qemuxml2xmloutdata/channel-unix-source-path-active.xml
index 0d6a0295f8..68835ceb15 100644
--- a/tests/qemuxml2xmloutdata/channel-unix-source-path-active.xml
+++ b/tests/qemuxml2xmloutdata/channel-unix-source-path-active.xml
@@ -41,6 +41,11 @@
       <target type='virtio' name='org.qemu.guest_agent.3'/>
       <address type='virtio-serial' controller='0' bus='0' port='4'/>
     </channel>
+    <channel type='unix'>
+      <source mode='bind' path='/var/lib/libvirt/qemu/channel/1-QEMUGuest1/org.qemu.guest_agent.4'/>
+      <target type='virtio' name='org.qemu.guest_agent.4'/>
+      <address type='virtio-serial' controller='0' bus='0' port='5'/>
+    </channel>
     <input type='mouse' bus='ps2'/>
     <input type='keyboard' bus='ps2'/>
     <audio id='1' type='none'/>
diff --git a/tests/qemuxml2xmloutdata/channel-unix-source-path-inactive.xml b/tests/qemuxml2xmloutdata/channel-unix-source-path-inactive.xml
index d02ea52408..738c1184c0 100644
--- a/tests/qemuxml2xmloutdata/channel-unix-source-path-inactive.xml
+++ b/tests/qemuxml2xmloutdata/channel-unix-source-path-inactive.xml
@@ -38,6 +38,10 @@
       <target type='virtio' name='org.qemu.guest_agent.3'/>
       <address type='virtio-serial' controller='0' bus='0' port='4'/>
     </channel>
+    <channel type='unix'>
+      <target type='virtio' name='org.qemu.guest_agent.4'/>
+      <address type='virtio-serial' controller='0' bus='0' port='5'/>
+    </channel>
     <input type='mouse' bus='ps2'/>
     <input type='keyboard' bus='ps2'/>
     <audio id='1' type='none'/>
-- 
2.41.0
Re: [PATCH 1/4] qemu: Generate shorter channel target paths
Posted by Daniel P. Berrangé 2 years, 6 months ago
On Wed, Jul 12, 2023 at 04:49:53PM +0200, Michal Privoznik wrote:
> A <channel/> device is basically an UNIX socket into guest.
> Whatever is sent from the host, appears in the guest and vice
> versa. But because of that, the length of the path to the socket
> is important (underscored by fact that we derive the path from
> domain short name). But there are still cases where we might not
> fit into UNIX_PATH_MAX limit (usually 108 characters), because
> the path is derived also from other variables, e.g.
> XDG_CONFIG_HOME for session domains.
> 
> There is one component though, that's needless: "/target/". Drop
> it. This is safe to do, because running domains have their path
> saved in status XML and even though paths are dropped on
> migration, they are not part of guest ABI and thus we are free to
> change them.

This mentions dropping '/target/' which makes sense, but...

> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 94587638c3..b4844351ba 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -1780,7 +1780,7 @@ qemuDomainSetPrivatePaths(virQEMUDriver *driver,
>          priv->libDir = g_strdup_printf("%s/domain-%s", cfg->libDir, domname);
>  
>      if (!priv->channelTargetDir)
> -        priv->channelTargetDir = g_strdup_printf("%s/domain-%s",
> +        priv->channelTargetDir = g_strdup_printf("%s/%s",
>                                                   cfg->channelTargetDir, domname);

...this is also dropping 'domain-' which also makes sense, but
is not mentioned in the commit message.

> @@ -5352,9 +5352,12 @@ qemuDomainDefaultNetModel(const virDomainDef *def,
>   * libvirt 1.2.19 - 1.3.2:
>   *     {cfg->channelTargetDir}/domain-{dom-name}/{target-name}
>   *
> - * libvirt 1.3.3 and newer:
> + * libvirt 1.3.3 - 9.4.0:
>   *     {cfg->channelTargetDir}/domain-{dom-id}-{short-dom-name}/{target-name}
>   *
> + * libvirt 9.6.0 and newer:
> + *     {cfg->channelTargetDir}/{dom-id}-{short-dom-name}/{target-name}
> + *

This doesn't make it clear that 'cfg->channelTargetDir' is actually
different in those two examples.  Should we change th old ones to

    libvirt 1.2.19 - 1.3.2:
        {cfg->channelTargetDir}/target/domain-{dom-name}/{target-name}
   
    libvirt 1.3.3 - 9.4.0:
        {cfg->channelTargetDir}/target/domain-{dom-id}-{short-dom-name}/{target-name}



>   * The unix socket path was stored in config XML until libvirt 1.3.0.
>   * If someone specifies the same path as we generate, they shouldn't do it.
>   *
> @@ -5379,7 +5382,7 @@ qemuDomainChrDefDropDefaultPath(virDomainChrDef *chr,
>      cfg = virQEMUDriverGetConfig(driver);
>  
>      virBufferEscapeRegex(&buf, "^%s", cfg->channelTargetDir);
> -    virBufferAddLit(&buf, "/([^/]+\\.)|(domain-[^/]+/)");
> +    virBufferAddLit(&buf, "/(target/)?([^/]+\\.)|(domain-[^/]+/)|([0-9]+-[^/]+/)");
>      virBufferEscapeRegex(&buf, "%s$", chr->target.name);

  
> diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml b/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml
> index 0c3c70a78e..2e5cbfe09c 100644
> --- a/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml
> +++ b/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml
> @@ -1,5 +1,5 @@
>      <channel type='unix'>
> -      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-7-hotplug/org.qemu.guest_agent.0'/>
> +      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/7-hotplug/org.qemu.guest_agent.0'/>

You dropped 'domain-' but didn't drop '/target'. Same in a few other cases below


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
Re: [PATCH 1/4] qemu: Generate shorter channel target paths
Posted by Michal Prívozník 2 years, 6 months ago
On 7/21/23 14:27, Daniel P. Berrangé wrote:
> On Wed, Jul 12, 2023 at 04:49:53PM +0200, Michal Privoznik wrote:
>> A <channel/> device is basically an UNIX socket into guest.
>> Whatever is sent from the host, appears in the guest and vice
>> versa. But because of that, the length of the path to the socket
>> is important (underscored by fact that we derive the path from
>> domain short name). But there are still cases where we might not
>> fit into UNIX_PATH_MAX limit (usually 108 characters), because
>> the path is derived also from other variables, e.g.
>> XDG_CONFIG_HOME for session domains.
>>
>> There is one component though, that's needless: "/target/". Drop
>> it. This is safe to do, because running domains have their path
>> saved in status XML and even though paths are dropped on
>> migration, they are not part of guest ABI and thus we are free to
>> change them.
> 
> This mentions dropping '/target/' which makes sense, but...
> 
>> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
>> index 94587638c3..b4844351ba 100644
>> --- a/src/qemu/qemu_domain.c
>> +++ b/src/qemu/qemu_domain.c
>> @@ -1780,7 +1780,7 @@ qemuDomainSetPrivatePaths(virQEMUDriver *driver,
>>          priv->libDir = g_strdup_printf("%s/domain-%s", cfg->libDir, domname);
>>  
>>      if (!priv->channelTargetDir)
>> -        priv->channelTargetDir = g_strdup_printf("%s/domain-%s",
>> +        priv->channelTargetDir = g_strdup_printf("%s/%s",
>>                                                   cfg->channelTargetDir, domname);
> 
> ...this is also dropping 'domain-' which also makes sense, but
> is not mentioned in the commit message.
> 
>> @@ -5352,9 +5352,12 @@ qemuDomainDefaultNetModel(const virDomainDef *def,
>>   * libvirt 1.2.19 - 1.3.2:
>>   *     {cfg->channelTargetDir}/domain-{dom-name}/{target-name}
>>   *
>> - * libvirt 1.3.3 and newer:
>> + * libvirt 1.3.3 - 9.4.0:
>>   *     {cfg->channelTargetDir}/domain-{dom-id}-{short-dom-name}/{target-name}
>>   *
>> + * libvirt 9.6.0 and newer:
>> + *     {cfg->channelTargetDir}/{dom-id}-{short-dom-name}/{target-name}
>> + *
> 
> This doesn't make it clear that 'cfg->channelTargetDir' is actually
> different in those two examples.  Should we change th old ones to
> 
>     libvirt 1.2.19 - 1.3.2:
>         {cfg->channelTargetDir}/target/domain-{dom-name}/{target-name}
>    
>     libvirt 1.3.3 - 9.4.0:
>         {cfg->channelTargetDir}/target/domain-{dom-id}-{short-dom-name}/{target-name}
> 
> 

Good point, let me fix that.

> 
>>   * The unix socket path was stored in config XML until libvirt 1.3.0.
>>   * If someone specifies the same path as we generate, they shouldn't do it.
>>   *
>> @@ -5379,7 +5382,7 @@ qemuDomainChrDefDropDefaultPath(virDomainChrDef *chr,
>>      cfg = virQEMUDriverGetConfig(driver);
>>  
>>      virBufferEscapeRegex(&buf, "^%s", cfg->channelTargetDir);
>> -    virBufferAddLit(&buf, "/([^/]+\\.)|(domain-[^/]+/)");
>> +    virBufferAddLit(&buf, "/(target/)?([^/]+\\.)|(domain-[^/]+/)|([0-9]+-[^/]+/)");
>>      virBufferEscapeRegex(&buf, "%s$", chr->target.name);
> 
>   
>> diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml b/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml
>> index 0c3c70a78e..2e5cbfe09c 100644
>> --- a/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml
>> +++ b/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent-detach.xml
>> @@ -1,5 +1,5 @@
>>      <channel type='unix'>
>> -      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-7-hotplug/org.qemu.guest_agent.0'/>
>> +      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/7-hotplug/org.qemu.guest_agent.0'/>
> 
> You dropped 'domain-' but didn't drop '/target'. Same in a few other cases below

Yeah, I need to squash in the next patch that handles this. Let me fix
that in v2.

Michal