Huyền thoại về khôi phục dữ liệu Unix
Bạn đã bao giờ để cái terminal đã đăng nhập và rời khỏi nó, chỉ để tìm một thứ gì đó rồi quay lại và thằng bạn của bạn (được cho là) đã nhập “rm -rf ~/*” và tay của nó đặt trên phím Enter rồi đe doạ “Hoặc đưa tao mượn 5 đô tới thứ 5 hoặc là tao nhấn phím Enter“.
Chắc chắn rằng thằng bạn đó nó không bị thần kinh mà gây tai hoạ vậy đâu, nó chỉ đùa thôi. Vì vậy, có lẽ bạn chưa bao giờ trải qua những thảm họa tồi tệ nhất….
Đó là một buổi chiều thứ tư yên tĩnh. Thứ tư, 1 tháng 10, 15:15 BST (Giờ mùa hè Anh), khi mà Peter, một người đồng nghiệp của tôi, rời khỏi màn hình anh ấy và nói với tôi, “Mario, tôi có một chút vấn đề về việc gửi mail“. Biết là việc đọc cái thông báo đó khá khó khăn, tôi liền lại gần cái máy của anh ta để kiểm tra xem có lỗi gì hay không. Một cái thông báo lỗi khá kì lạ mà tôi thấy (tôi cũng không nhớ chính xác nó là gì) là “cannot access /foo/bar for userid 147“. Trong đầu tôi ngay lập tức dấy lên sự nghi vấn là “Userid 147 là của ai nhỉ?; người gửi tin nhắn, người nhận, hay là cái gì?“. Vì vậy tôi liền đi tới cái máy khác với Terminal đã được đăng nhập sẵn và nhập
grep 147 /etc/passwd
Và chỉ nhận được phản hồi
/etc/passwd: No such file or directory.
Ngay lập tức, tôi nhận ra có gì đó thực sự không ổn và ngay lập tức tôi nhập:
ls /etc
Và kết quả là
ls: not found.
Tôi khuyên Peter là tốt nhất để mọi thứ ở yên vị trí một lúc, và tức tốc chạy đi tìm người quản trị hệ thống.
Khi mà tôi đến cái văn phòng của anh ta, cánh cửa hé ra và trong vòng 10 giây tôi nhận ra vấn đề kinh thiên động địa đó là gì. James, người quản lý của chúng tôi, ngồi đó, tay ôm đầu, tay để giữa hai đầu gối, như là cả thế giới mới vừa bị sụp đổ. Lập trình viên hệ thống mới được bổ nhiệm của chúng tôi, Neil, ngồi bên cạnh anh ấy, thẫn thờ ngồi nhìn vào màn hình Terminal của anh ta. Và ngay trên cùng của màn hình, tôi đã thấy thứ kinh hãi như sau:
# cd
# rm -rf *
Ôi thôi rồi, chẳng còn gì để nói nữa, thì ra đó là lý do của mọi việc.
Tôi không thể nhớ được những gì diễn ra tiếp theo những phút sau đó; trí nhớ của tôi nhạt nhoà dần. Tôi nhớ là tôi có thử ls (lần nữa), ps, who và có thể là một ố lệnh khác, tất cả đều chẳng còn hoạt động được. Điều kế tiếp mà tôi nhớ tôi có làm đó chính là quay về máy của tôi với cái Terminal (Terminal đồ hoạ đa cửa sổ), và nhập
cd /
echo *
Tôi nợ một lời cảm ơn sâu sắc cho David Korn vì đã tạo một cái hàm echo dựng sẵn trong cái shell của anh ấy; và tất nhiên, /bin, cùng với /bin/echo, đã bị xoá sạch. Và những gì diễn ra kế tiếp là /dev, /etc và /lib đã đi vào dĩ vãng; may mắn thay, Neil đã ngừng lệnh rm khi mà nó vừa xoá tới /news, và /tmp, /usr và /users đều chưa bị động đến.
Trong khi đó James đã kiểm tra cái tủ băng dữ liệu của chúng tôi và đã nhận được cái được cho là một cuốn băng dữ liệu bị bỏ đi của hệ thống tệp root, mất 4 tuần trước. Câu hỏi cấp bách là, “Làm sao mà chúng ta khôi phục dữ liệu của cái cuộn băng dữ liệu đó đây?“. Không chỉ chúng ta đã mất /etc/restore, mà còn tất cả những đầu vào thiết bị của cuộn băng đã bị biến mất. Và cái mknod nằm ở đâu? Bạn đoán ra rồi đó, /etc. Thế còn khôi phục dữ liệu qua Ethernet từ một cái VAX khác (VAX là tên của máy tính đời 198X đến 199X [1])? Ừ thì, /bin/tar đã biệt tích và thật chu đáo khi những người bên đại học Berkeley đã đặt rcp trong mục /bin từ bản phân phối 4.3. Hơn nữa, làm sao mà kết nối Ethernet được khi không có cái tối thiểu là /etc/hosts chứ? Chúng tôi đã tìm thấy một phiên bản của cpio trong /usr/local, nhưng điều đó không có nghĩa là chúng ta sẽ khôi phục được mà không có cái băng chứa dữ liệu gốc.
Hoặc là, chúng ta có thể khởi động cái băng và xây dựng lại hệ thống file gốc, nhưng mà cả James lẫn Neil vẫn chưa bao giờ làm trước đó, và chúng tôi cũng không chắc rằng điều đầu tiên sẽ xảy ra với cả hệ thống đĩa, có thể nó sẽ bị format lại và toàn bộ dữ liệu của user đều biến mất (Chúng tôi thường xoá dữ liệu người dùng vào mỗi thứ năm, nhưng theo định luật Murphy [2] cái chuyện này lại xảy ra vào thứ 4). Một cách khác là có thể mượn đĩa dữ liệu từ một cái VAX khác, tắt máy đó và dọn dẹp sau. Nhưng bắt buộc ít nhất phải gọi tới kỹ sư DEC để có thể thao tác được. Chúng tôi có một số lượng -người dùng đang viết luận văn tiến sĩ và có thể sẽ mất khoảng một tuần làm việc (chưa kể downtime của máy), điều đó không khả thi.
Vậy, giờ làm gì được nữa? Một ý tưởng kế tiếp là viết một chương trình để làm một cái mô tả device cho cái băng dữ liệu, nhưng chúng ta đều biết nơi mà cc, as và ld vẫn còn tồn tại. Hoặc là làm một cái khung sườn đầu vào cho /etc/passwd, /etc/hosts và nhiều hơn thế nữa, vậy nên /usr/bin/ftp có thể hoạt động. May mắn thay, tôi vẫn còn cái gnuemacs vẫn đang chạy trong 1 trong những cái cửa sổ làm việc của tôi, cái mà chúng ta có thể tạo passwd, .v.v. Nhưng bước đầu tiên là tạo một cái directory để đặt chúng vào. Tất nhiên là /bin/mkdir và /bin/mv đã tan biến vào không trung, vì vậy chúng tôi không thể đổi tên /tmp sang /etc được. Tuy nhiên có vẻ đây là cách khá là hợp lý.
Nhóm của chúng tôi có thể sự gia nhập của Alasdair, giáo viên UNIX thường trú của chúng tôi, và may mắn là ông ấy biết về trình biên dịch VAX. Vì vậy kế hoạch của chúng tôi sẽ diễn ra như sau: viết chương trình bằng trình biên dịch mà nó có thể đổi tên /tmp sang /etc, tập trung nó trên một cái VAX khác, uuencode nó, nhập vào cái file uuencode bằng cái GNU của tôi, rồi uudecode nó (có vài ý tưởng cho rằng đặt uudecode trong /usr/bin), chạy nó, và xong, kế hoạch sẽ suông sẻ kể từ đó. Một điều kì diệu nữa là cái Terminal bị hư hại đã trở lại bình thường với lệnh su (su nằm trong mục /bin, nhớ chứ?) vì vậy ít nhất chúng tôi cũng đã có một cơ hội cho việc làm này.
Và chỉ trong vòng 1 giờ, chúng tôi đã cố gắng tạo hàng tá dòng lệnh để tạo /etc. Mã nhị phân bị giới hạn chỉ còn dài 76 bytes, vì vậy chúng tôi chuyển nó qua hex (dễ đọc hơn chút với đầu ra của uuencode), và nhập vào nó bằng cái editor của tôi. Nếu có bất kỳ ai gặp vấn đề tương tự, đây là đoạn hex để tham khảo trong tương lai:
070100002c000000000000000000000000000000000000000000000000000000 0000dd8fff010000dd8f27000000fb02ef07000000fb01ef070000000000bc8f 8800040000bc012f65746300
Tôi có một chương trình khá tiện lợi để chuyển ASCII hex sang mã nhị phân, và output của /usr/bin/sum được đếm với đoạn mã nhị phân ban đầu của chúng tôi. Nhưng đợi đã… Làm sao mà bạn set quyền thực thi mà không có /bin/chmod? Và sau một vài giây suy nghĩ (thường là vài phút) tôi đề nghị mọi người sẽ viết mã nhị phân trên đầu phần nhị phân có sẵn, sở hữu bởi tôi…vấn đề đã được giải quyết. Chúng tôi liền phi nước đại mà đăng nhập root, cẩn thận set umask bằng 0 (để tôi có thể tạo file bằng cái GNU của tôi) và chạy đoạn mã nhị phân trên. Và ngay lập tức, chúng tôi đã có /etc, có thể ghi dữ liệu vào một cách ổn thoả. Từ đó, chúng tôi dùng cách tương tự mà tạo lại passwd, hosts, services, protocols,.v.v., và cuối cùng là ftp cũng đã được tạo lại hoàn tất. Sau đó chúng tôi khôi phục dữ liệu của /bin thông qua ethernet (thật tuyệt vời bao nhiêu khi bạn bắt đầu nhớ ls sau một lúc, vài giờ ngắn ngủi) và những file được chọn từ /etc. Cái file key đã nằm trong /etc/restore, với cái mà chúng tôi đã phục hồi là /dev từ cái cuộn băng bị vứt, và phần còn lại đã đi vào lịch sử.
Bây giờ, bạn đang tự hỏi chính mình (như tôi), cái chốt lại của câu chuyện này là gì? Ừ thì, chỉ một điều thôi, bạn phải luôn nhớ cụm từ bất hủ, ĐỪNG HOẢNG LOẠN. Phản ứng ban đầu của chúng tôi là khởi động lại máy và thử mọi thứ chỉ bằng quyền của 1 người dùng, nhưng sẽ không là gì nếu không có /etc/init và /bin/sh. Suy nghĩ hợp lý đã cứu chúng tôi khỏi hoàn cảnh trớ trêu này.
Cái điều kế tiếp cần nhớ rằng các công cụ UNIX có thể rất hữu dụng trong một số trường hợp bất đắc dĩ. Kể cả không có cái gnuemacs của tôi, chúng tôi có thể vượt qua điều này bằng cách dùng /usr/bin/grep như là thay thế cho /bin/cat
Và điều cuối cùng là, thật đáng ngạc nhiên khi mà biết bao nhiêu phần của hệ thống đã bị xoá mà nó không bị sập hoàn toàn. Tực tế ra chả có ai đăng nhập được (/bin/login?), và hầu hết những câu lệnh có ích đã biến mất, mọi thứ khác dường như bình thường. Tất nhiên, một vài thứ sẽ khoogn thế tồn tại mà không có /etc/termcap, hoặc /dev/kmem hay là /etc/utmp, nhưng sau tất cả, chúng đều có sự liên kết chặt chẽ với nhau.
Tôi sẽ dành cho bạn câu hỏi này: nếu bạn bị đặt vào tình huống tương tự và có sự hiện diện của tâm trí luôn đi kèm với nhận thức muộn màn, bạn có thể thoát khỏi nó theo cách đơn giản hay dễ dàng hơn không? Hãy để lại câu trả lời phía dưới nhé!
(Tác giả: Mario Wolczko)
Chỉnh sửa lần cuối (bài gốc): Thu Mar 7 13:47:40 EST 1996
Tham khảo:
[1]: VAX là một dạng máy tính đời cũ, bạn có thể xem ví dụ về nó ở ảnh 2
[2]: Định luận Murphy: Nếu một điều tồi tệ có thể xảy ra, nó sẽ xảy ra vào thời điểm tệ nhất