net/tap: move fds parameters handling to separate functions
This significantly simplify the code in net_init_tap(). Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Reviewed-by: Ben Chaney <bchaney@akamai.com> Signed-off-by: Jason Wang <jasowang@redhat.com>
Vladimir Sementsov-Ogievskiy committed
Mar 18, 2026 at 14:31 UTC
dadfb97e8d43d9a2613b47f2ad8b00d095e965db
1 file changed
+65
-34
net/tap.c
+65
-34
@@ -781,6 +781,61 @@ failed:
781
return false;
782
}
783
784
+static bool unblock_fds(int *fds, int nfds, Error **errp)
785
+{
786
+ for (int i = 0; i < nfds; i++) {
787
+ if (!qemu_set_blocking(fds[i], false, errp)) {
788
+ return false;
789
+ }
790
+ }
791
+
792
+ return true;
793
+}
794
+
795
+static int tap_parse_fds_and_queues(const NetdevTapOptions *tap, int **fds,
796
+ Error **errp)
797
+{
798
+ int queues = 1;
799
+
800
+ if (tap->has_queues + !!tap->helper + !!tap->fds + !!tap->fd > 1) {
801
+ error_setg(errp, "queues=, helper=, fds= and fd= are mutual exclusive");
802
+ return -1;
803
+ }
804
+
805
+ if (tap->has_queues) {
806
+ if (tap->queues > INT_MAX) {
807
+ error_setg(errp, "queues exceeds maximum %d", INT_MAX);
808
+ return -1;
809
+ }
810
+ queues = tap->queues;
811
+ *fds = NULL;
812
+ } else if (tap->fd || tap->fds) {
813
+ queues = net_parse_fds(tap->fd ?: tap->fds, fds,
814
+ tap->fd ? 1 : 0, errp);
815
+ if (!*fds) {
816
+ return -1;
817
+ }
818
+ } else if (tap->helper) {
819
+ int fd = net_bridge_run_helper(tap->helper,
820
+ tap->br ?: DEFAULT_BRIDGE_INTERFACE,
821
+ errp);
822
+ if (fd < 0) {
823
+ return -1;
824
+ }
825
+
826
+ queues = 1;
827
+ *fds = g_new(int, 1);
828
+ **fds = fd;
829
+ }
830
+
831
+ if (*fds && !unblock_fds(*fds, queues, errp)) {
832
+ net_free_fds(*fds, queues);
833
+ return -1;
834
+ }
835
+
836
+ return queues;
837
+}
838
+
839
int net_init_tap(const Netdev *netdev, const char *name,
840
NetClientState *peer, Error **errp)
841
{
@@ -792,7 +847,6 @@ int net_init_tap(const Netdev *netdev, const char *name,
847
848
assert(netdev->type == NET_CLIENT_DRIVER_TAP);
849
tap = &netdev->u.tap;
795
- queues = tap->has_queues ? tap->queues : 1;
850
851
/* QEMU hubs do not support multiqueue tap, in this case peer is set.
852
* For -netdev, peer is always NULL. */
@@ -829,10 +883,15 @@ int net_init_tap(const Netdev *netdev, const char *name,
883
return -1;
884
}
885
886
+ queues = tap_parse_fds_and_queues(tap, &fds, errp);
887
+ if (queues < 0) {
888
+ return -1;
889
+ }
890
+
891
if (tap->vhostfd) {
892
vhostfd = monitor_fd_param(monitor_cur(), tap->vhostfd, errp);
893
if (vhostfd == -1) {
835
- return -1;
894
+ goto fail;
895
}
896
897
if (!qemu_set_blocking(vhostfd, false, errp)) {
@@ -841,41 +900,23 @@ int net_init_tap(const Netdev *netdev, const char *name,
900
}
901
902
if (tap->fd) {
844
- fd = monitor_fd_param(monitor_cur(), tap->fd, errp);
845
- if (fd == -1) {
846
- goto fail;
847
- }
848
-
849
- if (!qemu_set_blocking(fd, false, errp)) {
850
- goto fail;
851
- }
852
-
853
- vnet_hdr = tap_probe_vnet_hdr(fd, errp);
903
+ vnet_hdr = tap_probe_vnet_hdr(fds[0], errp);
904
if (vnet_hdr < 0) {
905
goto fail;
906
}
907
908
if (!net_init_tap_one(tap, peer, name, NULL,
909
NULL, NULL,
860
- vhostfd, vnet_hdr, fd, errp)) {
910
+ vhostfd, vnet_hdr, fds[0], errp)) {
911
goto fail;
912
}
913
} else if (tap->fds) {
864
- queues = net_parse_fds(tap->fds, &fds, 0, errp);
865
- if (queues < 0) {
866
- goto fail;
867
- }
868
-
914
if (tap->vhostfds && net_parse_fds(tap->vhostfds, &vhost_fds,
915
queues, errp) < 0) {
916
goto fail;
917
}
918
919
for (i = 0; i < queues; i++) {
875
- if (!qemu_set_blocking(fds[i], false, errp)) {
876
- goto fail;
877
- }
878
-
920
if (vhost_fds && !qemu_set_blocking(vhost_fds[i], false, errp)) {
921
goto fail;
922
}
@@ -899,24 +940,14 @@ int net_init_tap(const Netdev *netdev, const char *name,
940
}
941
}
942
} else if (tap->helper) {
902
- fd = net_bridge_run_helper(tap->helper,
903
- tap->br ?: DEFAULT_BRIDGE_INTERFACE,
904
- errp);
905
- if (fd == -1) {
906
- goto fail;
907
- }
908
-
909
- if (!qemu_set_blocking(fd, false, errp)) {
910
- goto fail;
911
- }
912
- vnet_hdr = tap_probe_vnet_hdr(fd, errp);
943
+ vnet_hdr = tap_probe_vnet_hdr(fds[0], errp);
944
if (vnet_hdr < 0) {
945
goto fail;
946
}
947
948
if (!net_init_tap_one(tap, peer, name, ifname,
949
NULL, NULL, vhostfd,
919
- vnet_hdr, fd, errp)) {
950
+ vnet_hdr, fds[0], errp)) {
951
goto fail;
952
}
953
} else {