From f30cbb86fff27e72ae25780aa2b90cf24937864e Mon Sep 17 00:00:00 2001 From: Emir Buljubasic Date: Fri, 29 May 2026 13:41:13 +0200 Subject: [PATCH 1/4] lxc/criu: restore cgroup limits and freezer on restore Signed-off-by: Emir Buljubasic --- src/lxc/criu.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/lxc/criu.c b/src/lxc/criu.c index 9996b888aa..d6c2c4cd65 100644 --- a/src/lxc/criu.c +++ b/src/lxc/criu.c @@ -939,6 +939,21 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_ goto out_fini_handler; } + if (!cgroup_ops->payload_delegate_controllers(cgroup_ops)) { + ERROR("Failed to delegate controllers to payload cgroup"); + goto out_fini_handler; + } + + if (!cgroup_ops->setup_limits(cgroup_ops, handler)) { + ERROR("Failed to setup cgroup limits"); + goto out_fini_handler; + } + + if (!cgroup_ops->chown(cgroup_ops, handler->conf)) + goto out_fini_handler; + + cgroup_ops->finalize(cgroup_ops); + if (!restore_net_info(c)) { ERROR("failed restoring network info"); goto out_fini_handler; From 3224f46d012a2ef2aca3790754d716f5068c3097 Mon Sep 17 00:00:00 2001 From: KATOH Yasufumi Date: Sun, 7 Jun 2026 00:48:47 +0900 Subject: [PATCH 2/4] doc: update cgroup section of lxc.container.conf(5) to reflect cgroup v1 removal Remove or rewrite descriptions that assumed cgroup v1 support, following its removal in LXC 7.0. Signed-off-by: KATOH Yasufumi --- doc/ja/lxc.container.conf.sgml.in | 132 +++++++++++------------------- doc/lxc.container.conf.sgml.in | 111 ++++++++----------------- 2 files changed, 84 insertions(+), 159 deletions(-) diff --git a/doc/ja/lxc.container.conf.sgml.in b/doc/ja/lxc.container.conf.sgml.in index 9e04085d30..40b5d5dee9 100644 --- a/doc/ja/lxc.container.conf.sgml.in +++ b/doc/ja/lxc.container.conf.sgml.in @@ -2069,27 +2069,20 @@ explanation of the differences between the two versions. --> カーネルにおける cgroup 実装は長年にわたって大きく変化してきました。 - Linux 4.5 で新しい cgroup ファイルシステムのサポートが追加されました。通常は "cgroup2" や "unified hierarchy"(単一階層構造) と呼ばれています。 - それ以来、通常は古い cgroup ファイルシステムは "cgroup1" や "legacy hierarchies"(レガシー階層構造)と呼ばれています。 + Linux 4.5 で新しい cgroup ファイルシステムのサポートが追加されました。通常は "cgroup v2" や "unified hierarchy"(単一階層構造) と呼ばれています。 + それ以来、通常は古い cgroup ファイルシステムは "cgroup v1" や "legacy hierarchies"(レガシー階層構造)と呼ばれています。 この 2 つのバージョンの違いについての詳細な説明は、cgroup のマニュアルページをご覧ください。 - LXC は cgroup1(レガシー階層構造)と cgroup2(単一階層構造)に対する設定を、異なる設定プレフィックスを使って区別しています。 - cgroup1 に対する設定を変更するには というプレフィックスを使う必要があり、cgroup2 の設定を変更するには を使う必要があります。 - LXC は、cgroup2 だけが使われているシステム上の を無視します。逆に cgroup1 だけが使われているシステム上の を無視します。 + Since LXC 7.0, only the unified cgroup hierarchy (cgroup v2) is + supported. To alter settings for controllers in the unified hierarchy, + the key prefix must be used. + The key prefix, which was used for + legacy and hybrid hierarchy configurations, is no longer supported. + --> + LXC 7.0 以降、cgroup v2(単一階層構造)のみがサポートされています。cgroup v2 のコントローラーの設定を変更するには、 というプレフィックスを使う必要があります。cgroup v1(レガシー階層構造)や v1 と v2 のハイブリッドな構成で使われていた というプレフィックスはサポートされなくなりました。 @@ -2108,67 +2101,44 @@ cgroup 階層の本質は、プロセスを階層的に構造化する方法です。通常は、cgroup 階層では 1 つ以上の「コントローラー」が有効になっています。 通常、cgroup 階層の「コントローラー」は階層に従って特定のタイプのシステムリソースを分配する役割を果たします。 コントローラーには "pids" コントローラー、"cpu" コントローラー、"memory" コントローラーなどがあります。 - しかし、システムリソースの分配するという役割に該当しないコントローラーもあります。このようなコントローラーは「ユーティリティー」コントローラーと呼ばれたりします。 + しかし、システムリソースを分配するという役割に該当しないコントローラーもあります。このようなコントローラーは「ユーティリティー」コントローラーと呼ばれたりします。 ユーティリティーコントローラーの 1 つにデバイスコントローラーがあります。このコントローラーはシステムリソースを分配する代わりにデバイスへのアクセスを管理できます。 - cgroup1 では、デバイスコントローラーは他の多くのコントローラーと同様に、書き込みできるファイルのセットとして実装されていました。 - これらのファイルは "devices.allow" と "devices.deny" という名前のファイルでした。レガシーデバイスコントローラーは「許可リスト(allowlists)」と「拒否リスト(denylists)」の両方を実装できました。 + LXC supports both "allowlist" and "denylist" semantics for device + access control. An allowlist blocks access to all devices by default, + and allow rules must be specified for particular devices or device + classes. A denylist allows access to all devices by default, and "deny + rules" must be specified to restrict access to particular devices or + device classes. + --> + LXC は、デバイスアクセスコントロールにおいて、「許可リスト(allowlist)」と「拒否リスト(denylist)」の両方をサポートしています。許可リストは、デフォルトですべてのデバイスへのアクセスをブロックし、特定のデバイスまたはデバイスクラスに対して「許可ルール(allow rules)」を指定する必要があります。拒否リストは、デフォルトですべてのデバイスへのアクセスを許可し、特定のデバイスまたはデバイスクラスへのアクセスを拒否するには「拒否ルール(deny rules)」を指定する必要があります。 - 許可リスト(allowlist)とは、すべてのデバイスへのアクセスをブロックするデバイスプログラムです。特定のデバイスへのアクセスを行うには、特定のデバイスもしくはデバイスクラスに対する「許可ルール(allow rules)」を指定する必要があります。 - 一方、拒否リスト(denylist)はデフォルトですべてのデバイスへのアクセスを許可するデバイスプログラムです。特定のデバイスへのアクセスを拒否するには、特定のデバイスもしくはデバイスクラスに対する「拒否ルール(deny rules)」を指定する必要があります。 + cgroup v2 では、デバイスコントローラーは、以前使用されていたファイルベースのインターフェースではなく、cgroup にアタッチされたタイプ の eBPF プログラムを介して実装されています。LXC は、この eBPF ベースのデバイスコントローラーで、v1 のときと同じ許可リスト・拒否リストのセマンティクスを保持します。このあとの段落では、cgroup v2 の eBPF デバイスコントローラーに対するセマンティクスを説明します。 - cgroup2 では、デバイスコントローラーの実装が完全に変わりました。読み書きするファイルの代わりに、 の eBPF プログラムを cgroup にアタッチできます。 - カーネルの実装が完全に変わったのにもかかわらず、LXC は cgroup1 のデバイスコントローラーと cgroup2 の eBPF ベースのデバイスコントローラーで同じセマンティクスに従えるようにしています。 - このあとの段落では、cgroup2 の eBPF デバイスコントローラーに対するセマンティクスを説明します。 + cgroup v2 の eBPF ベースのデバイスコントローラーのデバイスルールは、 を使って指定します。 - - - 先に述べたように、cgroup2 の eBPF ベースのデバイスコントローラーに対するデバイスルールを指定するフォーマットは、cgroup1 のデバイスコントローラーと同じです。ただし、設定キーのプレフィックスは変更されています。 - 具体的には、cgroup1 のデバイスコントローラーに対するデバイスルールは を使って指定します。一方、cgroup2 の eBPF ベースのコントローラーでは を使わなければなりません。 - @@ -2376,22 +2346,16 @@ - - コンテナの cgroup を作成するパスやディレクトリを指定します。 - 例えば、"c1" という名前のコンテナで のように設定すると、"my-cgroup" のサブ cgroup のようにコンテナの cgroup を作成します。 - 例えば、ユーザのカレントの cgroup である "my-user" が cgroup v1 階層にある cpuset コントローラの root cgroup 内に存在する場合、この設定は "/sys/fs/cgroup/cpuset/my-user/my-cgroup/first/c1" という cgroup をこのコンテナ向けに作成します。 - 存在しない cgroup は LXC が作成しますが、ユーザがカレントの cgroup に書き込み権を持っていることが前提となります。 + named "c1", if the user's current cgroup is "my-user", will + create the container's cgroups under "my-user/my-cgroup/first". + Any missing cgroups will be created by LXC. This presupposes + that the user has write access to its current cgroup. + --> + コンテナの cgroup を作成するパスやディレクトリを指定します。例えば、"c1" という名前のコンテナで のように設定すると、ユーザのカレント cgroup が "my-user" の場合、コンテナの cgroup は "my-user/my-cgroup/first" の下に作成されます。存在しない cgroup は LXC が作成しますが、ユーザーがカレントの cgroup に書き込み権を持っていることが前提となります。 @@ -4139,11 +4103,11 @@ devices.allow は、特定のデバイスを使用可能にします。 - lxc.cgroup.cpuset.cpus = 0,1 - lxc.cgroup.cpu.shares = 1234 - lxc.cgroup.devices.deny = a - lxc.cgroup.devices.allow = c 1:3 rw - lxc.cgroup.devices.allow = b 8:0 rw + lxc.cgroup2.cpuset.cpus = 0,1 + lxc.cgroup2.cpu.shares = 1234 + lxc.cgroup2.devices.deny = a + lxc.cgroup2.devices.allow = c 1:3 rw + lxc.cgroup2.devices.allow = b 8:0 rw @@ -4177,11 +4141,11 @@ lxc.net.2.hwaddr = 4a:49:43:49:79:ff lxc.net.2.ipv4.address = 10.2.3.6/24 lxc.net.2.ipv6.address = 2003:db8:1:0:214:1234:fe0b:3297 - lxc.cgroup.cpuset.cpus = 0,1 - lxc.cgroup.cpu.shares = 1234 - lxc.cgroup.devices.deny = a - lxc.cgroup.devices.allow = c 1:3 rw - lxc.cgroup.devices.allow = b 8:0 rw + lxc.cgroup2.cpuset.cpus = 0,1 + lxc.cgroup2.cpu.shares = 1234 + lxc.cgroup2.devices.deny = a + lxc.cgroup2.devices.allow = c 1:3 rw + lxc.cgroup2.devices.allow = b 8:0 rw lxc.mount.fstab = /etc/fstab.complex lxc.mount.entry = /lib /root/myrootfs/lib none ro,bind 0 0 lxc.rootfs.path = dir:/mnt/rootfs.complex diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in index 8ba375df9c..b0eca005f8 100644 --- a/doc/lxc.container.conf.sgml.in +++ b/doc/lxc.container.conf.sgml.in @@ -1546,17 +1546,11 @@ - LXC distinguishes settings for the legacy and the unified hierarchy by - using different configuration key prefixes. To alter settings for - controllers in a legacy hierarchy the key prefix - must be used and in order to alter the - settings for a controller in the unified hierarchy the - key must be used. Note that LXC will - ignore settings on systems that only use - the unified hierarchy. Conversely, it will ignore - options on systems that only use legacy - hierarchies. (legacy and hybrid hierarchy) - support is dropped. + Since LXC 7.0, only the unified cgroup hierarchy (cgroup v2) is + supported. To alter settings for controllers in the unified hierarchy, + the key prefix must be used. + The key prefix, which was used for + legacy and hybrid hierarchy configurations, is no longer supported. @@ -1573,45 +1567,30 @@ - In the legacy hierarchy the device controller was implemented like most - other controllers as a set of files that could be written to. These - files where named "devices.allow" and "devices.deny". The legacy device - controller allowed the implementation of both "allowlists" and - "denylists". + LXC supports both "allowlist" and "denylist" semantics for device + access control. An allowlist blocks access to all devices by default, + and "allow rules" must be specified for particular devices or device + classes. A denylist allows access to all devices by default, and "deny + rules" must be specified to restrict access to particular devices or + device classes. - An allowlist is a device program that by default blocks access to all - devices. In order to access specific devices "allow rules" for - particular devices or device classes must be specified. In contrast, a - denylist is a device program that by default allows access to all - devices. In order to restrict access to specific devices "deny rules" - for particular devices or device classes must be specified. + In the unified cgroup hierarchy, the device controller is implemented + via an eBPF program of type + attached to a cgroup, + rather than the file-based interface used previously. LXC preserves + the same allowlist/denylist semantics in this eBPF-based device + controller. The following paragraphs explain these semantics in + detail. - In the unified cgroup hierarchy the implementation of the device - controller has completely changed. Instead of files to read from and - write to a eBPF program of - can be attached to a - cgroup. Even though the kernel implementation has changed completely - LXC tries to allow for the same semantics to be followed in the legacy - device cgroup and the unified eBPF-based device controller. The - following paragraphs explain the semantics for the unified eBPF-based - device controller. + Device rules for the cgroup2 eBPF-based device controller are + specified via and + . - - As mentioned the format for specifying device rules for the unified - eBPF-based device controller is the same as for the legacy cgroup - device controller; only the configuration key prefix has changed. - Specifically, device rules for the legacy cgroup device controller are - specified via and - whereas for the - cgroup2 eBPF-based device controller - and - must be used. - @@ -1722,21 +1701,6 @@ switch from an allowlist program to a denylist program. - - - - - - - Specify the control group value to be set on a legacy cgroup - hierarchy. The controller name is the literal name of the control - group. The permitted names and the syntax of their values is not - dictated by LXC, instead it depends on the features of the Linux - kernel running at the time the container is started, eg. - - - - @@ -1758,16 +1722,13 @@ - specify a directory or path in which the container's cgroup will + Specify a directory or path in which the container's cgroup will be created. For example, setting for a container - named "c1" will create the container's cgroup as a sub-cgroup of - "my-cgroup". For example, if the user's current cgroup "my-user" - is located in the root cgroup of the cpuset controller in a - cgroup v1 hierarchy this would create the cgroup - "/sys/fs/cgroup/cpuset/my-user/my-cgroup/first/c1" for the - container. Any missing cgroups will be created by LXC. This - presupposes that the user has write access to its current cgroup. + named "c1", if the user's current cgroup is "my-user", will + create the container's cgroups under "my-user/my-cgroup/first". + Any missing cgroups will be created by LXC. This presupposes + that the user has write access to its current cgroup. @@ -3093,11 +3054,11 @@ cpus.share prioritize the control group, devices.allow makes usable the specified devices. - lxc.cgroup.cpuset.cpus = 0,1 - lxc.cgroup.cpu.shares = 1234 - lxc.cgroup.devices.deny = a - lxc.cgroup.devices.allow = c 1:3 rw - lxc.cgroup.devices.allow = b 8:0 rw + lxc.cgroup2.cpuset.cpus = 0,1 + lxc.cgroup2.cpu.shares = 1234 + lxc.cgroup2.devices.deny = a + lxc.cgroup2.devices.allow = c 1:3 rw + lxc.cgroup2.devices.allow = b 8:0 rw @@ -3128,11 +3089,11 @@ lxc.net.2.hwaddr = 4a:49:43:49:79:ff lxc.net.2.ipv4.address = 10.2.3.6/24 lxc.net.2.ipv6.address = 2003:db8:1:0:214:1234:fe0b:3297 - lxc.cgroup.cpuset.cpus = 0,1 - lxc.cgroup.cpu.shares = 1234 - lxc.cgroup.devices.deny = a - lxc.cgroup.devices.allow = c 1:3 rw - lxc.cgroup.devices.allow = b 8:0 rw + lxc.cgroup2.cpuset.cpus = 0,1 + lxc.cgroup2.cpu.shares = 1234 + lxc.cgroup2.devices.deny = a + lxc.cgroup2.devices.allow = c 1:3 rw + lxc.cgroup2.devices.allow = b 8:0 rw lxc.mount.fstab = /etc/fstab.complex lxc.mount.entry = /lib /root/myrootfs/lib none ro,bind 0 0 lxc.rootfs.path = dir:/mnt/rootfs.complex From 195088dfa6647c0b92ac7c6ef5d4bcf02d2724f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 13:22:26 +0000 Subject: [PATCH 3/4] build(deps): bump actions/checkout from 6 to 7 Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/builds.yml | 2 +- .github/workflows/coverity.yml | 2 +- .github/workflows/tests.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index fcc620b007..9469fdf52e 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Install dependencies run: | diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 6bccb6ffbb..45af834105 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -14,7 +14,7 @@ jobs: if: github.repository == 'lxc/lxc' steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Download Coverity Build Tool run: | diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9fb0805066..061b85f06a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Install dependencies run: | @@ -64,7 +64,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Install dependencies run: | From c2809b067bbd5c63f0f78a5acd6f7af4e77e584c Mon Sep 17 00:00:00 2001 From: Adrian Ratiu Date: Sat, 18 Jul 2026 23:11:52 +0300 Subject: [PATCH 4/4] tree-wide: fix const-correctness issues exposed by glibc 2.43 glibc 2.43 implements strchr(3), strrchr(3) and strstr(3) as C23-style _Generic macros which propagate the const qualifier of the input string to the return type. For example, a 'const char *' input now produces 'const char *' output types and vice-versa (non-const -> non-const). Building with clang and -Werror=incompatible-pointer-types fails: src/lxc/confile.c:2690:4: error: assigning to 'char *' from 'const char *' discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers] Constify the result pointers where they are only read. Where the code intentionally writes through the result into caller-owned writable storage, drop the bogus const from the parameter instead of casting it away: update_hwaddr() (and thus its caller append_unexp_config_line()) modify the string in-place via rand_complete_hwaddr(), so 'char *' is the honest type. The two call sites already pass writable buffers (a strdup()'d line and an internally built one), so no cast is needed. The one remaining cast is in cgroup1-only pam_cgfs code (cgv1_handle_cpuset_hierarchy) where the writable buffer is passed down through a const 'cgroup' parameter; that hierarchy is slated for removal, so the minimal cast is kept there. This is just a build fix, the runtime behavior is unchanged. Fixes: #4710 Signed-off-by: Adrian Ratiu --- src/lxc/confile.c | 6 +++--- src/lxc/confile.h | 2 +- src/lxc/confile_utils.c | 2 +- src/lxc/pam/pam_cgfs.c | 4 ++-- src/lxc/storage/nbd.c | 2 +- src/lxc/storage/zfs.c | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 0bebe4687e..555b0e64ec 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -2675,7 +2675,7 @@ static int set_config_console_size(const char *key, const char *value, * lxc.include. * 'x' and 'X' are substituted in-place. */ -static void update_hwaddr(const char *line) +static void update_hwaddr(char *line) { char *p; @@ -2701,7 +2701,7 @@ static void update_hwaddr(const char *line) rand_complete_hwaddr(p); } -int append_unexp_config_line(const char *line, struct lxc_conf *conf) +int append_unexp_config_line(char *line, struct lxc_conf *conf) { size_t linelen; size_t len = conf->unexpanded_len; @@ -4213,7 +4213,7 @@ static int get_config_uts_name(const char *key, char *retv, int inlen, static int get_config_hooks(const char *key, char *retv, int inlen, struct lxc_conf *c, void *data) { - char *subkey; + const char *subkey; int len, fulllen = 0, found = -1; struct string_entry *entry; int i; diff --git a/src/lxc/confile.h b/src/lxc/confile.h index 33e97dbd46..cb9263849a 100644 --- a/src/lxc/confile.h +++ b/src/lxc/confile.h @@ -75,7 +75,7 @@ __hidden extern int lxc_list_net(struct lxc_conf *c, const char *key, char *retv __hidden extern int lxc_config_read(const char *file, struct lxc_conf *conf, bool from_include); -__hidden extern int append_unexp_config_line(const char *line, struct lxc_conf *conf); +__hidden extern int append_unexp_config_line(char *line, struct lxc_conf *conf); extern int lxc_config_define_add(struct lxc_list *defines, char *arg); diff --git a/src/lxc/confile_utils.c b/src/lxc/confile_utils.c index 7dcd735698..1467a112a2 100644 --- a/src/lxc/confile_utils.c +++ b/src/lxc/confile_utils.c @@ -903,7 +903,7 @@ int lxc_inherit_namespace(const char *nsfd_path, const char *lxcpath, { __do_free char *dup = NULL; int fd, pid; - char *lastslash; + const char *lastslash; if (nsfd_path[0] == '/') { return open(nsfd_path, O_RDONLY | O_CLOEXEC); diff --git a/src/lxc/pam/pam_cgfs.c b/src/lxc/pam/pam_cgfs.c index e638269bc8..f066345fab 100644 --- a/src/lxc/pam/pam_cgfs.c +++ b/src/lxc/pam/pam_cgfs.c @@ -362,7 +362,7 @@ static char *copy_to_eol(char *s) /* Check if given entry under /proc//mountinfo is a fuse.lxcfs mount. */ static bool is_lxcfs(const char *line) { - char *p = strstr(line, " - "); + const char *p = strstr(line, " - "); if (!p) return false; @@ -1914,7 +1914,7 @@ static bool cgv1_handle_cpuset_hierarchy(struct cgv1_hierarchy *h, if (*cgroup == '/') cgroup++; - slash = strchr(cgroup, '/'); + slash = (char *)strchr(cgroup, '/'); if (slash) *slash = '\0'; diff --git a/src/lxc/storage/nbd.c b/src/lxc/storage/nbd.c index c35f9e8659..73ea19b8c3 100644 --- a/src/lxc/storage/nbd.c +++ b/src/lxc/storage/nbd.c @@ -291,7 +291,7 @@ static void nbd_detach(const char *path) */ static int nbd_get_partition(const char *src) { - char *p = strchr(src, ':'); + const char *p = strchr(src, ':'); if (!p) return 0; diff --git a/src/lxc/storage/zfs.c b/src/lxc/storage/zfs.c index 521a9fd637..c3075962ab 100644 --- a/src/lxc/storage/zfs.c +++ b/src/lxc/storage/zfs.c @@ -461,7 +461,7 @@ int zfs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new, orig_src = cmd_output; } - tmp = strrchr(orig_src, '/'); + tmp = (char *)strrchr(orig_src, '/'); if (!tmp) { ERROR("Failed to detect \"/\" in \"%s\"", orig_src); return -1;