Support for audio in ph-init
This commit is contained in:
parent
cded52b7c9
commit
3dabe69881
71
ph-init/src/audio.rs
Normal file
71
ph-init/src/audio.rs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
use std::fs;
|
||||||
|
use crate::{Error, sys, warn};
|
||||||
|
use crate::error::Result;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
const DAEMON_CONF: &str = r#"
|
||||||
|
log-target = file:/tmp/pulseaudio.log
|
||||||
|
log-level = debug
|
||||||
|
"#;
|
||||||
|
|
||||||
|
// If extra-arguments is not set, pulseaudio will be launched with
|
||||||
|
// '--log-target=syslog' which overrides the log settings in daemon.conf
|
||||||
|
const CLIENT_CONF: &str = r#"
|
||||||
|
autospawn = yes
|
||||||
|
daemon-binary = /usr/bin/pulseaudio
|
||||||
|
extra-arguments = --
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const DEFAULT_PA: &str = r#"
|
||||||
|
load-module module-device-restore
|
||||||
|
load-module module-stream-restore
|
||||||
|
load-module module-card-restore
|
||||||
|
|
||||||
|
load-module module-alsa-sink device=hw:0,0
|
||||||
|
load-module module-native-protocol-unix
|
||||||
|
load-module module-always-sink
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const SOUND_DEVICES_PATH: &str = "/dev/snd";
|
||||||
|
const PULSE_RUN_PATH: &str = "/run/ph/pulse";
|
||||||
|
|
||||||
|
pub struct AudioSupport;
|
||||||
|
|
||||||
|
impl AudioSupport {
|
||||||
|
pub fn setup() -> Result<()> {
|
||||||
|
if Path::new(SOUND_DEVICES_PATH).exists() {
|
||||||
|
Self::setup_sound_devices()?;
|
||||||
|
Self::setup_pulse_audio_config()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_sound_devices() -> Result<()> {
|
||||||
|
for entry in fs::read_dir(SOUND_DEVICES_PATH)
|
||||||
|
.map_err(Error::DevSndReadDir)? {
|
||||||
|
let entry = entry.map_err(Error::DevSndReadDir)?;
|
||||||
|
let path = entry.path();
|
||||||
|
if let Some(path_str) = path.as_os_str().to_str() {
|
||||||
|
sys::chmod(path_str, 0o666)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_config_file(name: &str, content: &str) -> Result<()> {
|
||||||
|
let pulse_run_path = Path::new(PULSE_RUN_PATH);
|
||||||
|
fs::write(pulse_run_path.join(name), content)
|
||||||
|
.map_err(Error::PulseAudioConfigWrite)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_pulse_audio_config() -> Result<()> {
|
||||||
|
fs::create_dir_all(PULSE_RUN_PATH)
|
||||||
|
.map_err(Error::PulseAudioConfigWrite)?;
|
||||||
|
Self::write_config_file("daemon.conf", DAEMON_CONF)?;
|
||||||
|
Self::write_config_file("client.conf", CLIENT_CONF)?;
|
||||||
|
Self::write_config_file("default.pa", DEFAULT_PA)?;
|
||||||
|
sys::bind_mount(PULSE_RUN_PATH, "/etc/pulse")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -30,6 +30,8 @@ pub enum Error {
|
|||||||
MountOverlay(io::Error),
|
MountOverlay(io::Error),
|
||||||
#[error("failed to move mount from {0} to {1}: {2}")]
|
#[error("failed to move mount from {0} to {1}: {2}")]
|
||||||
MoveMount(String, String, io::Error),
|
MoveMount(String, String, io::Error),
|
||||||
|
#[error("failed to bind mount from {0} to {1}: {2}")]
|
||||||
|
BindMount(String, String, io::Error),
|
||||||
#[error("failed to mount 9p volume {0} at {1}: {2}")]
|
#[error("failed to mount 9p volume {0} at {1}: {2}")]
|
||||||
Mount9P(String, String, io::Error),
|
Mount9P(String, String, io::Error),
|
||||||
#[error("failed to unmount {0}: {1}")]
|
#[error("failed to unmount {0}: {1}")]
|
||||||
@ -68,6 +70,10 @@ pub enum Error {
|
|||||||
WriteBashrc(io::Error),
|
WriteBashrc(io::Error),
|
||||||
#[error("error configuring network: {0}")]
|
#[error("error configuring network: {0}")]
|
||||||
NetworkConfigure(netlink::Error),
|
NetworkConfigure(netlink::Error),
|
||||||
|
#[error("error reading /dev/snd: {0}")]
|
||||||
|
DevSndReadDir(io::Error),
|
||||||
|
#[error("error writing pulse audio config file: {0}")]
|
||||||
|
PulseAudioConfigWrite(io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
@ -9,6 +9,7 @@ use std::collections::BTreeMap;
|
|||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use crate::audio::AudioSupport;
|
||||||
use crate::netlink::NetlinkSocket;
|
use crate::netlink::NetlinkSocket;
|
||||||
|
|
||||||
const BASHRC: &str = r#"
|
const BASHRC: &str = r#"
|
||||||
@ -117,6 +118,8 @@ impl InitServer {
|
|||||||
mkdir("/run/user/1000")?;
|
mkdir("/run/user/1000")?;
|
||||||
chown("/run/user/1000", 1000,1000)?;
|
chown("/run/user/1000", 1000,1000)?;
|
||||||
|
|
||||||
|
AudioSupport::setup()?;
|
||||||
|
|
||||||
self.mount_home_if_exists()?;
|
self.mount_home_if_exists()?;
|
||||||
Logger::set_file_output("/run/phinit.log")
|
Logger::set_file_output("/run/phinit.log")
|
||||||
.map_err(Error::OpenLogFailed)?;
|
.map_err(Error::OpenLogFailed)?;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
|
mod audio;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod log;
|
mod log;
|
||||||
mod error;
|
mod error;
|
||||||
|
@ -69,6 +69,11 @@ pub fn move_mount(source: &str, target: &str) -> Result<()> {
|
|||||||
.map_err(|e| Error::MoveMount(source.to_string(), target.to_string(), e))
|
.map_err(|e| Error::MoveMount(source.to_string(), target.to_string(), e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bind_mount(source: &str, target: &str) -> Result<()> {
|
||||||
|
mount(source, target, "", libc::MS_BIND, None)
|
||||||
|
.map_err(|e| Error::BindMount(source.to_string(), target.to_string(), e))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mount_9p(name: &str, target: &str) -> Result<()> {
|
pub fn mount_9p(name: &str, target: &str) -> Result<()> {
|
||||||
const MS_LAZYTIME: libc::c_ulong = 1 << 25;
|
const MS_LAZYTIME: libc::c_ulong = 1 << 25;
|
||||||
mount(name, target, "9p",
|
mount(name, target, "9p",
|
||||||
|
Loading…
Reference in New Issue
Block a user