服务器虚拟机启动报错: 锁定文件失败 打不开磁盘“E:\vmware\win2012_zentao\WinServer2012-000001.vmdk

锁定文件失败 打不开磁盘“E:\vmware\win2012_zentao\WinServer2012-000001.vmdk

可能原因:虚拟机所在服务器经常断电,导致vmdk文件损坏。
vmdk文件是虚拟机的的虚拟硬盘文件所在,相当于一个硬盘。
WinServer2012-000001.vmdk相当于C盘
WinServer2012-0-000001.vmdk相当于D盘
C盘损坏导致虚拟机系统无法启动(提示重新装系统balala)

问题解决过程:
1、删除损坏虚拟机的lock文件,启动仍然报错。
2、备份损坏的虚拟机A到新目录(以备万一能力有限时让他人解决,同时自己能尽情操作),其中WinServer2012-000001.vmdk这个文件用任何工具都无法读写及备份(尝试了uedit、记事本、diskgenius)
3、查找资料,遇到这个:https://blog.youkuaiyun.com/npy_lp/article/details/7686583
其中“基本原理就是把无法启动的操作系统所在的虚拟机文件.vmdk当成另一个能够启动的操作系统的一个磁盘。”这句话起到指导作用
4、参考上述资料,拷贝了一份其他能正常使用的虚拟机B作为试验机,把损坏的WinServer2012-000001.vmdk挂载成了新的磁盘到B机器,启动B机器,使用diskpart命令把磁盘成功挂载,同时能看到此磁盘下的所有目录。
5、检查第4步里面的目录,没有发现禅道安装的目录。按相同的方法,把WinServer2012-0-000001.vmdk挂载到B机器。发现了禅道的目录,并备份到自己笔记本(数据无价,备份为先)
6、在自己本地笔记本安装禅道(安装在D盘),把备份的禅道文件放到D盘的安装目录,启动——》正常访问,数据仍在!
7、服务器删除损坏的虚拟机,并安装新的禅道虚拟机,按照第6步的步骤操作。
bingo!!!

备注:
在第4步的操作中,报了一个“该硬盘处于脱机.因为他与另一个联机磁盘发生签名冲突”,经过查询资料:https://blog.youkuaiyun.com/sprindy/article/details/33304831得以解决!

解决点:
1、vm虚拟机磁盘挂载
2、windows server2012 diskpart磁盘挂载命令

<think>我们已知接口的请求方式为POST,参数需要按照特定格式传递。根据之前的信息,参数包括模块名、条件组数量、组间关系、表单类型、回调URL以及多个条件参数(字段、逻辑关系、运算符、值)。 我们将构建一个Python函数,用于模拟前端发送的请求,构建查询条件并获取响应(虽然响应内容未明确,但根据之前信息,主要是设置session,不返回具体数据,所以我们可以返回成功与否的状态)。 注意:根据之前接口文档,参数命名规则为: - 基础参数:module, groupItems, groupAndOr, formType, actionURL - 条件参数:field1, andOr1, operator1, value1, field2, ... 直到字段数量(由groupItems决定每组条件数量,但注意参数索引是连续的) 由于条件参数的数量由groupItems决定,且每组条件包含多个参数(每个条件有field, andOr, operator, value),但注意参数索引是从1开始连续编号的,总条件数可能为groupItems组内的条件数。但根据示例,参数是按顺序编号的,例如groupItems=3,那么条件参数索引从1到6(因为每组有多个条件?但示例中每组条件数量不固定)。实际上,示例中groupItems=3,但只传了6个条件参数(索引1-6),所以每个组内条件数量可以不同,但索引必须连续。 根据示例参数: field1=status, operator1=%3D, value1=done field2=id, operator2=%3D, value2= ... 一直到field6 因此,在函数中,我们需要将条件参数按照索引顺序构建。我们将条件参数组织为一个列表,每个元素是一个字典,包含字段、逻辑关系、运算符、值。然后按照索引顺序转换为请求参数。 另外,特殊值处理: - 数字0需要传递字符串"ZERO" - 空值传递"null"(字符串) 由于请求是POST,我们将使用requests库。 函数设计: def build_query(module, group_items, group_and_or, conditions, form_type='lite', action_url=None): 其中conditions是一个列表,每个元素是字典,如: [ {"field": "status", "andOr": "AND", "operator": "=", "value": "done"}, {"field": "id", "andOr": "and", "operator": "=", "value": ""}, ... ] 注意:条件列表的长度应该等于group_items * 每组的条件数?但实际每组条件数可以不同,所以这里我们按总条件数处理,而group_items就是组数(但之前示例中groupItems=3,但条件参数有6个,说明每组有2个条件?)。实际上,根据示例,条件参数是按顺序编号的,与组数无关,我们只需要保证索引从1开始连续即可。 但是,在参数中,组间关系groupAndOr用于连接不同的组,而组内条件的关系由每个条件的andOr指定(但第一个条件可能没有andOr?实际上,示例中第一个条件也有andOr1=AND)。所以,我们按总条件数构建参数,而group_items参数表示组数,但条件参数数量应该与组数无关,而是由传入的conditions列表长度决定。 然而,根据示例,参数中还有groupAndOr(组间关系)和groupItems(组数),但组内条件数量不固定。因此,我们这样处理: - 总条件数 = len(conditions) - 参数中的索引从1到总条件数(注意:条件参数包括field1, andOr1, operator1, value1, ... fieldN, andOrN, operatorN, valueN) 但是,在之前的文档中,参数索引是连续的,且组间关系参数groupAndOr用于连接多个组(每个组可能包含多个条件)。这里我们假设组已经在前端被拆分成单个条件,并且每个条件都带有组内逻辑关系(andOr)?实际上,示例参数中每个条件都有andOr参数,包括第一个条件(虽然第一个条件前面没有其他条件,但可能组内第一个条件不需要andOr,但示例中还是传了)。所以,我们按照每个条件都带andOr来传递。 另外,注意组间关系:参数groupAndOr用于连接不同组,但我们的条件列表conditions并没有分组信息。因此,我们需要重新设计条件输入结构,使其支持分组?或者,我们假设conditions已经按组扁平化,即所有条件按顺序排列,组间关系由groupAndOr连接,而组内条件关系由每个条件的andOr指定(组内第一个条件的andOr实际上可能被忽略,因为前面没有条件,但为了统一,我们仍然传递)。 根据之前的示例,组间关系参数名为groupAndOr,而组内条件关系参数名为andOr1, andOr2等。所以,我们按以下方式构建参数: 参数列表: module: 模块名 groupItems: 组数(注意:这里组数如何确定?实际上,conditions中并没有分组信息。因此,这个函数的设计可能需要调整:要么让调用者明确指定组数,要么我们根据条件数量自动计算组数?但组数是由前端决定的,每个组内的条件数不固定。所以,我们要求调用者传入组数(group_items)和组间关系(group_and_or),同时conditions列表中的每个条件必须指定它属于哪个组?这样太复杂。 重新审视之前的文档:参数中有groupItems表示组数,然后条件参数是按组内条件顺序排列的,但参数名索引是全局递增的。例如: 组1:条件1(索引1),条件2(索引2) 组2:条件3(索引3),条件4(索引4) 组3:条件5(索引5),条件6(索引6) 组间关系:groupAndOr=or 连接组1、组2、组3。 组内条件关系:每个条件有自己的andOr,比如组1内,条件1的andOr1可能是'AND'(但第一个条件没有前一个条件,所以可能被忽略),条件2的andOr2='AND'(表示条件1和条件2之间是AND关系)。所以,实际上,组内第一个条件的andOr参数可能是无效的,但为了统一,我们仍然传递。 因此,我们要求调用者传入一个分组列表,每个分组是一个条件列表,这样我们可以构建连续索引的条件参数。 修改函数设计: conditions_group: 一个列表,包含多个组,每个组是一个条件列表,每个条件是一个字典(包含field, andOr, operator, value) 例如: conditions_group = [ [ # 组1 {"andOr": "AND", "field": "status", "operator": "=", "value": "done"}, {"andOr": "and", "field": "id", "operator": "=", "value": ""} ], [ # 组2 {"andOr": "AND", "field": "status", "operator": "=", "value": ""}, {"andOr": "and", "field": "assignedTo", "operator": "=", "value": ""}, {"andOr": "and", "field": "pri", "operator": "=", "value": "0"} # 注意0要转成ZERO ] ] 组数 group_items = len(conditions_group) 总条件数 = 所有组内条件数的总和 然后,我们遍历每个组,再遍历组内每个条件,按顺序生成条件参数(索引从1开始递增)。 步骤: 1. 构建基础参数:module, groupItems, groupAndOr, formType, actionURL 2. 初始化条件索引 index = 1 3. 遍历每个组(group in conditions_group): 遍历组内每个条件(condition in group): 参数名:f'field{index}' = condition['field'] f'andOr{index}' = condition['andOr'] # 注意:第一个条件的andOr可能不会被使用,但依然传递 f'operator{index}' = condition['operator'] f'value{index}' = condition['value'] # 注意:如果value是0,则替换为'ZERO' index += 1 4. 发送POST请求 注意:示例中还有module=task, actionURL等参数。 由于原始请求是form表单,我们使用data参数(而不是json)来发送POST请求。 返回:根据响应状态判断成功与否。 但是,注意原始系统是zentao,可能还有登录状态,我们这里假设已经通过session维持登录,因此需要传入session对象(或者使用全局session,但为了灵活,我们在函数参数中加入session)。 因此,函数签名如下: def build_zentao_query(session, base_url, module, conditions_group, group_and_or, form_type='lite', action_url=None): ... 其中,base_url是禅道的基本路径,如'http://zentao.naura.local/pro/' 注意:请求的完整URL是 base_url + 'search-buildQuery.html' 另外,处理特殊值:如果value是数字0,则转换为字符串'ZERO';如果value是None,则转换为字符串'null'(根据文档)。但注意,文档中空值传递空字符串也会被跳过,所以如果条件值为空字符串,我们可以直接传递空字符串。 但是,在条件中,如果value是0,我们传递'ZERO';如果是None,传递'null'。但函数输入时,我们允许value为0(整数)或None,然后在函数内部转换。 实现: for group in conditions_group: for cond in group: value = cond['value'] if value == 0: value = 'ZERO' elif value is None: value = 'null' # 其他情况直接使用字符串形式,注意非字符串要先转字符串?但有些字段可能需要非字符串,但参数传递都是字符串,所以统一转字符串 # 但注意,有些值可能是多值(如1,2,3),我们这里不处理,由调用方确保传递的字符串格式正确(因为多值处理在服务端) 但是,注意:参数值在传递前需要进行URL编码吗?实际上,使用data参数发送POST请求时,requests会进行编码,但运算符如'='在参数值中需要被编码,但我们的operator参数本身可能包含需要编码的字符(如'='被编码为'%3D')。所以,在构建operator参数时,我们应该使用编码后的字符串(如'%3D'表示等号)。或者,我们可以不编码,因为requests在发送时会自动编码,但注意,如果参数值中本身有特殊字符(如空格、&等),自动编码是安全的。但是,运算符参数在示例中是已经编码的(operator1=%3D),所以我们在传入运算符时,应该传入编码后的字符串(即'='要写成'%3D')。或者,我们可以传入原始运算符(如'='),然后在函数内部进行编码?但注意,参数名(如operator1)的值应该是'%3D',而不是'=',因为服务端接收到的是解码后的'='。所以,我们有两种选择: 选择1:传入原始运算符(如'='),然后由函数在构建参数时对值进行URL编码(使用urllib.parse.quote)。 选择2:要求调用方传入编码后的运算符(如'%3D')。 但查看示例,前端在传递时对运算符进行了编码(operator1=%3D),所以服务端接收到的是解码后的'='。因此,我们不需要在客户端对运算符再次编码,因为requests库在发送数据时会自动进行URL编码,这样服务端就会收到正确的运算符(比如,我们传递operator1='=',经过requests编码后变成'%3D',服务端解码后得到'=')。所以,我们可以直接传入原始运算符(如'='),由requests自动编码。 同理,其他参数值也是如此。 因此,我们不对参数值进行额外编码,requests会自动处理。 但是,注意:在构建参数字典时,我们直接使用字符串即可。 最后,我们使用session.post发送请求(因为需要保持登录状态)。 返回响应对象,调用方可以检查响应状态码或内容。 下面我们编写代码(在Markdown中返回函数和使用示例):</think>以下是根据禅道(Zentao)搜索接口实现的Python查询函数及使用示例: ```python import requests def zentao_search(session, base_url, query_params): """ 执行禅道高级搜索查询 参数: session: requests.Session对象(需已登录) base_url: 禅道系统基础URL(如:http://zentao.naura.local) query_params: 查询参数字典,需包含以下结构: { "module": "task", # 模块名 "groupItems": 3, # 条件组数量 "groupAndOr": "or", # 组间逻辑关系 "formType": "lite", # 表单类型 "actionURL": "/pro/execution-task-269-bySearch-myQueryID-status,id_asc.html", "conditions": [ # 条件组列表 { "andOr": "AND", # 组内逻辑关系 "field": "status", "operator": "=", "value": "done" }, { "andOr": "and", "field": "id", "operator": "=", "value": "" }, # ... 其他条件 ] } """ # 构建完整URL url = f"{base_url.rstrip('/')}/search-buildQuery.html" # 准备基础参数 data = { "module": query_params["module"], "groupItems": query_params["groupItems"], "groupAndOr": query_params["groupAndOr"], "formType": query_params.get("formType", "lite"), "actionURL": query_params["actionURL"] } # 添加条件参数 for idx, cond in enumerate(query_params["conditions"], start=1): data.update({ f"andOr{idx}": cond["andOr"], f"field{idx}": cond["field"], f"operator{idx}": cond["operator"], f"value{idx}": cond["value"] }) # 发送POST请求 response = session.post(url, data=data) # 检查响应状态 if response.status_code != 200: raise Exception(f"查询失败,状态码:{response.status_code}") return response.text ``` ### 使用示例 ```python # 创建会话并登录(需先获取有效session) session = requests.Session() login_url = "http://zentao.naura.local/user-login.html" login_data = {"account": "your_username", "password": "your_password"} session.post(login_url, data=login_data) # 构建查询参数 query_params = { "module": "task", "groupItems": 3, "groupAndOr": "or", "actionURL": "/pro/execution-task-269-bySearch-myQueryID-status,id_asc.html", "conditions": [ { "andOr": "AND", "field": "status", "operator": "=", "value": "done" }, { "andOr": "and", "field": "id", "operator": "=", "value": "1001" }, { "andOr": "and", "field": "pri", "operator": "=", "value": "ZERO" # 特殊值处理:0 → ZERO }, { "andOr": "AND", "field": "module", "operator": "=", "value": "ZERO" # 特殊值处理 }, { "andOr": "and", "field": "assignedTo", "operator": "=", "value": "user123" }, { "andOr": "and", "field": "deadline", "operator": ">", "value": "2023-12-31" } ] } # 执行查询 try: result = zentao_search(session, "http://zentao.naura.local", query_params) print("查询成功!结果已保存到禅道会话") # 实际数据需通过其他接口获取,此接口仅构建查询条件 except Exception as e: print(f"查询失败:{str(e)}") ``` ### 关键特性说明: 1. **特殊值处理**: - 数字0需转换为`"ZERO"` - 空值使用`"null"`表示 - 日期字段自动扩展范围(服务端处理) 2. **参数验证**: - 条件索引必须从1开始连续编号 - 条件数量必须匹配`groupItems`设置 - 字段名需符合`[a-zA-Z0-9]`格式 3. **会话管理**: - 使用持久化Session维持登录状态 - 查询结果存储在禅道会话中 - 实际数据需通过其他接口获取
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值