소스 검색

[comboot] Fix reference counting on replacement images

When chaining COMBOOT images, the old images now get freed correctly.
tags/v0.9.7
Michael Brown 15 년 전
부모
커밋
14eafc5b8d
5개의 변경된 파일23개의 추가작업 그리고 18개의 파일을 삭제
  1. 1
    0
      src/arch/i386/image/com32.c
  2. 1
    0
      src/arch/i386/image/comboot.c
  3. 14
    15
      src/arch/i386/interface/syslinux/comboot_call.c
  4. 1
    2
      src/core/image.c
  5. 6
    1
      src/include/gpxe/image.h

+ 1
- 0
src/arch/i386/image/com32.c 파일 보기

122
 		DBGC ( image, "COM32 %p: exited to run kernel %p\n",
122
 		DBGC ( image, "COM32 %p: exited to run kernel %p\n",
123
 		       image, comboot_replacement_image );
123
 		       image, comboot_replacement_image );
124
 		image->replacement = comboot_replacement_image;
124
 		image->replacement = comboot_replacement_image;
125
+		comboot_replacement_image = NULL;
125
 		image_autoload ( image->replacement );
126
 		image_autoload ( image->replacement );
126
 		break;
127
 		break;
127
 
128
 

+ 1
- 0
src/arch/i386/image/comboot.c 파일 보기

191
 		DBGC ( image, "COMBOOT %p: exited to run kernel %p\n",
191
 		DBGC ( image, "COMBOOT %p: exited to run kernel %p\n",
192
 		       image, comboot_replacement_image );
192
 		       image, comboot_replacement_image );
193
 		image->replacement = comboot_replacement_image;
193
 		image->replacement = comboot_replacement_image;
194
+		comboot_replacement_image = NULL;
194
 		image_autoload ( image->replacement );
195
 		image_autoload ( image->replacement );
195
 		break;
196
 		break;
196
 
197
 

+ 14
- 15
src/arch/i386/interface/syslinux/comboot_call.c 파일 보기

157
  * Fetch kernel and optional initrd
157
  * Fetch kernel and optional initrd
158
  */
158
  */
159
 static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
159
 static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
160
-	struct image *kernel;
160
+	struct image *kernel = NULL;
161
 	struct image *initrd = NULL;
161
 	struct image *initrd = NULL;
162
 	char *initrd_file;
162
 	char *initrd_file;
163
 	int rc;
163
 	int rc;
181
 		if ( ! initrd ) {
181
 		if ( ! initrd ) {
182
 			DBG ( "COMBOOT: could not allocate initrd\n" );
182
 			DBG ( "COMBOOT: could not allocate initrd\n" );
183
 			rc = -ENOMEM;
183
 			rc = -ENOMEM;
184
-			goto err_alloc_initrd;
184
+			goto out;
185
 		}
185
 		}
186
 		if ( ( rc = imgfetch ( initrd, initrd_file,
186
 		if ( ( rc = imgfetch ( initrd, initrd_file,
187
 				       register_image ) ) != 0 ) {
187
 				       register_image ) ) != 0 ) {
188
 			DBG ( "COMBOOT: could not fetch initrd: %s\n",
188
 			DBG ( "COMBOOT: could not fetch initrd: %s\n",
189
 			      strerror ( rc ) );
189
 			      strerror ( rc ) );
190
-			goto err_fetch_initrd;
190
+			goto out;
191
 		}
191
 		}
192
 
192
 
193
 		/* Restore space after initrd name, if applicable */
193
 		/* Restore space after initrd name, if applicable */
202
 	if ( ! kernel ) {
202
 	if ( ! kernel ) {
203
 		DBG ( "COMBOOT: could not allocate kernel\n" );
203
 		DBG ( "COMBOOT: could not allocate kernel\n" );
204
 		rc = -ENOMEM;
204
 		rc = -ENOMEM;
205
-		goto err_alloc_kernel;
205
+		goto out;
206
 	}
206
 	}
207
 	if ( ( rc = imgfetch ( kernel, kernel_file,
207
 	if ( ( rc = imgfetch ( kernel, kernel_file,
208
 			       register_image ) ) != 0 ) {
208
 			       register_image ) ) != 0 ) {
209
 		DBG ( "COMBOOT: could not fetch kernel: %s\n",
209
 		DBG ( "COMBOOT: could not fetch kernel: %s\n",
210
 		      strerror ( rc ) );
210
 		      strerror ( rc ) );
211
-		goto err_fetch_kernel;
211
+		goto out;
212
 	}
212
 	}
213
 	if ( ( rc = image_set_cmdline ( kernel, cmdline ) ) != 0 ) {
213
 	if ( ( rc = image_set_cmdline ( kernel, cmdline ) ) != 0 ) {
214
 		DBG ( "COMBOOT: could not set kernel command line: %s\n",
214
 		DBG ( "COMBOOT: could not set kernel command line: %s\n",
215
 		      strerror ( rc ) );
215
 		      strerror ( rc ) );
216
-		goto err_set_cmdline;
216
+		goto out;
217
 	}
217
 	}
218
 
218
 
219
 	/* Store kernel as replacement image */
219
 	/* Store kernel as replacement image */
220
-	comboot_replacement_image = kernel;
221
-
222
-	return 0;
223
-
224
- err_set_cmdline:
225
- err_fetch_kernel:
220
+	assert ( comboot_replacement_image == NULL );
221
+	comboot_replacement_image = image_get ( kernel );
222
+
223
+ out:
224
+	/* Drop image references unconditionally; either we want to
225
+	 * discard them, or they have been registered and we should
226
+	 * drop out local reference.
227
+	 */
226
 	image_put ( kernel );
228
 	image_put ( kernel );
227
- err_alloc_kernel:
228
- err_fetch_initrd:
229
 	image_put ( initrd );
229
 	image_put ( initrd );
230
- err_alloc_initrd:
231
 	return rc;
230
 	return rc;
232
 }
231
 }
233
 
232
 

+ 1
- 2
src/core/image.c 파일 보기

275
 	/* Pick up replacement image before we drop the original
275
 	/* Pick up replacement image before we drop the original
276
 	 * image's temporary reference.
276
 	 * image's temporary reference.
277
 	 */
277
 	 */
278
-	if ( ( replacement = image->replacement ) != NULL )
279
-		image_get ( replacement );
278
+	replacement = image->replacement;
280
 
279
 
281
 	/* Drop temporary reference to the original image */
280
 	/* Drop temporary reference to the original image */
282
 	image_put ( image );
281
 	image_put ( image );

+ 6
- 1
src/include/gpxe/image.h 파일 보기

53
 	 * style similar to a Unix exec() call) should return from its
53
 	 * style similar to a Unix exec() call) should return from its
54
 	 * exec() method with the replacement image set to point to
54
 	 * exec() method with the replacement image set to point to
55
 	 * the new image.  The new image must already be in a suitable
55
 	 * the new image.  The new image must already be in a suitable
56
-	 * state for execution.
56
+	 * state for execution (i.e. loaded).
57
+	 *
58
+	 * If an image unregisters itself as a result of being
59
+	 * executed, it must make sure that its replacement image (if
60
+	 * any) is registered, otherwise the replacement is likely to
61
+	 * be freed before it can be executed.
57
 	 */
62
 	 */
58
 	struct image *replacement;
63
 	struct image *replacement;
59
 };
64
 };

Loading…
취소
저장