Làm thế nào để init nhận biết về các sự kiện quyền lực?


8

Tôi có một Pi Model B Rev 2.0 (tôi nghĩ) và tôi dự định sử dụng nó cho hệ thống Tự động hóa gia đình. Khi tôi có một đồng hồ trả trước về nguồn điện của mình, thỉnh thoảng tôi hết điện tử để đi xung quanh Nguồn cung cấp chính của nhà tôi!

Để tránh sự cố, tôi đã lấy một UPS dưới dạng UPis Basic do PiModules sản xuất . Tôi đã cấu hình nó để tôi có thể thăm dò các điện áp cung cấp thông qua cổng nối tiếp của Pi (không phải cấu hình mặc định mà là một thiết lập được hỗ trợ được ghi lại trong tài liệu hướng dẫn ).

Hiện tại, nó sử dụng chân GPIO chuyên dụng (chân 13 trên tiêu đề, tôi tin rằng GPIO27) và bộ điều khiển vi mô tích hợp sử dụng mã đó và tập lệnh python chạy từ RC.local để báo cho Pi biết shutdown -h nowkhi nào pin bị hạ thấp - xảy ra khi nhấn nút "Tắt máy" của UPS hoặc nếu nguồn cung cấp pin hết mức nghiêm trọng trong trường hợp mất nguồn chính. Đối với bản ghi, kịch bản là:

#!/usr/bin/python

# import the  libraries to use time delays, send os commands and access GPIO pins
import PRi.GPIO as GPIO
import time
import os

GPIO.setmode(GPIO.BCM) # Set pin numbering to board numbering
GPIO.setup(27, GPIO.IN, pull_up_don=GPIO.PUD_UP) # Setup pin 27 as an input
while True: # Setup a whille loopto wait for a button press
    if(GPIO.input(27)==0): # Setup an if loop to run a shutdown command when button press sensed
        os.system("sudo shutdown -h now") # Send shutdown command to os
        break
    time.sleep(1) # Allow a sleep time of 1 second to reduce CPU usage

Điều này gây ấn tượng với tôi như một chút không liên quan được đưa ra initcó khả năng tích hợp để xử lý các sự kiện sức mạnh. Tôi nên nhắc lại rằng tôi đang sử dụng sysVinit trên Raspbian Jessie KHÔNG phải là systemd mặc định cho bản phát hành đó (vì lý do cá nhân và lý do quen thuộc).

Ban đầu, tôi muốn thay thế đoạn script trên bằng một cái gì đó bảo init thực hiện nó powerfailnowkhi pin xuống thấp - và thực hiện powerokwaitnếu nó sau đó trả về mức cao. Cuối cùng tôi cũng muốn thăm dò ý kiến các cổng nối tiếp và giữ một mắt trên những câu trả lời @rpi, @bat@upsđó trả lại điện áp hiện hành về đường sắt 5V của Pi, pin LiPo và UPis sở hữu microUSB đầu vào tương ứng - vì vậy mà Pi có thể đưa ra một cảnh báo trên / xử lý sự cố mất điện (nó sẽ dẫn đến powerfailhành động init và để Pi báo cáo tình trạng mất điện cho tôi, người dùng - giả sử tôi chưa sẵn sàng nhận thấy!)

Tuy nhiên tôi đang gặp khó khăn trong việc tìm hiểu cách thức các thiết bị Linux UPS hiệu cho initrằng powerfail\ powerwait\ powerfailnow\ powerokwaitlệnh quy định tại \etc\inittabnên được thực hiện.

Chẳng hạn, ai đó có thể tư vấn cho tôi, làm thế nào UPS "trưởng thành" nói với nhân Linux trên PC bình thường rằng các sự kiện "sức mạnh" đang xảy ra và làm thế nào tôi có thể tái tạo tương tự trong hệ thống này trên Pi không?


Cảm ơn @ Jacobm001 vì đã phát hiện ra sự vắng mặt của thẻ cho phần Python-ish của Câu hỏi này, trong vài giờ qua tôi đã trải qua một khóa học về ngôn ngữ (tôi đang thực hiện một số bước tiến) nhưng một thời gian ngắn trước đây tôi sẽ Tôi đã biết Asp của tôi từ khuỷu tay của tôi ...
SlySven

Tôi cũng tò mò làm thế nào Pi (hoặc init) biết về các sự kiện quyền lực. Hy vọng ai đó trả lời sớm.
PNDA

Tôi sẽ xem xét acpid và có lẽ bạn có thể thay đổi tập lệnh của mình để phản ứng khi có gì đó thay đổi (pin cao -> thấp) thay vì bỏ phiếu giá trị mỗi giây?
Diederik de Haas

2
@ PandaLion98 Phần cứng Pi không có bất kỳ sự kiện sức mạnh nào, vì vậy không có gì để biết về chúng. Nếu một số được triển khai, init sẽ chỉ biết về chúng nếu được thông báo bằng kernel (vì sự kiện trình điều khiển, trong trường hợp pi có thể là trình điều khiển cho một số phần cứng bổ sung) hoặc thông qua ứng dụng đất của người dùng.
goldilocks

Câu trả lời:


5

À, ha! Một số đoạn văn trong các trang người đàn ông cho init(8)đề cập đến việc khấu hao giao diện viết một giá trị một bức thư gửi /etc/powerstatus(nay được thay thế bằng /var/run/powerstatus) và sau đó gửi initmột SIGPWRtín hiệu; bức thư nên là một trong:

  • ' F ' ốm yếu điện: [quyền lực chính đã thất bại và] UPS được cung cấp sức mạnh, thực hiện powerwaitpowerfailmục.
  • Power ' O ' kay: [main] sức mạnh đã được khôi phục, thực hiện powerokwaitmục nhập.
  • ' L điện ow': sức mạnh là không và UPS có một [nghiêm túc] pin thấp, thực hiện powerfailnownhập cảnh.
Nếu tệp được chỉ định không tồn tại hoặc chứa bất cứ thứ gì ngoài các chữ cái F, Ohoặc L, init sẽ hoạt động như thể nó đã đọc chữ cái F.

Bên dưới đây là lời khuyên:

Cách sử dụng SIGPWR/etc/powerstatuskhông được khuyến khích. Ai đó muốn tương tác initnên sử dụng /run/initctlkênh điều khiển - xem mã nguồn của sysvinitgói để biết thêm tài liệu về điều này.

Vì vậy, trong khi đây có thể là một câu trả lời thì đó không phải câu trả lời - tiếp theo, tôi cần xem mã nguồn được giữ như một dự án không phải GNU được lưu trữ tại trang web lưu trữ của GNU .


1

Tôi đoán cách tiếp cận sạch nhất sẽ là có trình điều khiển thiết bị kernel quản lý GPIO27 và được thiết lập để nhận một ngắt khi nó xuống thấp. Trình xử lý ngắt sẽ thông báo cho init. Trang http://elinux.org/RPi_Low-level_perodesals nói rằng Raspbian Wheezy hỗ trợ ngắt GPIO.

Tôi xin lỗi vì phản hồi chất lượng thấp, tôi đã không xem xét trình điều khiển gpio của Linux và cách mở rộng / nâng cao chúng. Tôi cũng không tra cứu phương thức được phê duyệt hiện tại để thông báo init từ bên trong một trình xử lý ngắt. Hy vọng bài đăng này sẽ kích thích phản ứng tốt hơn.


Vâng, một ngắt có vẻ tốt hơn bỏ phiếu - Diederik de Haas đã đề cập ở trên. Trọng tâm điều tra của tôi hiện tại là "Trình xử lý ngắt sẽ thông báo cho init ..." đó là cơ chế gây bối rối, powerstattín hiệu tệp / SIGPWR trông tương đối đơn giản và dễ hiểu nhưng dường như không được chấp nhận. Bây giờ tôi đang cố gắng tìm hiểu về cách sử dụng initctlđường ống thực tế ...
SlySven

1

Bằng cách đào sâu vào mã nguồn của SysV initcó sẵn từ máy chủ Savannah của Tổ chức Phần mềm Tự do, tôi có thể gửi yêu cầu tới RPi's của mình initbằng cách điền vào một struct init_requestchi tiết trong initreq.htệp tiêu đề. Cụ thể, điều này đòi hỏi magic, sleeptimevà, cho mục đích của tôi, các cmdtrường được điền vào, với trường sau được đặt thành một INIT_CMD_POWERFAIL, INIT_CMD_POWERFAILNOWhoặc INIT_CMD_POWEROK.

Trình nền / chương trình của tôi cần được chạy với tư cách là người dùng có quyền ghi vào ống điều khiển init {ban đầu /dev/initctrlnhưng đã chuyển sang Debian và do đó Raspbian đến /run/initctrl} sau đó có thể gửi cấu trúc initđó để sau đó trả lời thích hợp bằng cách trả lời các mục sau trong /etc/inittab:

# What to do when the power fails/returns.
pf::powerwait:/etc/init.d/powerfail start
pn::powerfailnow:/etc/init.d/powerfail now
po::powerokwait:/etc/init.d/powerfail stop

Lưu ý: giao diện này - hoặc ít nhất là thông báo cung cấp điện KHÔNG được chấp nhận bởi răng nanh mới systemd- mặc dù, bởi những gì có thể được coi là một chút của chương trình sùng bái hàng hóa, nó cố gắng đảm bảo rằng initctrlđường ống tồn tại. Mặt khác, điều này thực hiện chính xác những gì tôi muốn nó làm trên hệ thống RPi của tôi!


Mặc dù tôi ngưỡng mộ sự cống hiến của bạn cho vấn đề này của bạn, tôi không thể không nhận thấy rằng bạn đã dành một lượng thời gian đáng kể để thực hiện một giải pháp tương đương về mặt chức năng với kịch bản ban đầu của bạn và thậm chí không phải là bằng chứng trong tương lai.
Dmitry Grigoryev

Chà, trong khi nó có chức năng tương đương với hệ thống ban đầu, nó sử dụng giao diện được cung cấp được đề xuất thay vì giao diện không dùng nữa. Để chứng minh trong tương lai, những người viết hệ thống tương lai sẽ không thực hiện giao diện đã biết của hệ thống mà họ đang cố gắng thay thế để đảm bảo khả năng tương thích ngược nếu có thể.
SlySven

Rốt cuộc, việc nhận được thông báo về sự cố mất điện chính là khá quan trọng đối với một hệ thống có UPS, do đó, một người quản lý hệ thống / quy trình đàng hoàng phải nhận thức được cách mà người tiền nhiệm đã làm mọi thứ và tìm kiếm các quy trình khác bằng API đó - một giao diện tồn tại nhưng bị bỏ qua có vẻ hơi thiển cận ... 8- / Theo mã tại: github.com/systemd/systemd/blob/master/src/initctl/initctl.c tất cả một UPS nói systemdrằng nguồn điện chính bị hỏng Cách này sẽ ghi thông báo: "Đã nhận được yêu cầu UPS / power initctl. Điều này không được thực hiện trong systemd. Nâng cấp trình nền UPS của bạn!"
SlySven

"Điều này không được triển khai trong systemd. Nâng cấp trình nền UPS của bạn" - đó là tất cả những gì bạn cần biết về khả năng tương thích ngược trong Linux;)
Dmitry Grigoryev

Các initctlgiao diện để van Smoorenburg init được khai báo là private và không cho các bên thứ ba bằng một trong (lúc đó) bảo trì của chương trình sao lưu vào năm 2012. Miquel van Smoorenburg của powerd, sau đó Tom Webster genpowerd, ban đầu sử dụng các /etc/powerstatuscơ chế.
JdeBP
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.