gstreamer文档part-negotiation.txt翻译

本文深入探讨了GStreamer管道中数据流协商的过程,包括基本原则、查询、事件、操作以及两种调度模式下的协商机制。重点阐述了协商的发起、执行流程以及应用场景,同时介绍了不同协商场景下的问题及解决策略。

这篇翻译将会不断完善。有些不会翻译的地方会保留原文。开始。

######################################################################################################

协商

-----------
Capabilities 协商决定了Gstreamer 管道中数据流的格式,理想情况下,协商将信息从掌握信息一方传递到灵活的一方。受限于不灵活的一方。


基本原则
~~~~~~~~~~~
必须被遵守的简单原则


 1) 上游给出建议的格式
 2) 下游决定格式


 以下4种消息被用于caps协商
 1) GST_QUERY_CAPS        : 得到可能的格式
 2) GST_QUERY_ACCEPT_CAPS : 检测指定的格式是否可能
 3) GST_EVENT_CAPS        : 决定格式(下游)

 4) GST_EVENT_RECONFIGURE : 告诉上游有了新的格式


查询
-------
Pad可以询问它的peer pad所支持的GstCaps.这一步就是CAPS查询。这些被支持的能力列表将被选出合适的用于数据传输


CAPS查询是递归的,建立可能的caps时elements必须考虑它的peers。因为最后的caps可能很大,filter可以被用来限制caps。那些仅仅匹配filter的caps才会成为最终caps。filter的顺序决定了最终返回的caps顺序(?)。


 (in) "filter", GST_TYPE_CAPS (default NULL)
       - 一个GstCaps用来过滤结果
 (out) "caps", GST_TYPE_CAPS (default NULL)
       - 结果caps
  
pad可以询问它的peer pad 是否支持指定caps。通过ACCEPT_CAPS查询。caps必须是固定的


ACCEPT_CAPS查询没有被要求递归工作。它可以简单的返回TRUE,只要在处理随后对应此caps的CAPS消息时返回success


 (in) "caps", GST_TYPE_CAPS
       - 待检查的GstCaps, 必须是固定的


(out) "result", G_TYPE_BOOLEAN (default FALSE)
       - 如果 caps 被接受就该返回TRUE


事件
~~~~~~
但媒体格式协商完成.peer elements应该收到携带GstCaps的CAPS消息。该caps必须是固定
    "caps", GST_TYPE_CAPS
       - 协商好的 GstCaps, 必须固定


操作
~~~~~~~~~
GStreamer 有两个调度模式,push和pull,因此有两种不同的机制实现该目标。我们先挑更为普遍的push说起。


Push-mode协商
~~~~~~~~~~~~~~~~~~~~~
Push协商发生在elements想去push并且需要决定格式的时候。这被叫做下游协商,因为上游为下游决定了格式。这是最普遍的情况。


协商也会发生在但下游element想从上游接收新格式的时候。这被叫做上游协商。


基本的协商如下:
 - GstCaps (见 part-caps.txt) 被引用计数在它作为消息参数被push之前。
 - element应该针对接受到的CAPS消息重新设置自己,在处理消息之前。如果CAPS消息携带的数据类型不被接受,element应该拒绝这个消息。同样在chian函数中用返回GST_FLOW_NOT_NEGOTIATED的方法拒绝下一个buffer。


 - 下游elements发送RECONFIGURE事件到上游,可以请求变化流格式,当上游elements收到RECONFIGURE事件将协商一个新的格式。


source pad开始协商的一般流程如下:
The general flow for a source pad starting the negotiation.


             src              sink
              |                 |
              |  querycaps?     |
              |---------------->|
              |     caps        |
 从候选中选   |< - - - - - - - -|
 则caps       |                 |
              |                 |
              |                 |-.
              |  accepts?       | |
  cap A       |---------------->| | optional
              |      yes        | |
              |< - - - - - - - -| |
              |                 |-'
              |  send_event()   |
 发送 CAPS    |---------------->| 接收 A, 重新设置 to
 事件 A       |                 | process type A.
              |                 |
              |  push           |
 push buffer  |---------------->| Process buffer of type A
              |                 |


伪代码描述
[element 想创建buffer]
 还没协商好格式
 if not format
   # 看看我们可以做什么
   ourcaps = gst_pad_query_caps (srcpad)
   # 看看我的peer可以对我的caps做过滤么(由此得到候选)
   candidates = gst_pad_peer_query_caps (srcpad, ourcaps)
   
   foreach每个候选
# 确保每个caps是固定的
     fixedcaps = gst_pad_fixate_caps (srcpad, candidate)
     
# 看我的peer是否接受当前候选
     if gst_pad_peer_accept_caps (srcpad, fixedcaps)
  # 将caps存储为已协商的caps,这将调用setcaps函数(谁的setcaps函数?)
       gst_pad_push_event (srcpad, gst_event_new_caps (fixedcaps))
       break
     endif
   done
 endif


 #用ALLOCATION请求协商allocator/bufferpool


 buffer = gst_buffer_new_allocate (NULL, size, 0);
 #填充buffer然后push


sink pad开始协商的一般过程


             src              sink
              |                 |
              |  accepts?       |
              |<----------------| type B
              |      yes        |
              |- - - - - - - - >|-.
              |                 | | suggest B caps next
              |                 |<'
              |                 |
              |   push_event()  |
  mark      .-|<----------------| 发送 RECONFIGURE 事件
 renegotiate| |                 |
            '>|                 |
              |  querycaps()    |
 renegotiate  |---------------->| 
              |  suggest B      |
              |< - - - - - - - -|
              |                 |
              |  send_event()   |
 send CAPS    |---------------->| 接受 type B, 重设 to
 event B      |                 | process type B.
              |                 |
              |  push           |
 push buffer  |---------------->| 处理B类型的buffer
              |                 |


使用场景


videotestsrc ! xvimagesink
  1) 谁来决定什么格式?
   - 按照惯例,永远是src pad决定。sink pad在caps query中将想建议格式放在返回结果的前面。
   - 因为是src决定,它会选择自己可以处理的格式,所以这一步仅仅会因为sink pad说自己能够接受该格式而随后它又不能处理该格式而失败。


  2) 协商什么时候开始?
   - 在src pad push之前,它决定一个格式类型,就像上面说的那样,然后用这个类型push一个caps事件。sink检查媒体类型并用这个格式设置自己
   - src pad然后一般会发出一个ALLOCATION请求来和sink pad协商bufferpool。然后从内存池分配buffer在push给sink.因为sink pad已经接受了这个格式,所以它可以为这个格式创建一个内存池。
   - 因为sink可以接受这个格式,所以它可以处理该格式
   - since the sink stated in 1) it could accept the type, it will be able to
     handle it.
  3) sink如何请求另一个格式?   
   - sink 询问src pad能否接受新格式
   - sink push RECONFIGURE事件到上游
   - src接收到RECONFIGURE事件然后标记为renegotiation
   - 下次push之前,src重新协商caps和buffer pool.sink将想要的格式放到caps查询结果的最前面。
 
videotestsrc ! queue ! xvimagesink
queue代理了所有的 accept和caps请求到peer pad.
  - queue proxies all accept and caps queries to the other peer pad.
queue代理了bufferpool.  
  - queue proxies the bufferpool
  queue代理了RECONFIGURE事件
  - queue proxies the RECONFIGURE event
  queue在队列中存储了CAPS事件。这意味着queue可以拥有不同类型的buffer.
  - queue stores CAPS event in the queue. This means that the queue can contain
    buffers with different types.


Pull模式的协商
~~~~~~~~~~~~~~~~~~~~~


解释
^^^^^^^^^
工作在pull模式下的管道和push模式有不一样的协商需求,push模式用于以下两种情况。
 * 播放媒体文件,
A pipeline in pull mode has different negotiation needs than one
activated in push mode. Push mode is optimized for two use cases:


 * Playback of media files, in which the demuxers and the decoders are
   the points from which format information should disseminate to the
   rest of the pipeline; and
 * 从在线源录制,人们会在源element后放置capsfilter;caps信息从用户经过可能的源caps,到pipeline的sink
 * Recording from live sources, in which users are accustomed to putting
   a capsfilter directly after the source element; thus the caps
   information flow proceeds from the user, through the potential caps
   of the source, to the sinks of the pipeline.


pull模式有其他的典型应用:
In contrast, pull mode has other typical use cases:


 * 从易损的源回放,如RTP,管道上更高的延迟能带来增加质量
 * Playback from a lossy source, such as RTP, in which more knowledge
   about the latency of the pipeline can increase quality; or


 * 语音合成,API只会处理必要的采样,典型的受限于硬件驱动。
 * Audio synthesis, in which audio APIs are tuned to producing only the
   necessary number of samples, typically driven by a hardware interrupt
   to fill a DMA buffer or a Jack[0] port buffer.


 * 低延迟效果处理,
 * Low-latency effects processing, whereby filters should be applied as
   data is transferred from a ring buffer to a sink instead of
   beforehand. For example, instead of using the internal alsasink
   ringbuffer thread in push-mode wavsrc ! volume ! alsasink, placing
   the volume inside the sound card writer thread via wavsrc !
   audioringbuffer ! volume ! alsasink.


[0] http://jackit.sf.net


pull模式的问题在于sink得知道格式,这样通过gst_pad_pull_range()取数据的时候就可以知道要取多少了。这意味着在pull之前。sink必须决定协商格式。


回顾一下caps协商的原则,信息必须从有的那一方到无的那一方,我们看到两种使用情况有着不同的协商需求。


RTP和低延迟的回放都像普通回放一样,信息流到下游。
 * RTP and low-latency playback are both like the normal playback case,
   in which information flows downstream.


 * In audio synthesis, the part of the pipeline that has the most
   information is the sink, constrained by the capabilities of the graph
   that feeds it. However the caps are not completely specified; at some
   point the user has to intervene to choose the sample rate, at least.
   This can be done externally to gstreamer, as in the jack elements, or
   internally via a capsfilter, as is customary with live sources.


Given that sinks potentially need the input of sources, as in the RTP
case and at least as a filter in the synthesis case, there must be a
negotiation phase before the pull thread is activated. Also, given the
low latency offered by pull mode, we want to avoid capsnego from within
the pulling thread, in case it causes us to miss our scheduling
deadlines.


pull线程一般从PAUSED->PLAYING状态变化时开始,我们必须在此之前完成协商。


开始caps协商的时间就是在SCHEDULING请求完成之后,在sink开始pull线程之前。


机制
^^^^^^^^^
sink通过SCHEDULING请求检测上游element支持pull调度模式
The sink determines that the upstream elements support pull based scheduling by
doing a SCHEDULING query.


sink开始协商过程,先用gst_pad_query_caps取得自己的sink pads然后取得其peer 的src pads,两个pads计算交集。这个操作可以用gst_pad_get_allowed_caps()完成。也可以通过在它所有的src pad上调用get_allowed_caps()返回交集。这样,sink elements就知道整个管道的能力集。


sink element最后固定结果caps,如果需要,固定浮动的caps(带范围的caps).至此,从该sink pad的caps查询将返回固定的caps,这也意味着上游elements只能产生该格式的数据。


如果sink element不能设置它sink pad的caps。它应该在总线上抛出一个错误信息来指出协商错误。


但协商完成,sink pad和上游内部连接起来的pads被激活在pull模式。典型的,这个操作将触发下游的协商,被强制设置为协商过后的固定caps。




经过这些步骤,sink element从状态变化函数返回ASYNC。但sink收到第一个buffer时状态变为PAUSED。
After these steps, the sink element returns ASYNC from the state change
function. The state will commit to PAUSED when the first buffer is received in
the sink. This is needed to provide a consistent API to the applications that
expect ASYNC return values from sinks but it also allows us to perform the
remainder of the negotiation outside of the context of the pulling thread.




格式
~~~~~~~~
我们定义了三种样式的用于协商:


 1) Fixed?: 不能选择输出格式
      - Caps encoded in the stream
      - A video/audio decoder
      - 一般用 gst_pad_use_fixed_caps()


 2) Transform
      - Caps not modified (passthrough)
      - can do caps transform based on element property
      - fixed caps get transformed into fixed caps
      - videobox


 3) 动态?: 可以选择输出格式 
      - A converter element
      - 决定于下游 caps, 需要做CAPS 请求来找到transform.
      - usually prefers to use the identity transform
      - 固定的caps可以被转换为不固定的caps.
错误:事务测试失败: file /usr/sbin/alternatives from install of chkconfig-1.19.1-1.el8.x86_64 conflicts with file from package alternatives-1.24-2.el9.x86_64 file /usr/share/man/man8/alternatives.8.gz from install of chkconfig-1.19.1-1.el8.x86_64 conflicts with file from package alternatives-1.24-2.el9.x86_64 file /usr/lib/rpm/macros.d/macros.systemd from install of systemd-239-51.el8_5.2.x86_64 conflicts with file from package systemd-rpm-macros-252-57.el9.noarch file /usr/sbin/service from install of initscripts-10.00.15-1.el8.x86_64 conflicts with file from package initscripts-service-10.11.8-4.el9.noarch file /usr/share/man/man8/service.8.gz from install of initscripts-10.00.15-1.el8.x86_64 conflicts with file from package initscripts-service-10.11.8-4.el9.noarch file /usr/lib/udev/rename_device from install of initscripts-10.00.15-1.el8.x86_64 conflicts with file from package initscripts-rename-device-10.11.8-4.el9.x86_64 file /usr/lib64/girepository-1.0/GstInsertBin-1.0.typelib from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/girepository-1.0/GstMpegts-1.0.typelib from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/girepository-1.0/GstPlayer-1.0.typelib from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/girepository-1.0/GstWebRTC-1.0.typelib from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgstadaptivedemux-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgstbadaudio-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgstbasecamerabinsrc-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgstcodecparsers-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgstinsertbin-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgstisoff-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgstmpegts-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgstphotography-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgstplayer-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgstsctp-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgsturidownloader-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgstwayland-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/lib64/libgstwebrtc-1.0.so.0 from install of gstreamer1-plugins-bad-free-1.16.1-1.el8.x86_64 conflicts with file from package gstreamer1-plugins-bad-free-libs-1.22.12-4.el9.x86_64 file /usr/bin/jcat-tool from install of fwupd-1.5.9-1.el8_4.x86_64 conflicts with file from package libjcat-0.1.6-3.el9.x86_64 file /usr/lib64/libjcat.so.1.0.0 from install of fwupd-1.5.9-1.el8_4.x86_64 conflicts with file from package libjcat-0.1.6-3.el9.x86_64 file /usr/share/man/man1/jcat-tool.1.gz from install of fwupd-1.5.9-1.el8_4.x86_64 conflicts with file from package libjcat-0.1.6-3.el9.x86_64 file /usr/share/man/man5/oci-hooks.5.gz from install of podman-3.3.1-9.module_el8.5.0+988+b1f0b741.x86_64 conflicts with file from package containers-common-4:1-134.el9.x86_64 file /usr/share/man/man7/bpf-helpers.7.gz from install of bpftool-4.18.0-348.7.1.el8_5.x86_64 conflicts with file from package man-pages-6.04-7.el9.noarch 我在linux上下载samba软件包后先显示了这些
最新发布
11-12
<think> 我们正在处理一个关于在Linux上安装samba软件包时出现事务测试失败和文件冲突的问题。根据用户描述,冲突涉及chkconfig、systemd、initscripts等多个包。我们需要解决这些文件冲突。 根据引用[2]中的信息,我们知道chkconfig工具在管理服务时可能需要脚本中包含特定的注释(如#chkconfig和#description)才能正确工作。但这里的问题是在安装samba时出现的包冲突,而不是服务配置问题。 然而,从引用[1]中我们了解到,Linux系统中有多种服务管理机制(如cron、chkconfig、systemd等),并且可能有扩展的解决方案(如anacron、xinetd等)。但是,这些引用并没有直接提供解决包冲突的方法。 因此,我们需要从包管理的角度来解决冲突。常见的包管理器有yum(RHEL/CentOS)和dnf(Fedora/RHEL8+)。通常,文件冲突可能是因为多个包试图安装同一个文件,或者包之间的依赖关系不满足。 解决思路: 1. 更新系统:确保所有已安装的包都是最新的,以避免因版本问题导致的冲突。 2. 清理和重建包管理器的缓存:有时候缓存问题会导致依赖关系解析错误。 3. 使用包管理器提供的冲突解决选项:如yum/dnf的`--skip-broken`或`--allowerasing`等选项,但需谨慎使用,因为它们可能会移除其他包。 4. 手动移除冲突的包:如果冲突的包可以被移除而不影响系统稳定性,可以尝试移除它们,然后再安装samba。 5. 使用rpm命令绕过依赖:这种方法风险较高,只建议在明确知道后果的情况下使用。 由于用户提到了chkconfig、systemd、initscripts等包冲突,我们需要注意这些包都是系统核心包,因此不能轻易移除。所以,我们优先尝试更新和清理缓存。 具体步骤: 步骤1:更新系统 执行以下命令更新系统: ```bash sudo yum update ``` 或者对于使用dnf的系统: ```bash sudo dnf update ``` 步骤2:清理缓存 ```bash sudo yum clean all ``` 或者 ```bash sudo dnf clean all ``` 步骤3:尝试安装samba ```bash sudo yum install samba ``` 或 ```bash sudo dnf install samba ``` 如果仍然出现冲突,我们可以尝试使用`--skip-broken`选项跳过冲突的包(但可能无法安装samba): ```bash sudo yum install --skip-broken samba ``` 如果上述方法无效,我们可以尝试使用`rpm`命令来强制移除冲突的文件(但风险很大,需要知道具体冲突的文件)。不建议直接强制移除,因为可能导致系统不稳定。 另一种方法是,我们可以通过重新安装冲突的包来尝试修复。例如,如果冲突的是initscripts包,可以尝试: ```bash sudo yum reinstall initscripts ``` 然后再次尝试安装samba。 如果用户使用的是较新的系统(如CentOS 7或RHEL 7及以上),systemd已经成为主流的服务管理工具,而chkconfig可能已经不再需要。但是,samba可能同时支持两种服务管理方式,因此可能会依赖两种工具。我们可以尝试安装一个不包含chkconfig支持的samba包(如果存在的话),或者寻找其他替代方案。 另外,根据引用[1]中提到的systemd自定义启动脚本的链接,我们可以考虑使用systemd来管理samba服务,从而避免对chkconfig的依赖。但是,这需要在安装samba之后配置服务单元文件,而我们现在的问题是在安装阶段。 如果所有方法都失败,我们可以尝试从源代码编译samba,但这样会失去包管理的便利性。 由于问题描述不够具体(如操作系统版本、samba版本等),我们只能提供一般性的解决方案。 最后,我们生成相关问题: §§相关问题§§ 1. 如何查看yum或dnf安装过程中的详细错误信息? 2. 如何解决Linux中多个软件包之间的文件冲突? 3. 在Linux中,如何安全地强制移除一个软件包? 4. systemd和chkconfig在服务管理上有什么区别? 5. 如何从源代码编译安装samba? </think>### 解决 Samba 安装时的文件冲突问题 当在 Linux 上安装 Samba 时出现事务测试失败和文件冲突(涉及 chkconfig、systemd、initscripts 等包),通常是由于系统服务管理工具冲突或残留配置文件导致。以下是系统化的解决方案: #### 🔧 1. **清理冲突包和残留配置** ```bash # 尝试移除冲突包(如 initscripts 和旧版 systemd 组件) sudo yum remove initscripts systemd-sysv -y --skip-broken # 清理包管理器缓存 sudo yum clean all sudo rm -rf /var/cache/yum ``` #### ⚙️ 2. **修复依赖关系** ```bash # 重建 RPM 数据库并更新系统 sudo rpm --rebuilddb sudo yum update -y # 尝试强制安装 Samba(忽略依赖冲突) sudo yum install samba --skip-broken -y ``` #### 🔄 3. **手动解决服务管理冲突** 若报错提及 `chkconfig` 和 `systemd` 冲突: ```bash # 禁用旧版 SysV 服务(如果存在) sudo systemctl mask smb.service # 创建 systemd 服务文件(示例路径) sudo tee /etc/systemd/system/smb.service <<'EOF' [Unit] Description=Samba Service After=network.target [Service] Type=forking ExecStart=/usr/sbin/smbd ExecReload=/bin/kill -HUP $MAINPID [Install] WantedBy=multi-user.target EOF # 重载 systemd 配置 sudo systemctl daemon-reload ``` #### 🧩 4. **关键配置文件检查** 检查 `/etc/init.d/` 下的残留脚本: ```bash # 清理冲突的初始化脚本 sudo rm -f /etc/init.d/smb # 确保 chkconfig 配置正确(参考引用[2]) sudo tee -a /etc/init.d/samba-custom <<'EOF' #!/bin/bash # chkconfig: 2345 90 10 # 必须添加此行(引用[2]) # description: Custom Samba Service EOF sudo chkconfig --add samba-custom ``` #### 💻 5. **最终安装验证** ```bash # 重新安装 Samba sudo yum install samba samba-common -y # 启动服务 sudo systemctl start smb sudo systemctl enable smb ``` > 📌 **核心注意事项** > 1. 优先使用 `systemd` 而非 `chkconfig`(现代 Linux 发行版默认) > 2. 文件冲突通常源于 `/etc/init.d/` 与 `/usr/lib/systemd/` 的服务定义重复 > 3. 若系统使用 `xinetd`(引用[1]扩展),需确认是否冲突:`sudo yum remove xinetd` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值