[CRIU] [PATCH v2 2/2] unix: don't drop the path on unix sockets if they don't exist
Pavel Emelyanov
xemul at virtuozzo.com
Mon Jul 4 10:38:42 PDT 2016
> @@ -962,8 +959,53 @@ static int bind_unix_sk(int sk, struct unix_sk_info *ui)
> ret = bind(sk, (struct sockaddr *)&addr,
> sizeof(addr.sun_family) + ui->ue->name.len);
> if (ret < 0) {
> - pr_perror("Can't bind socket");
> - goto done;
> + if (ui->ue->has_deleted && ui->ue->deleted && errno == EADDRINUSE) {
> + char temp[PATH_MAX];
> +
> + pr_info("found duplicate unix socket bound at %s\n", addr.sun_path);
> +
> + ret = snprintf(temp, sizeof(temp), "%s-%s-%d", addr.sun_path, "criu-temp", getpid());
> + /* this shouldn't happen, since sun_addr is only 108 chars long */
> + if (ret < 0 || ret >= sizeof(temp)) {
> + pr_err("snprintf of %s failed?\n", addr.sun_path);
> + goto done;
> + }
> +
> + ret = rename(addr.sun_path, temp);
> + if (ret < 0) {
> + pr_perror("couldn't move socket for binding");
> + goto done;
> + }
> +
> + ret = bind(sk, (struct sockaddr *)&addr,
> + sizeof(addr.sun_family) + ui->ue->name.len);
> + if (ret < 0) {
> + pr_perror("Can't bind socket after move");
> + goto done;
> + }
> +
> + ret = unlink(addr.sun_path);
This unlink seems redundant, the rename below should unlink it.
> + if (ret < 0) {
> + pr_perror("Can't unlink socket after bind");
> + goto done;
> + }
> +
> + ret = rename(temp, addr.sun_path);
> + if (ret < 0) {
> + pr_perror("couldn't move socket back");
> + goto done;
> + }
> +
> + /* we've handled the deleted-ness of this
> + * socket and we don't want to delete it later
> + * since it's not /this/ socket.
> + */
> + ui->ue->deleted = false;
> +
> + } else {
> + pr_perror("Can't bind socket");
> + goto done;
> + }
> }
>
> if (*ui->name && ui->ue->file_perms) {
> @@ -1225,6 +1267,11 @@ out:
> if (restore_socket_opts(sk, ui->ue->opts))
> return -1;
>
> + if (ui->ue->deleted && unlink((char *)ui->ue->name.data) < 0) {
I worry that we do this move/bind/unlink/move logic in bind_unix_sk(), which is
called in several places, but remove the deleted name only here. Is this safe?
> + pr_perror("failed to unlink %s\n", ui->ue->name.data);
> + return -1;
> + }
> +
> return sk;
> }
>
> diff --git a/images/sk-unix.proto b/images/sk-unix.proto
> index aa2bcf7..75ec3bf 100644
> --- a/images/sk-unix.proto
> +++ b/images/sk-unix.proto
> @@ -45,4 +45,5 @@ message unix_sk_entry {
> * Relative socket name may have prefix.
> */
> optional string name_dir = 14;
> + optional bool deleted = 15;
> }
>
More information about the CRIU
mailing list