Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Startup Init Lite
提交
2d8c6017
S
Startup Init Lite
项目概览
OpenHarmony
/
Startup Init Lite
1 年多 前同步成功
通知
3
Star
37
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
Startup Init Lite
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
2d8c6017
编写于
3月 29, 2022
作者:
X
xionglei6
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: inner source issue
Signed-off-by:
N
xionglei6
<
xionglei6@huawei.com
>
上级
a509cdec
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
56 addition
and
51 deletion
+56
-51
interfaces/innerkits/fs_manager/fstab_mount.c
interfaces/innerkits/fs_manager/fstab_mount.c
+1
-1
services/init/init_common_service.c
services/init/init_common_service.c
+2
-2
services/init/lite/init_cmds.c
services/init/lite/init_cmds.c
+4
-4
services/init/standard/fd_holder_service.c
services/init/standard/fd_holder_service.c
+2
-2
services/init/standard/init.c
services/init/standard/init.c
+1
-1
services/init/standard/init_cmds.c
services/init/standard/init_cmds.c
+2
-2
services/init/standard/init_service.c
services/init/standard/init_service.c
+1
-1
services/log/init_log.c
services/log/init_log.c
+1
-1
services/param/adapter/param_dac.c
services/param/adapter/param_dac.c
+0
-5
services/param/watcher/proxy/watcher_manager.cpp
services/param/watcher/proxy/watcher_manager.cpp
+5
-4
services/param/watcher/proxy/watcher_manager.h
services/param/watcher/proxy/watcher_manager.h
+8
-0
services/utils/init_utils.c
services/utils/init_utils.c
+1
-1
test/plugintest/plugin_param_test.c
test/plugintest/plugin_param_test.c
+1
-1
test/unittest/common/cmd_func_test.cpp
test/unittest/common/cmd_func_test.cpp
+1
-1
test/unittest/init/group_unittest.cpp
test/unittest/init/group_unittest.cpp
+9
-9
test/unittest/init/service_socket_unittest.cpp
test/unittest/init/service_socket_unittest.cpp
+2
-2
ueventd/ueventd_device_handler.c
ueventd/ueventd_device_handler.c
+14
-13
ueventd/ueventd_read_cfg.c
ueventd/ueventd_read_cfg.c
+1
-1
未找到文件。
interfaces/innerkits/fs_manager/fstab_mount.c
浏览文件 @
2d8c6017
...
...
@@ -143,7 +143,7 @@ MountStatus GetMountStatusForMountPoint(const char *mp)
FreeStringVector
(
mountItems
,
count
);
}
}
if
(
found
==
true
)
{
if
(
found
)
{
status
=
MOUNT_MOUNTED
;
}
else
if
(
feof
(
fp
)
>
0
)
{
status
=
MOUNT_UMOUNTED
;
...
...
services/init/init_common_service.c
浏览文件 @
2d8c6017
...
...
@@ -454,14 +454,14 @@ void ServiceReap(Service *service)
}
if
(
service
->
attribute
&
SERVICE_ATTR_CRITICAL
)
{
// critical
if
(
CalculateCrashTime
(
service
,
service
->
crashTime
,
service
->
crashCount
)
==
false
)
{
if
(
!
CalculateCrashTime
(
service
,
service
->
crashTime
,
service
->
crashCount
)
)
{
INIT_LOGE
(
"Critical service
\"
%s
\"
crashed %d times, rebooting system"
,
service
->
name
,
service
->
crashCount
);
ServiceStop
(
GetServiceByName
(
"appspawn"
));
ExecReboot
(
"reboot"
);
}
}
else
if
(
!
(
service
->
attribute
&
SERVICE_ATTR_NEED_RESTART
))
{
if
(
CalculateCrashTime
(
service
,
service
->
crashTime
,
service
->
crashCount
)
==
false
)
{
if
(
!
CalculateCrashTime
(
service
,
service
->
crashTime
,
service
->
crashCount
)
)
{
INIT_LOGE
(
"Service name=%s, crash %d times, no more start."
,
service
->
name
,
service
->
crashCount
);
return
;
}
...
...
services/init/lite/init_cmds.c
浏览文件 @
2d8c6017
...
...
@@ -31,16 +31,16 @@ int GetParamValue(const char *symValue, unsigned int symLen, char *paramValue, u
static
void
DoExec
(
const
struct
CmdArgs
*
ctx
)
{
// format: exec /xxx/xxx/xxx xxx
if
(
ctx
==
NULL
||
ctx
->
argv
[
0
]
==
NULL
)
{
INIT_LOGE
(
"DoExec: invalid arguments"
);
return
;
}
pid_t
pid
=
fork
();
if
(
pid
<
0
)
{
INIT_LOGE
(
"DoExec: failed to fork child process to exec
\"
%s
\"
"
,
ctx
->
argv
[
0
]);
return
;
}
if
(
pid
==
0
)
{
if
(
ctx
==
NULL
||
ctx
->
argv
[
0
]
==
NULL
)
{
INIT_LOGE
(
"DoExec: invalid arguments"
);
_exit
(
0x7f
);
}
int
ret
=
execve
(
ctx
->
argv
[
0
],
ctx
->
argv
,
NULL
);
if
(
ret
==
-
1
)
{
INIT_LOGE
(
"DoExec: execute
\"
%s
\"
failed: %d."
,
ctx
->
argv
[
0
],
errno
);
...
...
services/init/standard/fd_holder_service.c
浏览文件 @
2d8c6017
...
...
@@ -197,6 +197,7 @@ static void HandlerFdHolder(int sock)
INIT_LOGE
(
"Invalid message received: %s"
,
buffer
);
CloseFds
(
fds
,
fdCount
);
FreeFds
(
fds
);
return
;
}
char
*
serviceName
=
msg
[
0
];
char
*
action
=
msg
[
1
];
...
...
@@ -214,16 +215,15 @@ static void HandlerFdHolder(int sock)
if
(
strcmp
(
action
,
ACTION_HOLD
)
==
0
)
{
INIT_LOGI
(
"Service
\'
%s
\'
request init to %s fds"
,
serviceName
,
action
);
if
(
HandlerHoldFds
(
service
,
fds
,
fdCount
,
pollStr
)
<
0
)
{
CloseFds
(
fds
,
fdCount
);
}
}
else
if
(
strcmp
(
action
,
ACTION_GET
)
==
0
)
{
// In this case, ignore fds, just close them if fd passed to init
CloseFds
(
fds
,
fdCount
);
HandlerGetFds
(
sock
,
service
);
}
else
{
INIT_LOGE
(
"Unexpect action: %s"
,
action
);
}
FreeFds
(
fds
);
CloseFds
(
fds
,
fdCount
);
FreeStringVector
(
msg
,
msgCount
);
}
...
...
services/init/standard/init.c
浏览文件 @
2d8c6017
...
...
@@ -107,7 +107,7 @@ void SystemInit(void)
static
void
EnableDevKmsg
(
void
)
{
/* printk_devkmsg default value is ratelimit, We need to set "on" and remove the restrictions */
int
fd
=
open
(
"/proc/sys/kernel/printk_devkmsg"
,
O_WRONLY
|
O_CLOEXEC
,
S_IRUSR
|
S_IWUSR
|
S_IRGRP
|
S_I
R
GRP
);
int
fd
=
open
(
"/proc/sys/kernel/printk_devkmsg"
,
O_WRONLY
|
O_CLOEXEC
,
S_IRUSR
|
S_IWUSR
|
S_IRGRP
|
S_I
W
GRP
);
if
(
fd
<
0
)
{
return
;
}
...
...
services/init/standard/init_cmds.c
浏览文件 @
2d8c6017
...
...
@@ -177,12 +177,12 @@ static void DoLoadDefaultParams(const struct CmdArgs *ctx)
static
void
DoExec
(
const
struct
CmdArgs
*
ctx
)
{
// format: exec /xxx/xxx/xxx xxx
INIT_ERROR_CHECK
(
ctx
!=
NULL
&&
ctx
->
argv
[
0
]
!=
NULL
,
return
,
"DoExec: invalid arguments to exec
\"
%s
\"
"
,
ctx
->
argv
[
0
]);
pid_t
pid
=
fork
();
INIT_ERROR_CHECK
(
pid
>=
0
,
return
,
"DoExec: failed to fork child process to exec
\"
%s
\"
"
,
ctx
->
argv
[
0
]);
if
(
pid
==
0
)
{
INIT_ERROR_CHECK
(
ctx
!=
NULL
&&
ctx
->
argv
[
0
]
!=
NULL
,
_exit
(
0x7f
),
"DoExec: invalid arguments to exec
\"
%s
\"
"
,
ctx
->
argv
[
0
]);
#ifdef SUPPORT_PROFILER_HIDEBUG
do
{
if
(
access
(
"/system/lib/libhidebug.so"
,
F_OK
)
!=
0
)
{
...
...
services/init/standard/init_service.c
浏览文件 @
2d8c6017
...
...
@@ -125,7 +125,7 @@ int ServiceExec(const Service *service)
int
SetAccessToken
(
const
Service
*
service
)
{
INIT_ERROR_CHECK
(
service
!=
NULL
,
return
SERVICE_FAILURE
,
"
%s failed"
,
service
->
name
);
INIT_ERROR_CHECK
(
service
!=
NULL
,
return
SERVICE_FAILURE
,
"
service is null"
);
int
ret
=
SetSelfTokenID
(
service
->
tokenId
);
INIT_LOGI
(
"%s: token id %lld, set token id result %d"
,
service
->
name
,
service
->
tokenId
,
ret
);
return
ret
==
0
?
SERVICE_SUCCESS
:
SERVICE_FAILURE
;
...
...
services/log/init_log.c
浏览文件 @
2d8c6017
...
...
@@ -80,7 +80,7 @@ void InitToHiLog(InitLogLevel logLevel, const char *fmt, ...)
static
int
g_fd
=
-
1
;
void
OpenLogDevice
(
void
)
{
int
fd
=
open
(
"/dev/kmsg"
,
O_WRONLY
|
O_CLOEXEC
,
S_IRUSR
|
S_IWUSR
|
S_IRGRP
|
S_I
R
GRP
);
int
fd
=
open
(
"/dev/kmsg"
,
O_WRONLY
|
O_CLOEXEC
,
S_IRUSR
|
S_IWUSR
|
S_IRGRP
|
S_I
W
GRP
);
if
(
fd
>=
0
)
{
g_fd
=
fd
;
}
...
...
services/param/adapter/param_dac.c
浏览文件 @
2d8c6017
...
...
@@ -204,11 +204,6 @@ static int CheckUserInGroup(gid_t groupId, uid_t uid)
return
-
1
;
}
if
(
grpResult
->
gr_name
==
NULL
||
grpResult
->
gr_name
==
NULL
)
{
PARAM_LOGE
(
"CheckUserInGroup gr_name %s pw_name %s %d %d"
,
grpResult
->
gr_name
,
userResult
->
pw_name
,
groupId
,
uid
);
return
-
1
;
}
PARAM_LOGV
(
"CheckUserInGroup pw_name %s "
,
userResult
->
pw_name
);
if
(
strcmp
(
grpResult
->
gr_name
,
userResult
->
pw_name
)
==
0
)
{
return
0
;
...
...
services/param/watcher/proxy/watcher_manager.cpp
浏览文件 @
2d8c6017
...
...
@@ -60,13 +60,14 @@ uint32_t WatcherManager::AddWatcher(const std::string &keyPrefix, const sptr<IWa
uint32_t
groupId
=
0
;
ret
=
GetGroupId
(
groupId
);
WATCHER_CHECK
(
ret
==
0
,
return
0
,
"Failed to get group id for %s"
,
keyPrefix
.
c_str
());
group
=
std
::
make_shared
<
WatcherGroup
>
(
groupId
,
keyPrefix
);
WATCHER_CHECK
(
group
!=
nullptr
,
return
0
,
"Failed to create group for %s"
,
keyPrefix
.
c_str
()
);
TUNE_MAKE_SHARED
(
group
=
std
::
make_shared
<
WatcherGroup
>
(
groupId
,
keyPrefix
),
WATCHER_LOGE
(
"Failed to create group for %s"
,
keyPrefix
.
c_str
());
return
0
);
}
else
{
newGroup
=
group
->
Emptry
();
}
ParamWatcherPtr
paramWather
=
std
::
make_shared
<
ParamWatcher
>
(
watcherId
,
watcher
,
group
);
WATCHER_CHECK
(
paramWather
!=
nullptr
,
return
0
,
"Failed to create watcher for %s"
,
keyPrefix
.
c_str
());
ParamWatcherPtr
paramWather
=
nullptr
;
TUNE_MAKE_SHARED
(
paramWather
=
std
::
make_shared
<
ParamWatcher
>
(
watcherId
,
watcher
,
group
),
WATCHER_LOGE
(
"Failed to create watcher for %s"
,
keyPrefix
.
c_str
());
return
0
);
AddParamWatcher
(
keyPrefix
,
group
,
paramWather
);
if
(
newGroup
)
{
StartLoop
();
...
...
services/param/watcher/proxy/watcher_manager.h
浏览文件 @
2d8c6017
...
...
@@ -29,6 +29,14 @@
#include "parcel.h"
#include "system_ability.h"
#include "watcher_manager_stub.h"
#define TUNE_MAKE_SHARED(exec_expr0, exec_expr1) \
do { \
try { \
exec_expr0; \
} catch(...) { \
exec_expr1; \
}; \
} while (0)
namespace
OHOS
{
namespace
init_param
{
...
...
services/utils/init_utils.c
浏览文件 @
2d8c6017
...
...
@@ -196,7 +196,7 @@ int SplitString(char *srcPtr, const char *del, char **dstPtr, int maxNum)
char
*
buf
=
NULL
;
dstPtr
[
0
]
=
strtok_r
(
srcPtr
,
del
,
&
buf
);
int
counter
=
0
;
while
(
dstPtr
[
counter
]
!=
NULL
&&
(
counter
<
maxNum
))
{
while
(
(
counter
<
maxNum
)
&&
(
dstPtr
[
counter
]
!=
NULL
))
{
counter
++
;
if
(
counter
>=
maxNum
)
{
break
;
...
...
test/plugintest/plugin_param_test.c
浏览文件 @
2d8c6017
...
...
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
http://www.apache.org/licenses/LICENSE
2.0
*
http://www.apache.org/licenses/LICENSE-
2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
...
...
test/unittest/common/cmd_func_test.cpp
浏览文件 @
2d8c6017
...
...
@@ -940,7 +940,7 @@ HWTEST_F(StartupInitUTest, cmdFuncDoLoadCfgTest_003, TestSize.Level0)
break
;
}
}
while
(
size
>
0
);
EXPECT_TRUE
(
hasZpfs
==
true
);
EXPECT_TRUE
(
hasZpfs
);
fclose
(
fd
);
}
}
...
...
test/unittest/init/group_unittest.cpp
浏览文件 @
2d8c6017
...
...
@@ -72,13 +72,13 @@ static void TestHashNodeFree(const HashNode *node)
static
TestHashNode
*
TestCreateHashNode
(
const
char
*
value
)
{
TestHashNode
*
node
=
(
TestHashNode
*
)
malloc
(
sizeof
(
TestHashNode
)
+
strlen
(
value
)
+
1
);
if
(
node
==
NULL
)
{
return
NULL
;
if
(
node
==
nullptr
)
{
return
nullptr
;
}
int
ret
=
strcpy_s
(
node
->
name
,
strlen
(
value
)
+
1
,
value
);
if
(
ret
!=
0
)
{
free
(
node
);
return
NULL
;
return
nullptr
;
}
HASHMAPInitNode
(
&
node
->
node
);
return
node
;
...
...
@@ -87,7 +87,7 @@ static TestHashNode *TestCreateHashNode(const char *value)
static
void
CreateTestFile
(
const
char
*
fileName
,
const
char
*
data
)
{
FILE
*
tmpFile
=
fopen
(
fileName
,
"wr"
);
if
(
tmpFile
!=
NULL
)
{
if
(
tmpFile
!=
nullptr
)
{
fprintf
(
tmpFile
,
"%s"
,
data
);
(
void
)
fflush
(
tmpFile
);
fclose
(
tmpFile
);
...
...
@@ -124,13 +124,13 @@ HWTEST_F(InitGroupManagerUnitTest, TestHashMap, TestSize.Level1)
HashMapAdd
(
handle
,
&
node1
->
node
);
HashMapAdd
(
handle
,
&
node2
->
node
);
HashNode
*
node
=
HashMapGet
(
handle
,
(
const
void
*
)
str1
);
EXPECT_NE
(
node
!=
NULL
,
0
);
EXPECT_NE
(
node
!=
nullptr
,
0
);
if
(
node
)
{
TestHashNode
*
tmp
=
HASHMAP_ENTRY
(
node
,
TestHashNode
,
node
);
EXPECT_EQ
(
strcmp
(
tmp
->
name
,
str1
),
0
);
}
node
=
HashMapGet
(
handle
,
(
const
void
*
)
str2
);
EXPECT_NE
(
node
!=
NULL
,
0
);
EXPECT_NE
(
node
!=
nullptr
,
0
);
if
(
node
)
{
TestHashNode
*
tmp
=
HASHMAP_ENTRY
(
node
,
TestHashNode
,
node
);
EXPECT_EQ
(
strcmp
(
tmp
->
name
,
str2
),
0
);
...
...
@@ -142,7 +142,7 @@ HWTEST_F(InitGroupManagerUnitTest, TestHashMap, TestSize.Level1)
node3
=
TestCreateHashNode
(
"Test hash map node 5"
);
HashMapAdd
(
handle
,
&
node3
->
node
);
node
=
HashMapGet
(
handle
,
(
const
void
*
)
str3
);
EXPECT_NE
(
node
!=
NULL
,
0
);
EXPECT_NE
(
node
!=
nullptr
,
0
);
if
(
node
)
{
TestHashNode
*
tmp
=
HASHMAP_ENTRY
(
node
,
TestHashNode
,
node
);
EXPECT_EQ
(
strcmp
(
tmp
->
name
,
str3
),
0
);
...
...
@@ -155,7 +155,7 @@ HWTEST_F(InitGroupManagerUnitTest, TestHashMap, TestSize.Level1)
HashMapAdd
(
handle
,
&
node5
->
node
);
HashMapRemove
(
handle
,
"pre-init"
);
node
=
HashMapGet
(
handle
,
(
const
void
*
)
act
);
EXPECT_NE
(
node
!=
NULL
,
0
);
EXPECT_NE
(
node
!=
nullptr
,
0
);
if
(
node
)
{
TestHashNode
*
tmp
=
HASHMAP_ENTRY
(
node
,
TestHashNode
,
node
);
EXPECT_EQ
(
strcmp
(
tmp
->
name
,
act
),
0
);
...
...
@@ -342,7 +342,7 @@ HWTEST_F(InitGroupManagerUnitTest, TestParseServiceCpucore, TestSize.Level1)
cJSON
*
serviceItem
=
cJSON_GetObjectItem
(
jobItem
,
"services"
);
ASSERT_NE
(
nullptr
,
serviceItem
);
Service
*
service
=
AddService
(
"test_service22"
);
if
(
service
!=
NULL
)
{
if
(
service
!=
nullptr
)
{
int
ret
=
ParseOneService
(
serviceItem
,
service
);
EXPECT_EQ
(
ret
,
0
);
ReleaseService
(
service
);
...
...
test/unittest/init/service_socket_unittest.cpp
浏览文件 @
2d8c6017
...
...
@@ -47,9 +47,9 @@ HWTEST_F(ServiceSocketUnitTest, TestCreateSocket, TestSize.Level0)
sockopt
->
perm
=
0660
;
sockopt
->
option
=
SOCKET_OPTION_PASSCRED
;
errno_t
ret
=
strncpy_s
(
sockopt
->
name
,
strlen
(
testSocName
)
+
1
,
testSocName
,
strlen
(
testSocName
));
sockopt
->
next
=
NULL
;
sockopt
->
next
=
nullptr
;
EXPECT_EQ
(
ret
,
EOK
);
if
(
service
->
socketCfg
==
NULL
)
{
if
(
service
->
socketCfg
==
nullptr
)
{
service
->
socketCfg
=
sockopt
;
}
else
{
sockopt
->
next
=
service
->
socketCfg
->
next
;
...
...
ueventd/ueventd_device_handler.c
浏览文件 @
2d8c6017
...
...
@@ -246,6 +246,18 @@ static void BuildDeviceSymbolLinks(char **links, int linkNum, const char *parent
}
}
static
void
FreeSymbolLinks
(
char
**
links
,
int
length
)
{
if
(
links
!=
NULL
)
{
for
(
int
i
=
0
;
i
<
length
&&
links
[
i
]
!=
NULL
;
i
++
)
{
free
(
links
[
i
]);
links
[
i
]
=
NULL
;
}
free
(
links
);
links
=
NULL
;
}
}
static
char
**
GetBlockDeviceSymbolLinks
(
const
struct
Uevent
*
uevent
)
{
if
(
uevent
==
NULL
||
uevent
->
subsystem
==
NULL
||
STRINGEQUAL
(
uevent
->
subsystem
,
"block"
)
==
0
)
{
...
...
@@ -278,6 +290,7 @@ static char **GetBlockDeviceSymbolLinks(const struct Uevent *uevent)
char
subsystem
[
SYSPATH_SIZE
];
if
(
snprintf_s
(
subsystem
,
SYSPATH_SIZE
,
SYSPATH_SIZE
-
1
,
"%s/subsystem"
,
parent
)
==
-
1
)
{
INIT_LOGE
(
"Failed to build subsystem path for device
\"
%s
\"
"
,
uevent
->
syspath
);
FreeSymbolLinks
(
links
,
BLOCKDEVICE_LINKS
);
return
NULL
;
}
char
*
bus
=
GetRealPath
(
subsystem
);
...
...
@@ -305,18 +318,6 @@ static char **GetBlockDeviceSymbolLinks(const struct Uevent *uevent)
return
links
;
}
static
void
FreeSymbolLinks
(
char
**
links
)
{
if
(
links
!=
NULL
)
{
for
(
int
i
=
0
;
links
[
i
]
!=
NULL
;
i
++
)
{
free
(
links
[
i
]);
links
[
i
]
=
NULL
;
}
free
(
links
);
links
=
NULL
;
}
}
static
void
HandleDeviceNode
(
const
struct
Uevent
*
uevent
,
const
char
*
deviceNode
,
bool
isBlock
)
{
ACTION
action
=
uevent
->
action
;
...
...
@@ -353,7 +354,7 @@ static void HandleDeviceNode(const struct Uevent *uevent, const char *deviceNode
INIT_LOGV
(
"Device %s changed"
,
uevent
->
syspath
);
}
// Ignore other actions
FreeSymbolLinks
(
symLinks
);
FreeSymbolLinks
(
symLinks
,
BLOCKDEVICE_LINKS
);
}
static
const
char
*
GetDeviceName
(
char
*
sysPath
,
const
char
*
deviceName
)
...
...
ueventd/ueventd_read_cfg.c
浏览文件 @
2d8c6017
...
...
@@ -151,7 +151,7 @@ static int ParseSysfsConfig(char *p)
static
int
ParseFirmwareConfig
(
char
*
p
)
{
INIT_LOGV
(
"Parse firmware config info: %s"
,
p
);
INIT_
CHECK_ONLY_ELOG
(
!
INVALIDSTRING
(
p
)
,
"Invalid argument"
);
INIT_
ERROR_CHECK
(
!
INVALIDSTRING
(
p
),
return
-
1
,
"Invalid argument"
);
// Sanity checks
struct
stat
st
=
{};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录