nova 中os_type为window时需要使用localtime

本文介绍在OpenStack Nova项目中如何从镜像属性中获取操作系统类型(ostype)及如何根据ostype配置虚拟机时钟偏移,特别是在Windows与Linux系统之间的差异。
nova中在如下的code中可以拿到os type
E:\nova\nova\compute\api.py

    def _inherit_properties_from_image(self, image, auto_disk_config):
		#可见属性信息是包含在image的镜像当中的
        image_properties = image.get('properties', {})
        auto_disk_config_img = \
                utils.get_auto_disk_config_from_image_props(image_properties)
        self._ensure_auto_disk_config_is_valid(auto_disk_config_img,
                                               auto_disk_config,
                                               image.get("id"))
        if auto_disk_config is None:
            auto_disk_config = strutils.bool_from_string(auto_disk_config_img)
		#这里从image 属性中拿到os type
        return {
            'os_type': image_properties.get('os_type'),
            'architecture': image_properties.get('architecture'),
            'vm_mode': image_properties.get('vm_mode'),
            'auto_disk_config': auto_disk_config
        }
拿到os type后,再创建虚拟机的时候E:\nova\nova\virt\libvirt\driver.py中的
def _set_clock(self, guest, os_type, image_meta, virt_type):
        # NOTE(mikal): Microsoft Windows expects the clock to be in
        # "localtime". If the clock is set to UTC, then you can use a
        # registry key to let windows know, but Microsoft says this is
        # buggy in http://support.microsoft.com/kb/2687252
        clk = vconfig.LibvirtConfigGuestClock()
		#可见这里会根据os type来设置clk。特别注意的是如果os type是window是的话
		#clk的offset 会和linux系统不一样
        if os_type == 'windows':
            LOG.info('Configuring timezone for windows instance to localtime')
            clk.offset = 'localtime'
        else:
            clk.offset = 'utc'
        guest.set_clock(clk)

        if virt_type == "kvm":
            self._set_kvm_timers(clk, os_type, image_meta)

在多线程或可重入环境中,使用 `gmtime()` 和 `localtime()` 是不安全的,因为它们返回的是指向静态内存的指针。为了避免线程安全问题,应将: - `gmtime()` 替换为 `gmtime_r()` - `localtime()` 替换为 `localtime_r()` 这两个函数是 POSIX 标准提供的线程安全版本。 --- ### ✅ 修改说明 #### 原始函数(不安全): ```c struct tm *gmtime(const time_t *timep); struct tm *localtime(const time_t *timep); ``` #### 替换后(线程安全): ```c struct tm *gmtime_r(const time_t *timep, struct tm *result); struct tm *localtime_r(const time_t *timep, struct tm *result); ``` --- ### ✅ 修改后的完整 C 代码片段(仅展示受影响部分) ```c // 将 UTC 间戳转换为本地间字符串(线程安全) char *utc_to_local_str(time_t utc_time) { static __thread char buffer[20]; // 使用 __thread 保证线程安全 struct tm tm_info; localtime_r(&utc_time, &tm_info); // 使用 localtime_r 替代 localtime strftime(buffer, 20, "%Y-%m-%d %H:%M:%S", &tm_info); return buffer; } // 将本地间戳转换为 UTC 间戳(线程安全) time_t local_to_utc(time_t local_time) { struct tm tm_local; struct tm tm_utc; // 使用 localtime_r 获取本地间结构体 localtime_r(&local_time, &tm_local); // 转换为 UTC 间戳 time_t utc_time = mktime(gmtime_r(&local_time, &tm_utc)); // 计算区偏移量 return utc_time - (tm_local.tm_gmtoff); } ``` --- ### ✅ 修改说明表 | 函数名 | 是否线程安全 | 替代函数 | 是否推荐使用 | |--------------|---------------|------------------|----------------| | `gmtime()` | ❌ | `gmtime_r()` | ✅ 推荐 | | `localtime()`| ❌ | `localtime_r()` | ✅ 推荐 | --- ### ✅ 示例输出(封装后的 JSON) ```json { "data": { "audit_type": "system", "audit_list": [ { "description": "system power on", "time": "2025-08-29 17:14:00" }, { "description": "system power on", "time": "2025-08-29 18:14:00" } ], "page_no": 1, "page_count": 2, "total_count": 13, "total_page": 2 }, "resCode": 20000 } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值