yumコマンドで YumRepo Error が出たときの対処法

CentOSのアップデートを行おうとyumコマンドを実行したら以下のエラーが出ました。


# yum list updates
読み込んだプラグイン:fastestmirror, security
Determining fastest mirrors
YumRepo Error: All mirror URLs are not using ftp, http[s] or file.
 Eg. Invalid release/repo/arch combination/
removing mirrorlist with no valid mirrors: /var/cache/yum/x86_64/6/base/mirrorlist.txt
エラー: Cannot find a valid baseurl for repo: base

調べてみると、CentOSのサポートが切れるとyumコマンドが失敗するらしい。僕が使っていたのはCentOS 6.10だったのだけれど、CentOS 6系は 2020年11月30日にサポートが終了していたようです。新しいバージョンに乗り換えなくてはならないのでしょうが、すぐにできるわけでもないのでyumコマンドが成功するように対処してみました。「http://vault.centos.org/」のサイトからパッケージを取得するようにすれば良いらしいです。ここには過去のバージョンのパッケージが収められているとのこと。

こんな感じです。

では、やってみます。まずCentOSのバージョンを確認します。

# cat /etc/redhat-release
CentOS release 6.10 (Final)

リポジトリのファイルは /etc/yum.repos.d 配下にあるので、ここにある CentOS-Base.repo ファイルを修正します。

# cd /etc/yum.repos.d
# vi CentOS-Base.repo

mirrorlist= の行をコメントアウトし、新たに baseurl= の行を追加します。


[base]
name=CentOS-$releasever - Base
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra ←★コメントアウトする
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
baseurl=http://vault.centos.org/6.10/os/$basearch/ ←★この行を追加する
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

追加した行 baseurl=http://vault.centos.org/6.10/os/$basearch/ の太字部分はCentOSのバージョンにあわせて書き換えてください。 CentOS-Base.repo ファイルにはbaseブロック以外にも updates、extras、centosplus、contrib のブロックがあるので同様に書き換えます。

ファイルを保存したら、再度、yumコマンドを実行します。これで良いかと思っていたのですが、またエラーが出ました。。


# yum list updates
読み込んだプラグイン:fastestmirror, security
Determining fastest mirrors
YumRepo Error: All mirror URLs are not using ftp, http[s] or file.
 Eg. Invalid release/repo/arch combination/
removing mirrorlist with no valid mirrors: /var/cache/yum/x86_64/6/centos-sclo-rh/mirrorlist.txt
エラー: Cannot find a valid baseurl for repo: centos-sclo-rh

先ほどと違うのは「Cannot find a valid baseurl for repo: centos-sclo-rh」とのこと。/etc/yum.repos.d 配下を見ると他にもリポジトリのファイルがありました。


# cd /etc/yum.repos.d
# ll
合計 44
-rw-r--r--  1 root root 1991  6月 26 23:52 2018 CentOS-Base.repo
-rw-r--r--  1 root root  647  6月 26 23:52 2018 CentOS-Debuginfo.repo
-rw-r--r--  1 root root  630  6月 26 23:52 2018 CentOS-Media.repo
-rw-r--r--  1 root root  971 10月 29 18:21 2018 CentOS-SCLo-scl-rh.repo
-rw-r--r--  1 root root  998 12月 12 00:52 2018 CentOS-SCLo-scl.repo
-rw-r--r--  1 root root 8854  6月 26 23:52 2018 CentOS-Vault.repo
-rw-r--r--  1 root root  289  6月 26 23:52 2018 CentOS-fasttrack.repo
-rw-r--r--. 1 root root 1056 11月  5 12:52 2012 epel-testing.repo
-rw-r--r--. 1 root root  957 11月  5 12:52 2012 epel.repo

「centos-sclo-rh」で拡張子がrepoのファイルをgrepしてみます。


# grep centos-sclo-rh *repo
CentOS-SCLo-scl-rh.repo:[centos-sclo-rh]
CentOS-SCLo-scl-rh.repo:[centos-sclo-rh-testing]
CentOS-SCLo-scl-rh.repo:[centos-sclo-rh-source]
CentOS-SCLo-scl-rh.repo:[centos-sclo-rh-debuginfo]

CentOS-SCLo-scl-rh.repo ファイルも直さないといけないみたいなので修正します。


[centos-sclo-rh]
name=CentOS-6 - SCLo rh
#baseurl=http://mirror.centos.org/centos/6/sclo/$basearch/rh/
#mirrorlist=http://mirrorlist.centos.org?arch=$basearch&release=6&repo=sclo-rh ←★コメントアウトする
baseurl=http://vault.centos.org/6.10/sclo/$basearch/rh/ ←★この行を追加する
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo

CentOS-SCLo-scl-rh.repo ファイルには centos-sclo-rh-testing、centos-sclo-rh-source、centos-sclo-rh-debuginfo のブロックもあるのですが、これらは関係なさそうと判断して centos-sclo-rh のブロックしか直しませんでした。

修正した後にもう一度yumコマンドを実行したら、今度は「Cannot find a valid baseurl for repo: centos-sclo-sclo」です。「centos-sclo-sclo」でrepoのファイルをgrepします。


# grep centos-sclo-sclo *repo
CentOS-SCLo-scl.repo:[centos-sclo-sclo]
CentOS-SCLo-scl.repo:[centos-sclo-sclo-testing]
CentOS-SCLo-scl.repo:[centos-sclo-sclo-source]
CentOS-SCLo-scl.repo:[centos-sclo-sclo-debuginfo]

まだ直さないといけないところがありました。CentOS-SCLo-scl.repo ファイルを以下のように修正しました。


[centos-sclo-sclo]
name=CentOS-6 - SCLo sclo
# baseurl=http://mirror.centos.org/centos/6/sclo/$basearch/sclo/
#mirrorlist=http://mirrorlist.centos.org?arch=$basearch&release=6&repo=sclo-sclo ←★コメントアウトする
baseurl=http://vault.centos.org/6.10/sclo/$basearch/sclo/ ←★この行を追加する
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo

CentOS-SCLo-scl.repo ファイルの centos-sclo-sclo-testing、centos-sclo-sclo-source、centos-sclo-sclo-debuginfo のブロックはそのままです。

もう一度、yumコマンドを実行します。

# yum list updates
読み込んだプラグイン:fastestmirror, security
Determining fastest mirrors
 :
(これでやっと、yumコマンドが成功しました!)

C言語での日付と時刻の取得方法

C言語で日付と時刻を取得する方法です。

日付取得用の time_t 型の変数と tm 構造体へのポインタを定義して、time関数とlocaltime関数を使って日付と時刻の情報を取得します。

/* 日付取得用変数の定義 */
time_t t1;
struct tm *tp;

/* 日付情報の取得 */
time( &t1 );
tp = localtime( &t1 );

time関数を使って 1970年1月1日 00:00:00(UTC) から現在までの経過時間を取得します。取得した経過時間は time_t 型の変数に格納されます。なお UTC というのは協定世界時というもので、これを基準にして世界の国々で時刻を調整しています。日本標準時(JST)は協定世界時より9時間進んだ時刻になります。

次に、localtime関数を使って経過時間から現在の日付と時刻に変換します。この際に地域性も考慮され日本の場合は日本標準時になります(OSに設定したタイムゾーンによるかと思います)。変換された値は tm 構造体に格納されます。

日付、時刻の情報を表示するにはstrftime関数を使います。「YYYY/MM/DD HH24:MI:SS」形式で表示する例です。


#include <stdio.h>
#include <time.h>

int main( void )
{
	/* 日付取得用変数 */
	time_t t1;
	struct tm *tp;

	/* 印字用文字列の格納のため */
	char a[100];

	/* 日付情報の取得 */
	time( &t1 );
	tp = localtime( &t1 );

	/* YYYY/MM/DD HH24:MI:SS 形式で印字 */
	strftime( a, sizeof(a), "%Y/%m/%d %H:%M:%S", tp );

	printf( "%s\n", a );

	return 0;
}

strftime関数の書式文字列には以下のようなものがあります。

%Y 年4桁
%y 年2桁(00-99)
%m 月(01-12)
%d 日(01-31)
%H 時間(24時間)(00-23)
%I 時間(12時間)(01-12)
%M 分(00-59)
%S 秒(00-59)
%a 省略形の曜日
%A 完全な曜日
%w 週の日(0-6、日曜が0)
%b 省略形の月名
%B 完全な月名

strftime関数を使わず tm 構造体にアクセスして表示することもできます。


#include <stdio.h>
#include <time.h>
#include <string.h>

int main( void )
{
	/* 日付取得用変数 */
	time_t t1;
	struct tm *tp;

	/* 印字用文字列の格納のため */
	char a[100];

	/* 日付情報の取得 */
	time( &t1 );
	tp = localtime( &t1 );

	/* YYYY/MM/DD HH24:MI:SS 形式で印字 */
	snprintf( a, sizeof(a),"%04d/%02d/%02d %02d:%02d:%02d",
		tp->tm_year+1900,
		tp->tm_mon+1,
		tp->tm_mday,
		tp->tm_hour,
		tp->tm_min,
		tp->tm_sec );

	printf( "%s\n", a );

	return 0;
}

年を出すときに「tp->tm_year+1900」としているのは tm_year が1901年以降の年となっているためです。また「tp->tm_mon+1」としているのは tm_mon の範囲が 00-11 となっているためです。

日付、時刻の取得方法はコーディングを覚えてしまえば良いのですが、ちょっと気に留めておくことがlocaltime関数にあるので書いておきます。

localtime関数は「静的なオブジェクトを返す関数」であるため、通常のやり方とちょっと扱い方が違います。

通常の関数の使い方であればmain関数側で tm 構造体の変数を定義して tm 構造体のポインタをlocaltime関数に引き渡す感じになるかと思いますが、localtime関数はそのような使い方をしません。

(あえて)間違っているやり方です。

int main( void ) {
 :
 /* tm構造体の定義 */
 struct tm t1;
 :
 /* tm構造体のポインタを渡す */
 localtime( &t1 );
 :
}

localtime関数は構造体のポインタを受取りポインタの参照を通して構造体の実体に値を設定する、ということはしていないということです。

では、正しい使い方です。

int main( void ) {
 :
 /* tm構造体のポインタを定義 */
 struct tm *tp;
 :
 /* tm構造体へのポインタが返る */
 tp = localtime( ・・・ );
 :
}

このようになっているのは(もしくはこのようなことが出来るのは)、localtime関数が tm 構造体を static で宣言しているからでしょう。

struct tm *localtime(・・・) {
 :
 /* tm構造体の定義 */
 static struct tm t1;
 :
(tm 構造体に値を設定する処理)
 :
 return &t1;
}

これが「静的なオブジェクトを返す関数」という意味です。static であればlocaltime関数が終了しても tm 構造体は残り続けます。time.h にある asctime関数、ctime関数、gmtime関数も同様に静的なオブジェクトを返す関数になっています。

FILE構造体へのポインタを返すfopen関数と同じ使い方なので、日付関連の関数を扱うときはFILE構造体を扱う関数と同じ、と覚えておくと良いかもしれません。