Drivers

防止 USB 外置硬碟休眠

  • October 4, 2021

有誰知道是否有一種優雅的方法可以告訴外部 USB 驅動器在一段時間不活動後不要減速?我已經看到基於 cron 的解決方案每分鐘寫入一個文件,但沒有任何 unixey 優雅的味道。必須有一個 hdparm 或 scsi 命令可以向驅動器發出(通過 OpenBSD 中的 sd 驅動程序訪問 USB 驅動器)來告訴它不要休眠。恐怕這可能是機箱中控制器內置的一個功能,因此除了將驅動器從機箱中取出並將其直接放入機器中之外,沒有什麼可以改變它,但我想我會問,在關閉的機會。

理想情況下,我正在尋找一個 OpenBSD 解決方案,但我知道還有其他人有同樣的問題,因此任何解決方案都將被考慮作為答案。

只是我的2美分…

降低磁碟轉速會降低其使用壽命是不言而喻的。多年的經驗表明,啟動和停止磁碟電機比 24/7 旋轉造成的疲勞要嚴重得多。我所有具有大量啟動/停止計數的磁碟都重新分配了扇區,並且我所有 24/7 旋轉 10 年的磁碟(信不信由你)都像新的一樣好。畢竟,磁碟是為旋轉而不是為空轉而製造的,因此如果您的優先級不是疲勞而不是功耗,請隨意讓您的磁碟 24/7 旋轉。

我有一個外部 2TB 磁碟,在閒置 30 分鐘後會停止運轉。該磁碟旨在 24/7 全天候供電以進行備份,並充當連接到 Orange PI 的小型 NAS。

我使用了以下 udev 規則

/etc/udev/rules.d

(它從來沒有工作,因為降速是在磁碟韌體中)

SUBSYSTEM=="usb", TEST=="power/autosuspend" ATTR{power/autosuspend}="-1"

雖然磁碟支持

hdparm -B

我寫了一個可以在啟動時執行的小守護程序

/etc/rc.local

在 cicles 中將目前日期和時間寫入日誌文件 10 次,因此磁碟始終處於開啟狀態。隨意修改。

命令行選項是:寫入 awake.log 的目標目錄和(可選)時間延遲(預設 300)

例如

/usr/sbin/disk_awake /mnt/some_disk/keep_alive 30

程式碼:(你可以用gcc編譯)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <time.h>

int main(int argc, char* argv[])
{
FILE *fp=NULL;
pid_t process_id=0;
pid_t sid=0;
int secs=300;
char log_file[512];
time_t raw_time;
struct tm *time_info;
int ticks=0;
unsigned long step=1;

if (argc<2||argc>3)
{
printf("Usage: %s target_directory [seconds]\n",argv[0]);
exit(1);
}
if (strlen(argv[1])>500)
{
printf("String length of target_directory is HUGE!\n");
exit(1);
}
if (chdir(argv[1])<0)
{
printf("Directory %s does not exist\n",argv[1]);
exit(1);
}
strcpy(log_file,argv[1]);
strcat(log_file,"/awake.log");
if (!(fp=fopen(log_file,"w+")))
{
printf("Could not open log file %s\n",log_file);
exit(1);
}
if (!(argv[2]))
{
printf("Delay argument not specified. Defaulting to 300 seconds\n");
secs=300;
}
if (argv[2]&&(secs=atoi(argv[2]))<=0)
{
printf("Could not parse delay option. Defaulting to 300 seconds\n");
secs=300;
}
printf("Delay interval %d seconds\n",secs);
process_id=fork();
if (process_id<0)
{
printf("Could not fork()\n");
exit(1);
}
if (process_id>0)
{
printf("Started with pid %d\n", process_id);
exit(0);
}
umask(0);
sid=setsid();
if(sid<0)
{
printf("Could not setsid()\n");
exit(1);
}
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
while (1)
{
if (ticks==10)
{
fclose(fp);
if (!(fp=fopen(log_file,"w+"))) exit(1);
ticks=0;step++;
}
time(&raw_time);
time_info=localtime(&raw_time);
fprintf(fp,"%s %lu : %s","Step",step,asctime(time_info));
fflush(fp);
ticks++;
sleep(secs);
}
fclose(fp);
return(0);
}

我發現以下 cronjob 對我有用。

*/5 * * * * /bin/touch /dev/sdb &>/dev/null

顯然用磁碟的設備名稱更新它。

您還可以根據驅動器在斷電前的空閒時間來改變時間。

引用自:https://unix.stackexchange.com/questions/5211