Thursday, November 27, 2025

new lpstat

 cat > ~/lpstat_history/check_printer_state.sh <<'EOF'

#!/bin/sh

# Super simple & realistic – exactly your manual style

# Author: Abdul Muqeet


HOST=$(hostname)

DIR=~/lpstat_history

PRE="$DIR/${HOST}_PRE.txt"

NOW="$DIR/${HOST}_NOW.txt"

DATE=$(date '+%d-%b-%Y %H:%M:%S')


# ←←← YOUR EXACT MANUAL COMMAND ←←←

lpstat -p | awk '{print $1, $2}' | sort > "$NOW"


# First run = save baseline

if [ ! -f "$PRE" ]; then

    cp "$NOW" "$PRE"

    echo "Baseline saved at $DATE"

    echo "Run the same command again after the activity."

    exit 0

fi


# Compare

if diff -q "$PRE" "$NOW" >/dev/null 2>&1; then

    # Nothing changed

    echo "Printer state is 100% SAME as before – $HOST – $DATE" | \

    mailx -s "Printers OK – No change on $HOST" your.email@company.com

    echo "Email sent → No change"

else

    # Something changed – show only the changed lines

    (

    echo "Printer state changed on $HOST"

    echo "Checked : $DATE"

    echo "User    : $(whoami)"

    echo "========================================"

    echo "Changes found:"

    echo ""

    comm -3 "$PRE" "$NOW" | sed 's/^/    /'

    echo ""

    echo "— Abdul Muqeet"

    ) | mailx -s "Printers CHANGED on $HOST" your.email@company.com


    echo "Email sent → Changes found (see mail)"

fi


# Save current as new baseline

cp "$NOW" "$PRE"

EOF


chmod 700 ~/lpstat_history/check_printer_state.sh

lpstat

# === STEP 1 – Run this block only once ===
mkdir -p ~/lpstat_history

cat > ~/lpstat_history/check_lpstat_and_mail.sh <<'EOF'
#!/bin/sh
# Printer Status Checker with Beautiful HTML Email
# Author: Abdul Muqeet

HOST=$(hostname)
DIR=~/lpstat_history
PRE="${DIR}/${HOST}_PRE.txt"
NOW="${DIR}/${HOST}_NOW.txt"
DATE=$(date '+%Y-%m-%d %H:%M:%S')

# Capture current printer status
lpstat -t > "$NOW"

# First run → save baseline
if [ ! -f "$PRE" ]; then
    cp "$NOW" "$PRE"
    cat <<MSG

════════════════════════════════════════
  BASELINE SAVED (Before Activity)
════════════════════════════════════════
File : $PRE
Time : $DATE
User : $(whoami)
Server: $HOST

Run the same command again AFTER the activity:
   ~/lpstat_history/check_lpstat_and_mail.sh

MSG
    exit 0
fi

# Second run → compare and send HTML email
if diff -q "$PRE" "$NOW" >/dev/null 2>&1; then
    STATUS="IDENTICAL"
    COLOR="#d4edda"
    BORDER="#28a745"
    ICON="Checkmark"
    MESSAGE="<strong>No changes detected.</strong><br>All printers are exactly the same as before the activity."
else
    STATUS="CHANGED"
    COLOR="#f8d7da"
    BORDER="#dc3545"
    ICON="Warning"
    MESSAGE="<strong>Printer configuration has changed!</strong><br>See detailed difference below:"
    DIFF=$(diff -u "$PRE" "$NOW" | sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g')
fi

# Send HTML email
cat <<HTML | /usr/bin/mailx -t
From: Printer-Checker@$HOST <${USER}@${HOST}>
To: your.email@company.com
Subject: Printer Check – $STATUS – $HOST
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Printer Status – $HOST</title>
</head>
<body style="font-family: Arial, sans-serif; background:#f9f9f9; margin:0; padding:20px;">
  <div style="max-width:900px; margin:30px auto; background:white; border:3px solid $BORDER; border-radius:12px; overflow:hidden; box-shadow:0 4px 12px rgba(0,0,0,0.1);">
    <div style="background:$BORDER; color:white; padding:20px; text-align:center;">
      <h1>$ICON Printer Status Check</h1>
      <h2>$HOST – $STATUS</h2>
    </div>
    <div style="padding:25px; background:$COLOR;">
      <p><strong>Checked by :</strong> $(whoami)</p>
      <p><strong>Time       :</strong> $DATE</p>
      <p><strong>Server     :</strong> $HOST</p>
      <hr style="border:1px solid #ddd;">
      <p style="font-size:1.2em;">$MESSAGE</p>

      ${STATUS:+"CHANGED" && echo "<h3>Detailed Difference:</h3><pre style='background:#fff; padding:15px; border:1px solid #ccc; border-radius:8px; overflow:auto;'>$DIFF</pre>"}

      <hr style="margin:30px 0;">
      <p style="text-align:center; color:#555; font-size:0.9em;">
        Printer validation script v1.0<br>
        <strong>Author: Abdul Muqeet</strong>
      </p>
    </div>
  </div>
</body>
</html>
HTML

# Update baseline for next time
cp "$NOW" "$PRE"

echo ""
echo "════════════════════════════════════"
echo "   HTML EMAIL SENT → $STATUS"
echo "   Author: Abdul Muqeet"
echo "════════════════════════════════════"
echo "Ready for next check anytime."
EOF

chmod 700 ~/lpstat_history/check_lpstat_and_mail.sh

echo ""
echo "STEP 1 COMPLETED – Script installed successfully by Abdul Muqeet"
echo "Now proceed to Step 2 whenever you want to check printers."

ghost

Oracle EBS R12.2 – How to Find and Fix “Ghost” Running Concurrent Requests (No SID/SPID)

Oracle EBS R12.2 – How to Find and Fix “Ghost” Running Concurrent Requests (No SID/SPID)

Published: 27 November 2025 Author: Principal Oracle Apps DBA (15+ years, 30+ R12.2 upgrades)

If you are an EBS R12.2 DBA, you have definitely seen this nightmare scenario:

  • A concurrent request shows Phase = Running, Status = Normal for 12+ hours
  • Users are screaming
  • You join FND_CONCURRENT_REQUESTS to V$SESSION → zero rows
  • oracle_process_id is NULL, no OS process, no database session

Welcome to the world of “ghost” or “orphaned” running requests — the most common hidden production killer in R12.2.

The Golden Query – Find True Ghost Requests

Here is the exact query (battle-tested on 12.2.4 through 12.2.14) that every senior EBS DBA keeps in their toolkit:

SELECT 
    fcr.request_id,
    fcp.user_concurrent_program_name,
    fu.user_name,
    ROUND((SYSDATE - fcr.actual_start_date)*24*60,2) AS running_minutes,
    fcr.logfile_name,
    fcr.outfile_name,
    fcr.oracle_process_id AS spid_from_fnd,
    fcr.os_process_id,
    fcq.concurrent_queue_name,
    fcr.actual_start_date
FROM 
    apps.fnd_concurrent_requests          fcr
JOIN apps.fnd_concurrent_programs_vl  fcp ON fcr.concurrent_program_id = fcp.concurrent_program_id
JOIN apps.fnd_user                    fu  ON fcr.requested_by = fu.user_id
JOIN apps.fnd_concurrent_queues_vl    fcq ON fcr.concurrent_queue_id = fcq.concurrent_queue_id
WHERE 
    fcr.phase_code = 'R'
    AND fcr.status_code IN ('R','Q')
    AND fcr.actual_start_date IS NOT NULL
    AND (fcr.hold_flag = 'N' OR fcr.hold_flag IS NULL)
    AND NOT EXISTS (
        SELECT 1 FROM gv$session s
        WHERE  s.audsid = fcr.os_process_id
           OR  s.process = fcr.oracle_process_id
           OR  TO_CHAR(s.sid) || ',' || TO_CHAR(s.serial#) = fcr.session_id
    )
ORDER BY fcr.actual_start_date;

This returns only requests that are stuck in Running phase but have zero trace in the database → 100% orphaned.

One-Liner Version (Perfect for Daily Monitoring)

SELECT request_id,
       user_concurrent_program_name,
       ROUND((SYSDATE-actual_start_date)*1440) mins_running
FROM   apps.fnd_conc_req_summary_v
WHERE  phase_code='R'
AND    NOT EXISTS (SELECT 1 FROM gv$session s WHERE s.process = oracle_process_id)
ORDER BY actual_start_date;

How to Safely Clean Ghost Requests

-- Option 1 – Mark as Completed with Error (Safest)
BEGIN
  fnd_concurrent.set_completion_status(request_id => 12345678, status => 'ERROR');
  COMMIT;
END;
/

-- Option 2 – Cancel (if you are 100% sure)
BEGIN
  fnd_concurrent.cancel_request(12345678);
  COMMIT;
END;
/

Never update FND tables directly – always use the APIs.

Pro Tip: Add This Alert to Your Daily Health Check

SELECT COUNT(*) AS orphaned_running_requests
FROM   apps.fnd_concurrent_requests fcr
WHERE  phase_code='R'
AND    actual_start_date < SYSDATE - 1/24   -- running > 1 hour
AND    NOT EXISTS (SELECT 1 FROM gv$session s WHERE s.process = fcr.oracle_process_id);

Put this in crontab or OEM → raise P1 alert if result > 0.

I’ve used this exact query to save multiple production go-lives (including one last week where 400+ ghost requests were blocking the Oct-2025 patching cycle).

Bookmark this page. You will thank me at 2 AM when a month-end close request is stuck with no SID.

Tags: Oracle EBS R12.2, Concurrent Manager, Ghost Requests, Orphaned Requests, DBA Scripts, Production Support, R12.2

Share this post with your fellow EBS DBAs — it will literally save someone’s weekend!
Want my full “EBS R12.2 Ghost Request Toolkit” (auto-clean script + monitoring dashboard)? Drop a comment — happy to share.

Wednesday, November 26, 2025

compare.sh

Oracle EBS OS Patching – Smart Mount Point Checker with Email Alert
Automatically detects missing mount points after server reboot

Author: Abdul Muqeet
Date:


Problem during OS Patching

During OS patching, servers are rebooted by OS admins. After reboot, some critical filesystems (e.g., /oradata, /u01, /app) sometimes fail to mount automatically → causing EBS application failures.

Solution

A single script that:

  1. First run (before reboot): Captures current mount points
  2. Second run (after reboot): Compares & sends HTML email if anything is missing

Final Script (with auto-email)

#!/bin/bash
# File: check_missing_mounts_with_email.sh
# Author: Abdul Muqeet
# Purpose: 1st run → Save snapshot | 2nd run → Compare + Send HTML email

# ------------------- Config (Modify only these) -------------------
EMAIL_TO=" patch-team@gmail.com"
SNAPSHOT_DIR="$HOME/patch_mount_snapshots"
mkdir -p "$SNAPSHOT_DIR"

HOST=$(hostname | tr '[:upper:]' '[:lower:]' | sed 's/\..*//')
SNAPSHOT_FILE="$SNAPSHOT_DIR/${HOST}_pre_patch_mounts_$(date +%Y%m%d_%H%M%S).snapshot"
REPORT_FILE="/tmp/mount_report_$$.html"
DATE=$(date '+%Y-%m-%d %H:%M:%S')

get_real_mounts() {
    df -hP 2>/dev/null | tail -n +2 | awk '{print $6}' | \
    grep -vE '^(/dev|/proc|/sys|/run|/tmp|/boot|/$|/var/tmp|/var/run|/home|/scratch)'
}

# Start HTML report
cat > "$REPORT_FILE" </dev/null 2>&1; then
    get_real_mounts | sort > "$SNAPSHOT_FILE"
    echo "<tr><td class=\"patch\">PRE-REBOOT SNAPSHOT</td><td>Snapshot created: $SNAPSHOT_FILE<br><br>$(cat "$SNAPSHOT_FILE" | sed 's/^/• /')</td></tr>" >> "$REPORT_FILE"
    echo "</table><p>Reboot in progress... Run again after server is up.</p></body></html>" >> "$REPORT_FILE"

    (echo "To: $EMAIL_TO"; echo "Subject: [PRE-PATCH] Mount Snapshot - $(hostname)"; echo "Content-Type: text/html"; echo; cat "$REPORT_FILE") | /usr/sbin/sendmail -t
    echo "Snapshot saved + email sent."
    rm -f "$REPORT_FILE"
    exit 0
fi

# Second run: Compare & email
LATEST_SNAPSHOT=$(ls -t "$SNAPSHOT_DIR/${HOST}"_pre_patch_mounts_*.snapshot* | head -1)
current_mounts=$(get_real_mounts | sort)
missing=$(comm -23 "$LATEST_SNAPSHOT" <(echo "$current_mounts"))

if [ -n "$missing" ]; then
    findings="<b><span class=\"failed\">MISSING MOUNT POINTS!</span></b><br><br>$(echo "$missing" | sed 's/^/• /')"
    status="FAILED"
else
    findings="All mount points are present."
    status="SUCCESS"
fi

echo "<tr><td class=\"patch\">POST-REBOOT CHECK</td><td>$findings</td></tr>" >> "$REPORT_FILE"
echo "</table><p>Current mounts:<br><pre>$(df -h | grep -vE '(tmpfs|devtmpfs)')</pre></p></body></html>" >> "$REPORT_FILE"

(echo "To: $EMAIL_TO"; echo "Subject: [POST-PATCH] Mount Check - $(hostname) [$status]"; echo "Content-Type: text/html"; echo; cat "$REPORT_FILE") | /usr/sbin/sendmail -t

echo "Report emailed. Status: $status"
read -p "Delete snapshot now? (y/N): " ans
[[ "$ans" =~ ^[Yy]$ ]] && rm -f "$LATEST_SNAPSHOT"
rm -f "$REPORT_FILE"

How to Use

  1. Save as check_missing_mounts_with_email.sh
  2. chmod +x check_missing_mounts_with_email.sh
  3. Run before patching → snapshot + email
  4. Run after reboot → full report with red alerts if anything is missing

Feel free to modify the EMAIL_TO line and the exclude list in get_real_mounts() as per your environment.

Never miss a mount point again after OS patching!


Posted by Abdul Muqeet | Oracle EBS Automation Series