|  | 
|  | 1 | +// Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/ | 
|  | 2 | +// SPDX-License-Identifier: Apache-2.0 | 
|  | 3 | + | 
|  | 4 | +use serde::Serialize; | 
|  | 5 | +#[cfg(target_os = "linux")] | 
|  | 6 | +use memfd::{Memfd, MemfdOptions}; | 
|  | 7 | + | 
|  | 8 | +/// This struct MUST be backward compatible. | 
|  | 9 | +#[derive(Serialize, Debug)] | 
|  | 10 | +#[repr(C)] | 
|  | 11 | +pub struct TracerMetadata { | 
|  | 12 | +   /// Version of the schema. | 
|  | 13 | +   pub schema_version: u8, | 
|  | 14 | +   /// Runtime UUID. | 
|  | 15 | +   #[serde(skip_serializing_if = "Option::is_none")] | 
|  | 16 | +   pub runtime_id: Option<String>, | 
|  | 17 | +   /// Programming language of the tracer library (e.g., “python”). Refers to telemetry        for valid values. | 
|  | 18 | +   pub tracer_language: String, | 
|  | 19 | +   /// Version of the tracer (e.g., "1.0.0"). | 
|  | 20 | +   pub tracer_version: String, | 
|  | 21 | +   /// Identifier of the machine running the process. | 
|  | 22 | +   pub hostname: String, | 
|  | 23 | +   /// Name of the service being instrumented. | 
|  | 24 | +   #[serde(skip_serializing_if = "Option::is_none")] | 
|  | 25 | +   pub service_name: Option<String>, | 
|  | 26 | +   /// Environment of the service being instrumented. | 
|  | 27 | +   #[serde(skip_serializing_if = "Option::is_none")] | 
|  | 28 | +   pub service_env: Option<String>, | 
|  | 29 | +   /// Version of the service being instrumented. | 
|  | 30 | +   #[serde(skip_serializing_if = "Option::is_none")] | 
|  | 31 | +   pub service_version: Option<String>, | 
|  | 32 | +} | 
|  | 33 | + | 
|  | 34 | +pub enum AnonymousFileHandle { | 
|  | 35 | +    #[cfg(target_os = "linux")] | 
|  | 36 | +    Linux(Box<Memfd>), | 
|  | 37 | +    #[cfg(not(target_os = "linux"))] | 
|  | 38 | +    Other(()), | 
|  | 39 | +} | 
|  | 40 | + | 
|  | 41 | +/// Create the anonymous file storing the tracer metadata. | 
|  | 42 | +#[cfg(target_os = "linux")] | 
|  | 43 | +pub fn store_tracer_metadata(data: TracerMetadata) -> Result<AnonymousFileHandle, String> { | 
|  | 44 | +    let uid: String = rand::thread_rng().sample_iter(&Alphanumeric).take(8).map(char::from).collect(); | 
|  | 45 | +    let mfd_name: String = format!("{}-{}", "datadog-tracer-info", uid); | 
|  | 46 | + | 
|  | 47 | +    let mfd = MemfdOptions::default() | 
|  | 48 | +        .close_on_exec(true) | 
|  | 49 | +        .allow_sealing(true) | 
|  | 50 | +        .create::<&str>(mfd_name.as_ref()) | 
|  | 51 | +        .map_err(|e| format!("Unable to create memfd: {}", e))?; | 
|  | 52 | + | 
|  | 53 | +    let mut buf = Vec::new(); | 
|  | 54 | +    data.serialize(&mut Serializer::new(&mut buf).with_struct_map()).unwrap(); | 
|  | 55 | + | 
|  | 56 | +    mfd.as_file().write_all(&buf).unwrap(); | 
|  | 57 | +    mfd.add_seals(&[ | 
|  | 58 | +        memfd::FileSeal::SealShrink, | 
|  | 59 | +        memfd::FileSeal::SealGrow, | 
|  | 60 | +        memfd::FileSeal::SealSeal, | 
|  | 61 | +    ]).map_error(|e| format!("Unable to seal: {}", e))?; | 
|  | 62 | + | 
|  | 63 | +    return Ok(AnonymousFileHandle::Linux(Box::new(mfd))); | 
|  | 64 | +} | 
|  | 65 | + | 
|  | 66 | +#[cfg(not(target_os = "linux"))] | 
|  | 67 | +pub fn store_tracer_metadata(_data: TracerMetadata) -> Result<AnonymousFileHandle, String> { | 
|  | 68 | +    return Ok(AnonymousFileHandle::Other(())); | 
|  | 69 | +} | 
0 commit comments