@@ -182,14 +182,30 @@ async fn run_display_manager(args: Args, config: Config) -> Result<()> { |
| 182 | 182 | tracing::warn!(error = %e, "Failed to kill greeter"); |
| 183 | 183 | } |
| 184 | 184 | |
| 185 | + eprintln!("[MAIN] Greeter session ended, processing result"); |
| 186 | + tracing::debug!(?session_result, "Greeter session ended, processing result"); |
| 187 | + |
| 185 | 188 | match session_result { |
| 186 | 189 | Ok(Some(session_info)) => { |
| 190 | + eprintln!("[MAIN] Got session_info: {} {:?} ({})", |
| 191 | + session_info.username, session_info.cmd, session_info.session_type); |
| 192 | + tracing::info!( |
| 193 | + "Processing session start: {} {:?} ({})", |
| 194 | + session_info.username, |
| 195 | + session_info.cmd, |
| 196 | + session_info.session_type |
| 197 | + ); |
| 187 | 198 | let vt = x_server.as_ref().map(|x| x.vt()).unwrap_or(1); |
| 188 | 199 | let is_wayland = session_info.session_type == "wayland"; |
| 189 | 200 | |
| 190 | 201 | if is_wayland { |
| 191 | 202 | // WAYLAND SESSION: Stop X server first, then start compositor |
| 192 | | - tracing::info!("Wayland session selected, stopping X server"); |
| 203 | + tracing::info!( |
| 204 | + username = %session_info.username, |
| 205 | + cmd = ?session_info.cmd, |
| 206 | + vt, |
| 207 | + "Wayland session selected, stopping X server" |
| 208 | + ); |
| 193 | 209 | |
| 194 | 210 | // Stop X server - compositor needs direct VT access |
| 195 | 211 | if let Some(x) = x_server.take() { |
@@ -198,13 +214,29 @@ async fn run_display_manager(args: Args, config: Config) -> Result<()> { |
| 198 | 214 | } |
| 199 | 215 | |
| 200 | 216 | // Start Wayland compositor directly on VT |
| 201 | | - let mut session = UserSession::start( |
| 217 | + tracing::info!("Starting Wayland compositor"); |
| 218 | + let mut session = match UserSession::start( |
| 202 | 219 | &session_info.username, |
| 220 | + &session_info.password, |
| 203 | 221 | &session_info.cmd, |
| 204 | 222 | "wayland", |
| 205 | 223 | None, // No DISPLAY for Wayland |
| 206 | 224 | vt, |
| 207 | | - )?; |
| 225 | + ) { |
| 226 | + Ok(s) => { |
| 227 | + tracing::info!(pid = s.pid(), "Wayland session started successfully"); |
| 228 | + s |
| 229 | + } |
| 230 | + Err(e) => { |
| 231 | + tracing::error!(error = %e, "Failed to start Wayland session"); |
| 232 | + // Restart X server and try again with greeter |
| 233 | + tracing::info!("Restarting X server after Wayland session failure"); |
| 234 | + let new_x = XServer::start(&x_display, vt)?; |
| 235 | + vt::switch_to_vt(vt)?; |
| 236 | + x_server = Some(new_x); |
| 237 | + continue; |
| 238 | + } |
| 239 | + }; |
| 208 | 240 | |
| 209 | 241 | // Wait for session to end |
| 210 | 242 | let session_ended = tokio::select! { |
@@ -235,6 +267,7 @@ async fn run_display_manager(args: Args, config: Config) -> Result<()> { |
| 235 | 267 | // X11 SESSION: Keep X server running (existing behavior) |
| 236 | 268 | let mut session = UserSession::start( |
| 237 | 269 | &session_info.username, |
| 270 | + &session_info.password, |
| 238 | 271 | &session_info.cmd, |
| 239 | 272 | "x11", |
| 240 | 273 | Some(&x_display), |
@@ -278,10 +311,22 @@ async fn run_display_manager(args: Args, config: Config) -> Result<()> { |
| 278 | 311 | /// Information needed to start a user session |
| 279 | 312 | struct SessionStartInfo { |
| 280 | 313 | username: String, |
| 314 | + password: String, // Needed for PAM open_session in child process |
| 281 | 315 | cmd: Vec<String>, |
| 282 | 316 | session_type: String, |
| 283 | 317 | } |
| 284 | 318 | |
| 319 | +impl std::fmt::Debug for SessionStartInfo { |
| 320 | + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 321 | + f.debug_struct("SessionStartInfo") |
| 322 | + .field("username", &self.username) |
| 323 | + .field("password", &"[REDACTED]") |
| 324 | + .field("cmd", &self.cmd) |
| 325 | + .field("session_type", &self.session_type) |
| 326 | + .finish() |
| 327 | + } |
| 328 | +} |
| 329 | + |
| 285 | 330 | /// Handle greeter IPC until we get a successful auth and StartSession |
| 286 | 331 | async fn handle_greeter_session( |
| 287 | 332 | server: &ipc::Server, |
@@ -298,9 +343,20 @@ async fn handle_greeter_session( |
| 298 | 343 | |
| 299 | 344 | let (response, session_info) = handle_greeter_request(request, &mut auth).await; |
| 300 | 345 | |
| 346 | + eprintln!("[IPC] About to send response, has_session_info={}", session_info.is_some()); |
| 347 | + tracing::debug!(?response, has_session_info = session_info.is_some(), "Sending response to greeter"); |
| 301 | 348 | conn.send(&response).await?; |
| 349 | + eprintln!("[IPC] Response sent successfully"); |
| 350 | + tracing::debug!("Response sent successfully"); |
| 302 | 351 | |
| 303 | 352 | if let Some(info) = session_info { |
| 353 | + eprintln!("[IPC] Returning session info: {} {:?}", info.username, info.cmd); |
| 354 | + tracing::info!( |
| 355 | + username = %info.username, |
| 356 | + cmd = ?info.cmd, |
| 357 | + session_type = %info.session_type, |
| 358 | + "Returning session info to main loop" |
| 359 | + ); |
| 304 | 360 | return Ok(Some(info)); |
| 305 | 361 | } |
| 306 | 362 | } |
@@ -336,12 +392,12 @@ async fn handle_greeter_request( |
| 336 | 392 | } |
| 337 | 393 | |
| 338 | 394 | Request::StartSession { cmd, session_type, env: _ } => { |
| 339 | | - if let Some(username) = auth.take_authenticated() { |
| 395 | + tracing::debug!("Processing StartSession request"); |
| 396 | + if let Some((username, password)) = auth.take_authenticated() { |
| 340 | 397 | tracing::info!(%username, ?cmd, %session_type, "Session start requested"); |
| 341 | | - ( |
| 342 | | - Response::Success, |
| 343 | | - Some(SessionStartInfo { username, cmd, session_type }), |
| 344 | | - ) |
| 398 | + let info = SessionStartInfo { username, password, cmd, session_type }; |
| 399 | + tracing::debug!(?info, "Created SessionStartInfo"); |
| 400 | + (Response::Success, Some(info)) |
| 345 | 401 | } else { |
| 346 | 402 | ( |
| 347 | 403 | Response::Error { |