> For the complete documentation index, see [llms.txt](https://huataihuang.gitbook.io/cloud-atlas-draft/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://huataihuang.gitbook.io/cloud-atlas-draft/virtual/libvirt/hook/hooks_for_specific_system_management.md).

# 通过libvirt hooks实现特定系统管理

## libvirt定制事件脚本

从libvirt 0.8.0开始，host主机的特定事件可以触发定制脚本。

这些定制`hook`脚本在一下情况下触发：

* libvirt服务启动，停止或重新加载配置 - 版本0.8.0开始
* QEMU guest启动或停止 - 版本0.8.0开始
* LXC guest启动或停止 - 版本0.8.0开始
* libxl接管的Xen guest启动或停止 - 版本2.1.0开始
* 网络启动或停止，或者网络的接口插入/拔出 - 版本1.2.2开始

## 定制脚本位置

libvirt hook脚本位于目录`$SYSCONFDIR/libvirt/hooks/`:

* 在Linux发行版，例如Fedora和RHEL，默认是`/etc/libvirt/hooks/`目录
* 如果是从源代码编译libvirt，则可能位于`/usr/local/etc/libvirt/hooks/`目录

要使用hook脚本，需要手工创建`hooks`目录，并且将hook脚本存放到该目录中，并设置脚本可执行。

## 脚本命名

如上所述，以下是5个脚本调用名称：

* `/etc/libvirt/hooks/daemon`

libvirt服务启动，停止或重新加载配置时执行

* `/etc/libvirt/hooks/qemu`

QEMU guest启动、停止或迁移时执行

* `/etc/libvirt/hooks/lxc`

LXC guest启动或停止时执行

* `/etc/libvirt/hooks/libxl`

libxl接管的Xen guest启动、停止或迁移时执行

* `/etc/libvirt/hooks/network`

网络启动或停止，或者网络的接口插入/拔出时执行

## 脚本结构

hook脚本执行使用标准的Linux进程创建功能，使用以下命令解释器：

```
#!/bin/bash
```

或者

```
#!/usr/bin/python
```

> 可以使用任何可执行代码，也就是可以使用自己希望的语言
>
> **注意**：`bash`脚本开头必须设置好解释器，否则会出现（假设这里虚拟机名字是`example_virt_guest`）执行格式错误：

```
error: Hook script execution failed: internal error: Child process (LC_ALL=C PATH=/sbin:/usr/sbin:/bin:/usr/bin HOME=/home/admin USER=admin LOGNAME=admin /etc/libvirt/hooks/qemu example_virt_guest prepare begin -) unexpected exit status 1: libvirt:  error : cannot execute binary /etc/libvirt/hooks/qemu: Exec format error
```

> **注意**：`libvirt`只支持qemu启动或停止时候调用脚本，但是如果是guest os出现crash重启，则不属于qemu重启，就不会触发脚本执行。例如：[libvirt pvpanic](https://github.com/huataihuang/cloud-atlas-draft/tree/6f3204fffc11cf006abd394631e2598d98b415c3/virtual/libvirt/qemu/libvirt_pvpanic/README.md)情况下就不会触发hook脚本执行，需要自己定制修改libvirt代码。

## 脚本参数

> 这段没有理解，待开发实践

hook脚本调用使用特定的命令行参数，根据脚本和操作而不同：

guest hook脚本，qemu和lxc，会在标准输入上获得domain的完整XML描述。哲包括诸如domain的UUID和它的存储类型，以及提供脚本所需的所有libvirt信息。

对于所有案例，网络hook脚本的标准输入提供了完整的有关网络状态的XML描述，类似如下格式：

```markup
<hookData>
  <network>
     <name>$network_name</name>
     <uuid>afca425a-2c3a-420c-b2fb-dd7b4950d722</uuid>
     ...
  </network>
</hookData>
```

在网络的接口插入/拔出时，网络XML使用包含接口插拔的domain的完整XML描述：

```markup
<hookData>
  <network>
     <name>$network_name</name>
     <uuid>afca425a-2c3a-420c-b2fb-dd7b4950d722</uuid>
     ...
  </network>
  <domain type='$domain_type' id='$domain_id'>
     <name>$domain_name</name>
     <uuid>afca425a-2c3a-420c-b2fb-dd7b4950d722</uuid>
     ...
  </domain>
</hookData>
```

## 参数

以下时传递给每个hook脚本的跟随参数：

> 这里仅翻译整理了有关libvirt/qemu部分（因为我的开发工作主要围绕kvm）

* `/etc/libvirt/hooks/daemon`

当libvirt服务启动，脚本调用如下

```
/etc/libvirt/hooks/daemon - start - start
```

当libvirt服务停止，脚本调用

```
/etc/libvirt/hooks/daemon - shutdown - shutdown
```

当libvirt服务接收到`SIGHUP`信号，它将重新加载配置并触发hook脚本如下：

```
/etc/libvirt/hooks/daemon - reload begin SIGHUP
```

> 注意：当`libvirt`服务重启，这个`daemon`脚本只在`shutdown`操作发生时调用一次；而后在`start`操作则没有特定的操作针对`restart`。

* `/etc/libvirt/hooks/qemu`

## 参考

* [Hooks for specific system management](https://www.libvirt.org/hooks.html)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://huataihuang.gitbook.io/cloud-atlas-draft/virtual/libvirt/hook/hooks_for_specific_system_management.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
