+ /*
+ * Get the session maximum size for a snapshot meaning it will compute the
+ * size of all streams from all domain.
+ */
+ max_stream_size = get_session_max_subbuf_size(session);
+
+ nb_streams = get_session_nb_streams(session);
+ if (nb_streams) {
+ /*
+ * The maximum size of the snapshot is the number of streams multiplied
+ * by the biggest subbuf size of all channels in a session which is the
+ * maximum stream size available for each stream. The session max size
+ * is now checked against the snapshot max size value given by the user
+ * and if lower, an error is returned.
+ */
+ session_max_size = max_stream_size * nb_streams;
+ }
+
+ DBG3("Snapshot max size is %" PRIu64 " for max stream size of %" PRIu64,
+ session_max_size, max_stream_size);
+
+ /*
+ * If we use a temporary output, check right away if the max size fits else
+ * for each output the max size will be checked.
+ */
+ if (use_tmp_output &&
+ (tmp_output.max_size != 0 &&
+ tmp_output.max_size < session_max_size)) {
+ ret = LTTNG_ERR_MAX_SIZE_INVALID;
+ goto error;
+ }
+
+ if (session->kernel_session) {
+ struct ltt_kernel_session *ksess = session->kernel_session;
+
+ if (use_tmp_output) {
+ ret = record_kernel_snapshot(ksess, &tmp_output, session,
+ wait, max_stream_size);
+ if (ret != LTTNG_OK) {
+ goto error;
+ }
+ snapshot_success = 1;
+ } else {
+ struct snapshot_output *sout;
+ struct lttng_ht_iter iter;
+
+ rcu_read_lock();
+ cds_lfht_for_each_entry(session->snapshot.output_ht->ht,
+ &iter.iter, sout, node.node) {
+ /*
+ * Make a local copy of the output and assign the possible
+ * temporary value given by the caller.
+ */
+ memset(&tmp_output, 0, sizeof(tmp_output));
+ memcpy(&tmp_output, sout, sizeof(tmp_output));
+
+ /* Use temporary max size. */
+ if (output->max_size != (uint64_t) -1ULL) {
+ tmp_output.max_size = output->max_size;
+ }
+
+ if (tmp_output.max_size != 0 &&
+ tmp_output.max_size < session_max_size) {
+ rcu_read_unlock();
+ ret = LTTNG_ERR_MAX_SIZE_INVALID;
+ goto error;
+ }
+
+ /* Use temporary name. */
+ if (*output->name != '\0') {
+ strncpy(tmp_output.name, output->name,
+ sizeof(tmp_output.name));
+ }
+
+ tmp_output.nb_snapshot = session->snapshot.nb_snapshot;
+
+ ret = record_kernel_snapshot(ksess, &tmp_output,
+ session, wait, max_stream_size);
+ if (ret != LTTNG_OK) {
+ rcu_read_unlock();
+ goto error;
+ }
+ snapshot_success = 1;
+ }
+ rcu_read_unlock();