[CRIU] [PATCH v3 3/4] IPC: restore shared memory
Kinsbursky Stanislav
skinsbursky at openvz.org
Thu Feb 9 03:17:41 EST 2012
08.02.2012 22:37, Kir Kolyshkin пишет:
> On 02/08/2012 09:27 PM, Kinsbursky Stanislav wrote:
>> Signed-off-by: Stanislav Kinsbursky<skinsbursky at parallels.com>
>>
>> ---
>> ipc_ns.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>> 1 files changed, 107 insertions(+), 2 deletions(-)
>>
>> diff --git a/ipc_ns.c b/ipc_ns.c
>> index eda3399..5c4d27f 100644
>> --- a/ipc_ns.c
>> +++ b/ipc_ns.c
>> @@ -13,6 +13,14 @@
>> #include "namespaces.h"
>> #include "sysctl.h"
>>
>> +#ifndef IPC_PRESET
>> +#define IPC_PRESET 00040000
>> +#endif
>> +
>> +#ifndef SHM_SET
>> +#define SHM_SET 15
>> +#endif
>> +
>> static void print_ipc_seg(const struct ipc_seg *seg)
>> {
>> pr_info("id: %-10d key: 0x%08x ", seg->id, seg->key);
>> @@ -160,8 +168,12 @@ static int dump_ipc_shm(int fd)
>> int id, ret;
>>
>> id = shmctl(i, SHM_STAT,&ds);
>> - if (id< 0)
>> - continue;
>> + if (id< 0) {
>> + if (errno == EINVAL)
>> + continue;
>> + pr_perror("Failed to get stats for IPC shared memory\n");
> Remove \n
Yep. Thanks.
>> + break;
>> + }
>> ret = dump_ipc_shm_seg(fd, id,&ds);
>> if (ret< 0)
>> return ret;
>> @@ -277,6 +289,96 @@ void show_ipc_var(int fd)
>> pr_img_tail(CR_FD_IPCNS);
>> }
>>
>> +static int prepare_ipc_shm_pages(int fd, const struct ipc_shm_entry *shm)
>> +{
>> + int ret;
>> + void *data;
>> +
>> + data = shmat(shm->seg.id, NULL, 0);
>> + if (data == (void *)-1) {
>> + pr_err("Failed to attach IPC shared memory\n");
> shmat sets errno, so you should use pr_perror() here.
And again.
>> + return -errno;
>> + }
>> + ret = read_img_buf(fd, data, round_up(shm->size, sizeof(u32)));
>> + if (ret< 0) {
>> + pr_err("Failed to read IPC shared memory data\n");
>> + return ret;
>> + }
>> + if (shmdt(data)) {
>> + pr_err("Failed to detach IPC shared memory\n");
> ditto
And again.
>> + return -errno;
>> + }
>> + return 0;
>> +}
>> +
>> +static int prepare_ipc_shm_seg(int fd, const struct ipc_shm_entry *shm)
>> +{
>> + int ret, id;
>> + struct shmid_ds ds;
>> +
>> + id = shmget(shm->seg.id, shm->size,
>> + shm->seg.mode | IPC_CREAT | IPC_EXCL | IPC_PRESET);
>> + if (id == -1) {
>> pr_err("Failed to create shm segment\n");
> ditto
And again.
>> + return -errno;
>> + }
>> +
>> + if (id != shm->seg.id) {
>> + pr_err("Failed to preset id (%d instead of %d)\n",
>> + id, shm->seg.id);
>> + return -EFAULT;
>> + }
>> +
>> + ret = shmctl(id, SHM_STAT,&ds);
>> + if (ret< 0) {
>> + pr_err("Failed to stat shm segment\n");
> ditto
And again.
>> + return -errno;
>> + }
>> +
>> + ds.shm_perm.KEY = shm->seg.key;
>> + ret = shmctl(id, SHM_SET,&ds);
>> + if (ret< 0) {
>> + pr_err("Failed to update shm key\n");
> ditto
And again.
>> + return -errno;
>> + }
>> + ret = prepare_ipc_shm_pages(fd, shm);
>> + if (ret< 0) {
>> + pr_err("Failed to update shm pages\n");
>> return -errno;
> Returning -errno here is wrong, you might end up returning -0. Here's why:
>
> prepare_ipc_shm_pages()
> calls read_img_buf()
> which calls read_img_buf_eof()
> which does this:
>
> int ret;
> ret = read(fd, ptr, size);
> if (ret == size)
> return 1;
> if (ret == 0)
> return 0;
>
> if (ret< 0)
> pr_perror("Can't read img file");
> else
> pr_err("Img trimmed %d/%d\n", ret, size);
> return -1;
>
> See, in case read() will read fewer bytes this function returns -1, but
> errno is unset since read() hasn't failed.
And again.
--
Best regards,
Stanislav Kinsbursky
More information about the CRIU
mailing list