+
+/*
+ * Validate version of UST apps and set the compatible bit.
+ */
+int ust_app_validate_version(int sock)
+{
+ int ret;
+ struct ust_app *app;
+
+ rcu_read_lock();
+
+ app = find_app_by_sock(sock);
+ assert(app);
+
+ ret = ustctl_tracer_version(sock, &app->version);
+ if (ret < 0) {
+ goto error;
+ }
+
+ /* Validate version */
+ if (app->version.major > UST_APP_MAJOR_VERSION) {
+ goto error;
+ }
+
+ DBG2("UST app PID %d is compatible with major version %d "
+ "(supporting <= %d)", app->pid, app->version.major,
+ UST_APP_MAJOR_VERSION);
+ app->compatible = 1;
+ rcu_read_unlock();
+ return 0;
+
+error:
+ DBG2("UST app PID %d is not compatible with major version %d "
+ "(supporting <= %d)", app->pid, app->version.major,
+ UST_APP_MAJOR_VERSION);
+ app->compatible = 0;
+ rcu_read_unlock();
+ return -1;
+}
+
+/*
+ * Calibrate registered applications.
+ */
+int ust_app_calibrate_glb(struct lttng_ust_calibrate *calibrate)
+{
+ int ret = 0;
+ struct lttng_ht_iter iter;
+ struct ust_app *app;
+
+ rcu_read_lock();
+
+ cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+ if (!app->compatible) {
+ /*
+ * TODO: In time, we should notice the caller of this error by
+ * telling him that this is a version error.
+ */
+ continue;
+ }
+
+ ret = ustctl_calibrate(app->sock, calibrate);
+ if (ret < 0) {
+ switch (ret) {
+ case -ENOSYS:
+ /* Means that it's not implemented on the tracer side. */
+ ret = 0;
+ break;
+ default:
+ /* TODO: Report error to user */
+ DBG2("Calibrate app PID %d returned with error %d",
+ app->pid, ret);
+ break;
+ }
+ }
+ }
+
+ DBG("UST app global domain calibration finished");
+
+ rcu_read_unlock();
+
+ return ret;
+}