@@ -206,6 +206,8 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
206206 assert (m );
207207 assert (m -> sealed );
208208
209+ /* We put this together only once, if this message is reused
210+ * we reuse the earlier-built version */
209211 if (m -> kdbus )
210212 return 0 ;
211213
@@ -722,7 +724,26 @@ int bus_kernel_connect(sd_bus *b) {
722724 return bus_kernel_take_fd (b );
723725}
724726
725- int bus_kernel_write_message (sd_bus * bus , sd_bus_message * m ) {
727+ static void close_kdbus_msg (sd_bus * bus , struct kdbus_msg * k ) {
728+ uint64_t off ;
729+ struct kdbus_item * d ;
730+
731+ assert (bus );
732+ assert (k );
733+
734+ off = (uint8_t * )k - (uint8_t * )bus -> kdbus_buffer ;
735+ ioctl (bus -> input_fd , KDBUS_CMD_FREE , & off );
736+
737+ KDBUS_ITEM_FOREACH (d , k , items ) {
738+
739+ if (d -> type == KDBUS_ITEM_FDS )
740+ close_many (d -> fds , (d -> size - offsetof(struct kdbus_item , fds )) / sizeof (int ));
741+ else if (d -> type == KDBUS_ITEM_PAYLOAD_MEMFD )
742+ close_nointr_nofail (d -> memfd .fd );
743+ }
744+ }
745+
746+ int bus_kernel_write_message (sd_bus * bus , sd_bus_message * m , bool hint_sync_call ) {
726747 int r ;
727748
728749 assert (bus );
@@ -738,6 +759,14 @@ int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
738759 if (r < 0 )
739760 return r ;
740761
762+ /* If this is a synchronous method call, then let's tell the
763+ * kernel, so that it can pass CPU time/scheduling to the
764+ * destination for the time, if it wants to. If we
765+ * synchronously wait for the result anyway, we won't need CPU
766+ * anyway. */
767+ if (hint_sync_call )
768+ m -> kdbus -> flags |= KDBUS_MSG_FLAGS_EXPECT_REPLY |KDBUS_MSG_FLAGS_SYNC_REPLY ;
769+
741770 r = ioctl (bus -> output_fd , KDBUS_CMD_MSG_SEND , m -> kdbus );
742771 if (r < 0 ) {
743772 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL ;
@@ -785,29 +814,31 @@ int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) {
785814
786815 bus -> rqueue [bus -> rqueue_size ++ ] = reply ;
787816
788- return 0 ;
789- }
817+ } else if ( hint_sync_call ) {
818+ struct kdbus_msg * k ;
790819
791- return 1 ;
792- }
820+ k = ( struct kdbus_msg * )(( uint8_t * ) bus -> kdbus_buffer + m -> kdbus -> offset_reply ) ;
821+ assert ( k );
793822
794- static void close_kdbus_msg (sd_bus * bus , struct kdbus_msg * k ) {
795- uint64_t off ;
796- struct kdbus_item * d ;
797-
798- assert (bus );
799- assert (k );
823+ if (k -> payload_type == KDBUS_PAYLOAD_DBUS ) {
800824
801- off = (uint8_t * )k - (uint8_t * )bus -> kdbus_buffer ;
802- ioctl (bus -> input_fd , KDBUS_CMD_FREE , & off );
803-
804- KDBUS_ITEM_FOREACH (d , k , items ) {
825+ r = bus_kernel_make_message (bus , k );
826+ if (r < 0 ) {
827+ close_kdbus_msg (bus , k );
805828
806- if (d -> type == KDBUS_ITEM_FDS )
807- close_many (d -> fds , (d -> size - offsetof(struct kdbus_item , fds )) / sizeof (int ));
808- else if (d -> type == KDBUS_ITEM_PAYLOAD_MEMFD )
809- close_nointr_nofail (d -> memfd .fd );
829+ /* Anybody can send us invalid messages, let's just drop them. */
830+ if (r == - EBADMSG || r == - EPROTOTYPE )
831+ log_debug ("Ignoring invalid message: %s" , strerror (- r ));
832+ else
833+ return r ;
834+ }
835+ } else {
836+ log_debug ("Ignoring message with unknown payload type %llu." , (unsigned long long ) k -> payload_type );
837+ close_kdbus_msg (bus , k );
838+ }
810839 }
840+
841+ return 1 ;
811842}
812843
813844static int push_name_owner_changed (sd_bus * bus , const char * name , const char * old_owner , const char * new_owner ) {
@@ -964,8 +995,8 @@ int bus_kernel_read_message(sd_bus *bus) {
964995
965996 return - errno ;
966997 }
967- k = (struct kdbus_msg * )((uint8_t * )bus -> kdbus_buffer + recv .offset );
968998
999+ k = (struct kdbus_msg * )((uint8_t * )bus -> kdbus_buffer + recv .offset );
9691000 if (k -> payload_type == KDBUS_PAYLOAD_DBUS ) {
9701001 r = bus_kernel_make_message (bus , k );
9711002
@@ -977,8 +1008,10 @@ int bus_kernel_read_message(sd_bus *bus) {
9771008
9781009 } else if (k -> payload_type == KDBUS_PAYLOAD_KERNEL )
9791010 r = bus_kernel_translate_message (bus , k );
980- else
1011+ else {
1012+ log_debug ("Ignoring message with unknown payload type %llu." , (unsigned long long ) k -> payload_type );
9811013 r = 0 ;
1014+ }
9821015
9831016 if (r <= 0 )
9841017 close_kdbus_msg (bus , k );
0 commit comments