Add secondary_instance_ field to FtraceConfigMuxer

This will allow us to only support subset of the features for the
secondary ftrace instances.

As an example, in the first version, secondary ftrace instances won't
support atrace events.

Bug: 249050813
Test: perfetto_unittests
Change-Id: I09b38c9965096bc5bb81017aeb313753319712e7
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.cc b/src/traced/probes/ftrace/ftrace_config_muxer.cc
index ce768c1..61a26dd 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.cc
@@ -585,13 +585,15 @@
     FtraceProcfs* ftrace,
     ProtoTranslationTable* table,
     SyscallTable syscalls,
-    std::map<std::string, std::vector<GroupAndName>> vendor_events)
+    std::map<std::string, std::vector<GroupAndName>> vendor_events,
+    bool secondary_instance)
     : ftrace_(ftrace),
       table_(table),
       syscalls_(std::move(syscalls)),
       current_state_(),
       ds_configs_(),
-      vendor_events_(vendor_events) {}
+      vendor_events_(vendor_events),
+      secondary_instance_(secondary_instance) {}
 FtraceConfigMuxer::~FtraceConfigMuxer() = default;
 
 bool FtraceConfigMuxer::SetupConfig(FtraceConfigId id,
@@ -650,6 +652,12 @@
   }
 
   if (RequiresAtrace(request)) {
+    if (secondary_instance_) {
+      PERFETTO_ELOG(
+          "Secondary ftrace instances do not support atrace_categories and "
+          "atrace_apps options as they affect global state");
+      return false;
+    }
     if (IsOldAtrace() && !ds_configs_.empty()) {
       PERFETTO_ELOG(
           "Concurrent atrace sessions are not supported before Android P, "
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.h b/src/traced/probes/ftrace/ftrace_config_muxer.h
index affa4b6..2a2fca8 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.h
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.h
@@ -108,12 +108,12 @@
       FtraceProcfs* ftrace,
       ProtoTranslationTable* table,
       SyscallTable syscalls,
-      std::map<std::string, std::vector<GroupAndName>> vendor_events);
+      std::map<std::string, std::vector<GroupAndName>> vendor_events,
+      bool secondary_instance = false);
   virtual ~FtraceConfigMuxer();
 
   // Ask FtraceConfigMuxer to adjust ftrace procfs settings to
-  // match the requested config. Returns an id to manage this
-  // config or zero on failure.
+  // match the requested config. Returns true on success and false on failure.
   // This is best effort. FtraceConfigMuxer may not be able to adjust the
   // buffer size right now. Events may be missing or there may be extra events
   // (if you enable an atrace category we try to give you the matching events).
@@ -234,11 +234,17 @@
   // sizes and events, but don't enable ftrace (i.e. tracing_on).
   std::map<FtraceConfigId, FtraceDataSourceConfig> ds_configs_;
 
-  std::map<std::string, std::vector<GroupAndName>> vendor_events_;
-
   // Subset of |ds_configs_| that are currently active. At any time ftrace is
   // enabled iff |active_configs_| is not empty.
   std::set<FtraceConfigId> active_configs_;
+
+  std::map<std::string, std::vector<GroupAndName>> vendor_events_;
+
+  // If true, this muxer is for a secondary ftrace instance
+  // (tracefs/instances/<name>). At the moment, we only support basic ftrace
+  // event recording in such instances. So only |ftrace_events| and
+  // |ftrace_buffer_size| options are guaranteed to work.
+  bool secondary_instance_;
 };
 
 size_t ComputeCpuBufferSizeInPages(size_t requested_buffer_size_kb);
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc b/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
index 942e811..69c96d3 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer_unittest.cc
@@ -1291,5 +1291,17 @@
   ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&ftrace));
 }
 
+TEST_F(FtraceConfigMuxerTest, SecondaryInstanceDoNotSupportAtrace) {
+  auto fake_table = CreateFakeTable();
+  NiceMock<MockFtraceProcfs> ftrace;
+  FtraceConfigMuxer model(&ftrace, fake_table.get(), GetSyscallTable(), {},
+                          /* secondary_instance= */ true);
+
+  FtraceConfig config = CreateFtraceConfig({"sched/sched_switch"});
+  *config.add_atrace_categories() = "sched";
+
+  ASSERT_FALSE(model.SetupConfig(/* id= */ 73, config));
+}
+
 }  // namespace
 }  // namespace perfetto
diff --git a/src/traced/probes/ftrace/ftrace_controller.cc b/src/traced/probes/ftrace/ftrace_controller.cc
index c01e61c..3aee056 100644
--- a/src/traced/probes/ftrace/ftrace_controller.cc
+++ b/src/traced/probes/ftrace/ftrace_controller.cc
@@ -40,7 +40,6 @@
 #include "src/traced/probes/ftrace/atrace_hal_wrapper.h"
 #include "src/traced/probes/ftrace/cpu_reader.h"
 #include "src/traced/probes/ftrace/cpu_stats_parser.h"
-#include "src/traced/probes/ftrace/vendor_tracepoints.h"
 #include "src/traced/probes/ftrace/event_info.h"
 #include "src/traced/probes/ftrace/ftrace_config_muxer.h"
 #include "src/traced/probes/ftrace/ftrace_data_source.h"
@@ -48,6 +47,7 @@
 #include "src/traced/probes/ftrace/ftrace_procfs.h"
 #include "src/traced/probes/ftrace/ftrace_stats.h"
 #include "src/traced/probes/ftrace/proto_translation_table.h"
+#include "src/traced/probes/ftrace/vendor_tracepoints.h"
 
 namespace perfetto {
 namespace {